C # 'dan Excel dosyalarını okuma


233

Excel dosyalarını (.xls) doğrudan bir C # programından okumak için ücretsiz veya açık kaynaklı bir kitaplık var mı?

Sadece bir çalışma sayfası seçmek ve verileri dize olarak okumak için çok süslü olması gerekmez. Şimdiye kadar, Excel'in Unicode'a Aktar metin işlevini kullanıyorum ve sonuçta (sekmeyle ayrılmış) dosyayı ayrıştırıyorum, ancak manuel adımı ortadan kaldırmak istiyorum.

Yanıtlar:


153
var fileName = string.Format("{0}\\fileNameHere", Directory.GetCurrentDirectory());
var connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=Excel 8.0;", fileName);

var adapter = new OleDbDataAdapter("SELECT * FROM [workSheetNameHere$]", connectionString);
var ds = new DataSet();

adapter.Fill(ds, "anyNameHere");

DataTable data = ds.Tables["anyNameHere"];

Ben genellikle bunu kullanıyorum. Biraz farklı çünkü genellikle tabloların düzenlenmesinde bir AsEnumerable () sopa:

var data = ds.Tables["anyNameHere"].AsEnumerable();

çünkü bu alanlardan yapıları aramak ve oluşturmak için LINQ kullanmamı sağlıyor.

var query = data.Where(x => x.Field<string>("phoneNumber") != string.Empty).Select(x =>
                new MyContact
                    {
                        firstName= x.Field<string>("First Name"),
                        lastName = x.Field<string>("Last Name"),
                        phoneNumber =x.Field<string>("Phone Number"),
                    });

Bu yaklaşımdaki Seç, sütunun veri türünü tahmin etmeye çalışır ve tahmin edilen veri türüne zorlar. Örneğin, çoğunlukla çift değerli bir sütununuz varsa, x.Field <string> 'i geçmenizi sevmez, ancak x.Field <double>' u bekler. Bu doğru mu?
Kevin Le - Khnle

1
Sadece MSDN'de aradım. Görünüşe göre <T> sadece sütundaki içeriği bir türe çevirmek için kullanılıyor. Bu örnekte ve sadece sütunlardaki verileri dizelere dökmek. Eğer bir çift istiyorsanız, double.Parse (x.Field <string> ("Maliyet") ya da bunun gibi bir şeyi çağırmanız gerekir.
Robin Robinson

Linq sorgusuna double.Parse eklenmesi onu yavaşlatır mı?
İsimsiz Tip

23
Not Okuduğunuz eğer xlsx, bunun yerine bu bağlantı dizesi kullanmanız gerekir:string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; Extended Properties=Excel 12.0;", fileName)
Andreas Grech

7
Ne yazık ki Jet.OLEDB sürücüsü 64 bit uyumlu değil; Herhangi bir CPU yerine x86 hedefine geçmeniz gerekir (yine de bu yöntemle devam etmek istiyorsanız). Alternatif olarak 64 bit ACE sürücüsünü yükleyin ve bu sürücüyü kullanmak için bağlantı dizesini değiştirin (Andreas tarafından belirtildiği gibi) - microsoft.com/tr-tr/download/…
Duncan

83

Excel dosyasındaki basit veriler ise ADO.NET aracılığıyla verileri okuyabilirsiniz. Burada listelenen bağlantı dizelerine bakın:

http://www.connectionstrings.com/?carrier=excel2007 veya http://www.connectionstrings.com/?carrier=excel

-Ryan

Güncelleme: Çalışma sayfasını aşağıdaki gibi bir şeyle okuyabilirsiniz select * from [Sheet1$]


1
Bu şekilde açık ara en hızlı.
StingyJack

17
Tabii ki bu doğru değil, Stingy. Tüm verileri gözden geçirmeniz ve berbat DB kodu yazmanız gerekiyor (el işlerinizi modellerinizi, sütunları özelliklerle eşleştirin, yadda yadda). En hızlı yol, diğer bazı fakir SOB'un bunu sizin için yapmasına izin vermektir . Bu yüzden insanlar her şeyi aşağıdan yukarıya yazmak yerine çerçeveler kullanıyor.

12
Değersiz yöntem! Okunduğunda metin sütunlarını 255 karaktere böler. Dikkat! Bkz. Stackoverflow.com/questions/1519288/… ACE motoru aynı şeyi yapıyor!
Triynko

5
Exel'den veri okumak için ADO.NET kullanmanın Microsoft Access veya Microsoft Access Veritabanı Altyapısı Yeniden Dağıtılabilir yüklü olması gerektiğini unutmayın.
zihotki

3
Sürücü ayrıca ilk birkaç satıra göre sütun türlerini de tahmin edecektir. İlk satırlarda tamsayıya benzeyen bir sütun varsa, tamsayı olmayan bir isabet aldığınızda bir hata ile karşılaşacaksınız (örneğin, bir kayan nokta, bir dize)
Brian Low

27

ADO.NET yaklaşımı hızlı ve kolaydır, ancak özellikle DataTypes'in nasıl işlendiği konusunda bilmeniz gereken birkaç tuhaflık vardır.

Bu mükemmel makale, bazı yaygın tuzaklardan kaçınmanıza yardımcı olacaktır: http://blog.lab49.com/archives/196


Soruma cevap verdiniz (yukarıdaki yorum şeklinde).
Kevin Le - Khnle

22

Excel 2003 için kullandığım şey bu:

Dictionary<string, string> props = new Dictionary<string, string>();
props["Provider"] = "Microsoft.Jet.OLEDB.4.0";
props["Data Source"] = repFile;
props["Extended Properties"] = "Excel 8.0";

StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> prop in props)
{
    sb.Append(prop.Key);
    sb.Append('=');
    sb.Append(prop.Value);
    sb.Append(';');
}
string properties = sb.ToString();

using (OleDbConnection conn = new OleDbConnection(properties))
{
    conn.Open();
    DataSet ds = new DataSet();
    string columns = String.Join(",", columnNames.ToArray());
    using (OleDbDataAdapter da = new OleDbDataAdapter(
        "SELECT " + columns + " FROM [" + worksheet + "$]", conn))
    {
        DataTable dt = new DataTable(tableName);
        da.Fill(dt);
        ds.Tables.Add(dt);
    }
}

2
çalışma sayfası tanımlanmadı ... her şeyi açıkça tanımladıktan sonra bana biraz garip geliyor.
Jeremy Holovacs

21

Excel Veri Okuyucu ne dersiniz?

http://exceldatareader.codeplex.com/

Bir üretim ortamında öfke içinde, çeşitli Excel dosyalarından büyük miktarda veriyi SQL Server Compact'a çekmek için kullandım. Çok iyi çalışıyor ve oldukça sağlam.


2
İkinci Excel Veri Okuyucusunu kullanacağım; ayrıca, Excel elektronik tablolarını kullanarak veriye dayalı testleri gülünç derecede kolay hale getirmek için NUnit 2.5'in TestCaseSource özniteliğini kullanan inanılmaz derecede kullanışlı Excel Veriye Dayalı Testler kütüphanesine yol açtı. Resharper'ın TestCaseSource'u henüz desteklemediğine dikkat edin, bu nedenle NUnit runner'ı kullanmanız gerekir.
David Keaveny

Ne yazık ki, bu kütüphane ile yeni karşılaştığımız bazı sorunlar var. Öncelikle bazı para birimi alanları tarih olarak çıkıyor. İkincisi, çalışma kitabında boş sayfalar varsa çöküyor. Yani, entegrasyonu çok kolay olmasına rağmen, şimdi bu kütüphaneyi kullanmaya devam edip etmeyeceğimizi yeniden değerlendiriyoruz. Aktif olarak geliştirilmiş gibi görünmüyor.
Ian1971

Ayrıca, xlsx dosyasında, yoksa veriler okunamamasına neden olan bazı isteğe bağlı öğelerin bulunduğunu varsayar.
RichieHindle

SQL Server Reporting Services'dan gelen Excel dosyalarıyla sorun yaşıyoruz. Onları açıp kaydetmedikçe (düzenlenmemiş olsalar bile) işe yaramıyorlar. @RichieHindle: Hangi isteğe bağlı öğelerden bahsediyorsunuz (bunun SSRS Excel dosyalarımda bana yardımcı olabileceğini umarak)?
Peter

@Peter: Sanırım bu benim için sorun yaratan eksik bir <dimension>unsurdu <worksheet>.
RichieHindle

16

Birkaç yıl önce .NET 1.1 kullanarak C # 'da yazdığım bazı kod. Bunun tam olarak ihtiyacınız olan şey olup olmadığından emin değilim (ve en iyi kodum olmayabilir :)).

using System;
using System.Data;
using System.Data.OleDb;

namespace ExportExcelToAccess
{
    /// <summary>
    /// Summary description for ExcelHelper.
    /// </summary>
    public sealed class ExcelHelper
    {
        private const string CONNECTION_STRING = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=<FILENAME>;Extended Properties=\"Excel 8.0;HDR=Yes;\";";

        public static DataTable GetDataTableFromExcelFile(string fullFileName, ref string sheetName)
        {
            OleDbConnection objConnection = new OleDbConnection();
            objConnection = new OleDbConnection(CONNECTION_STRING.Replace("<FILENAME>", fullFileName));
            DataSet dsImport = new DataSet();

            try
            {
                objConnection.Open();

                DataTable dtSchema = objConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

                if( (null == dtSchema) || ( dtSchema.Rows.Count <= 0 ) )
                {
                    //raise exception if needed
                }

                if( (null != sheetName) && (0 != sheetName.Length))
                {
                    if( !CheckIfSheetNameExists(sheetName, dtSchema) )
                    {
                        //raise exception if needed
                    }
                }
                else
                {
                    //Reading the first sheet name from the Excel file.
                    sheetName = dtSchema.Rows[0]["TABLE_NAME"].ToString();
                }

                new OleDbDataAdapter("SELECT * FROM [" + sheetName + "]", objConnection ).Fill(dsImport);
            }
            catch (Exception)
            {
                //raise exception if needed
            }
            finally
            {
                // Clean up.
                if(objConnection != null)
                {
                    objConnection.Close();
                    objConnection.Dispose();
                }
            }


            return dsImport.Tables[0];
            #region Commented code for importing data from CSV file.
            //              string strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" +"Data Source=" + System.IO.Path.GetDirectoryName(fullFileName) +";" +"Extended Properties=\"Text;HDR=YES;FMT=Delimited\"";
            //
            //              System.Data.OleDb.OleDbConnection conText = new System.Data.OleDb.OleDbConnection(strConnectionString);
            //              new System.Data.OleDb.OleDbDataAdapter("SELECT * FROM " + System.IO.Path.GetFileName(fullFileName).Replace(".", "#"), conText).Fill(dsImport);
            //              return dsImport.Tables[0];

            #endregion
        }

        /// <summary>
        /// This method checks if the user entered sheetName exists in the Schema Table
        /// </summary>
        /// <param name="sheetName">Sheet name to be verified</param>
        /// <param name="dtSchema">schema table </param>
        private static bool CheckIfSheetNameExists(string sheetName, DataTable dtSchema)
        {
            foreach(DataRow dataRow in dtSchema.Rows)
            {
                if( sheetName == dataRow["TABLE_NAME"].ToString() )
                {
                    return true;
                }   
            }
            return false;
        }
    }
}

Daha fazla Cherian kabul edemedi. Bu kod çok eski ... Resharper ile bile yetkin olmadan önce :)
hitec

2
Kod çirkin, ama sayfa isimlerinin nasıl alınacağını gösterir, harika!
Sam

15

Koogra , C # ile yazılmış ve Excel dosyalarını okuyan ve yazan açık kaynaklı bir bileşendir.


NPOI ile karşılaştırıldığında artık daha aktif görünmüyor
David Burton


8

Bir süre önce C # 'daki Excel dosyalarından çok okuma yaptım ve iki yaklaşım kullandık:

  • Excel'in nesnelerine doğrudan eriştiğiniz ve yöntemleri ve özellikleri kullanarak değiştirdiğiniz COM API'si
  • Excel'i veritabanı gibi kullanmanıza izin veren ODBC sürücüsü.

İkinci yaklaşım çok daha hızlıydı: 20 sütun ve 200 satırlı büyük bir tablo okumak COM aracılığıyla 30 saniye ve ODBC aracılığıyla yarım saniye alacaktı. Yani ihtiyacınız olan tüm veri veritabanı yaklaşım tavsiye ederim.

Alkış,

Carl



6

.NET ile xls / xlsx dosyasını okumak için basit bir yöntem göstermek istiyorum. Umarım aşağıdakiler sizin için yararlı olacaktır.

 özel DataTable ReadExcelToTable (dize yolu)    
 {

     //Bağlantı dizisi

     string connstring = "Sağlayıcı = Microsoft.ACE.OLEDB.12.0; Veri Kaynağı =" + yol + "; Genişletilmiş Özellikler = 'Excel 8.0; HDR = HAYIR; IMEX = 1';";  
     //aynı isim 
     // string connstring = Provider = Microsoft.JET.OLEDB.4.0; Veri Kaynağı = "+ yol + //"; Genişletilmiş Özellikler = 'Excel 8.0; HDR = NO; IMEX = 1'; "; 

     kullanarak (OleDbConnection conn = yeni OleDbConnection (connstring))
     {
        conn.Open ();
        // Tüm Sayfa Adlarını Al
        DataTable sheetsName = conn.GetOleDbSchemaTable (OleDbSchemaGuid.Tables, yeni nesne [] {null, null, null, "Table"});  

        // İlk Sayfa Adını Alın
        string firstSheetName = sheetsName.Rows [0] [2] .ToString (); 

        // Sorgu Dizesi 
        string sql = string.Format ("SELECT * FROM [{0}]", firstSheetName); 
        OleDbDataAdapter ada = yeni OleDbDataAdapter (sql, biçimlendirme);
        DataSet kümesi = yeni DataSet ();
        ada.Fill (grubu);
        dönüş kümesi.Tablo [0];   
   }
 }

Kod şu makaleden alınmıştır: http://www.c-sharpcorner.com/uploadfile/d2dcfc/read-excel-file-with-net/ . Bundan daha fazla ayrıntı alabilirsiniz.


2
O oldu , sheetnames okuma konusunda özellikle bölümü yararlı.
martinstoeckli

4

Ücretsiz değil, ancak en son Office ile çok güzel bir otomasyon .Net API var. (uzun zamandır bir API vardı ama kötü COM oldu) Office uygulaması gizli bir arka plan işlemi kalırken kodda istediğiniz / ihtiyacınız olan her şeyi yapabilirsiniz.


3
@ Anonim tip Soruyu okudum ve istenen bir OSS uygulamasına yardımcı bir alternatif sunuyordum ... çünkü iyi bir şey olmadığından emindim. Ve kabul edilen cevaba bakılırsa, Office'in yüklü olması şartı yoktur.
xanadont

3

Burada bazýysam beni affet ama Office PIA'lar bunun için deđil mi?


5
Evet, ancak bu bir Excel.Application örneği oluşturmayı, xls dosyasını yüklemeyi vb. İçerir. Gereksinim yalnızca dosyadaki bazı verileri okumaksa, açıklanan ADO.NET yöntemlerinden birini kullanmak çok daha kolay ve çok daha hafiftir diğer cevaplarda.
Adam Ralph

Çok yavaş, Office PIA'yı temel olarak kullanarak, diğer her şey daha hızlıdır; yalnızca .Value2 özelliğinden geçirilen bir Object dizisi kullanarak bile. Hangi hala PIA kullanıyor.
İsimsiz Tip

3

Son zamanlarda, kısmen LINQ daha iyi almak için .... XML XML elektronik tablo olarak dosyayı kaydetmek ve daha sonra XML LINQ kullanarak bu dosyayı işlem almak için Excel'in otomasyon API kullanarak.


Excel'den koruyabileceğinizden şüphelenirim, ancak derleyicili insanlardan değil ... her şey gibi ... sadece bayt.
kenny

@gsvirdi, Excel dosya güvenliği hakkında ayrı bir soru gönderin, bu soru performans üzerindedir.
İsimsiz Tip


3

SmartXLS , excel Charts, formül motorlarının birçok özelliğini destekleyen ve excel2007 openxml formatını okuyabilen / yazabilen başka bir excel elektronik tablo bileşenidir.



2

EXCEL, sabit uzunluk veya sınırlandırılmış kayıtları dosya, dize veya akarsu + Daha fazla veri almak / vermek için ücretsiz ve kullanımı kolay bir .NET kütüphanesi olan FileHelpers Library'yi öneriyorum.

Excel Veri Bağlantısı Dokümantasyon Bölümü http://filehelpers.sourceforge.net/example_exceldatalink.html


1
Seni hayal kırıklığına uğratmayacağım, ama yakın zamanda FileHelpers kullanmaya başladım ve ne kadar da berbat olduğu konusunda şok oldum. Örneğin, bir csv'deki sütunları özelliklerle eşlemenin tek yolu ... affedersiniz, FIELDS, bir modelin alanlarını sütunlar sırasına göre oluşturmaktır . Seni bilmiyorum, ama f8king çerçevemdeki en merkezi tasarım hususlarından biri için derleyicinin tuhaflığına güvenmem.


2

SpreadsheetGear harika. Evet bu bir masraf, ancak bu diğer çözümlerle uğraşmaya kıyasla, maliyete değer. Hızlı, güvenilir, çok kapsamlı ve bu ürünü bir buçuk yıldan fazla süredir tam zamanlı yazılım işimde kullandıktan sonra müşteri desteklerinin harika olduğunu söylemeliyim!


Excel'den okuma ve Excel'e yazmanın çok basit ve etkili yolları (ücretsiz) olduğunda haklı çıkarmak zor.
İsimsiz Tip

2

Kullandığımız çözümün şunları yapması gerekiyordu:

  • Excel tarafından üretilen dosyaların Okuma / Yazılmasına izin ver
  • Performansta Hızlı Olun (COM'ları kullanmak gibi değil)
  • MS Office'ten Bağımsız Olun (MS Office yüklü istemciler olmadan kullanılabilir olması gerekir)
  • Özgür veya Açık Kaynak Olun (ancak aktif olarak geliştirin)

Birkaç seçenek var, ancak NPoi'yi (Java'nın uzun süredir var olan Poi açık kaynak projesinin .NET portu) en iyisi olarak gördük : http://npoi.codeplex.com/

Ayrıca .doc ve .ppt dosya biçimleriyle çalışmaya olanak tanır


2

Sadece tablo verileri. Marcos Melli'nin dosya indirme yardımcılarını buradan indirebilirsiniz .



1

belirli bir excel e-tablosunu yükleyen ve csv olarak kaydeden bir excel e-tablosu yazabilirsiniz (manuel olarak yapmak yerine).

o zaman c # otomatikleştirmek.

ve bir kez onun csv, c # programı grok olabilir.

(ayrıca, birisi excel'de program yapmanızı isterse, nasıl olduğunu bilmiyormuş gibi yapmak en iyisidir)

(değiştir: ah evet, rob ve ryan her ikisi de haklıdır)




1

Excel Paketi , Excel 2007 dosyalarını okumak / yazmak için açık kaynaklı (GPL) bir bileşendir. Küçük bir projede kullandım ve API basit. XLS ile değil, yalnızca XLSX (Excel 200 ve) ile çalışır.

Kaynak kodu da iyi organize edilmiş ve dolaşması kolay görünüyor (işlevselliği genişletmeniz veya yaptığım gibi küçük sorunları düzeltmeniz gerekiyorsa).

İlk başta, ADO.Net (Excel bağlantı dizesi) yaklaşımını denedim, ancak kötü hacklerle doluydu - örneğin ikinci satırda bir sayı varsa, aşağıdaki sütundaki tüm alanlar için girişleri döndürecek ve sessizce herhangi bir veri bırakacak bu uygun değil.


1

Biz kullanmak ClosedXML oldukça büyük sistemlerde.

  • Bedava
  • Kurulumu kolay
  • Düz ileri kodlama
  • Çok duyarlı destek
  • Geliştirici ekibi son derece yeni önerilere açık. Genellikle aynı hafta içinde yeni özellikler ve hata düzeltmeleri uygulanır

1

Take.ioE-tablo bu işi sizin için ve ücretsiz olarak yapacaktır. Sadece bir göz atın bu .


Bu gerçekten harika bir kütüphane. Sadece her şeyi dizeler listesi listesine dönüştürür, bu da ihtiyaç duyduğum iş için gayet iyi.
Drewmate

0

Ben sadece bir DataSet bir .xls elektronik tablo yüklemek için ExcelLibrary kullandım . Benim için harika çalıştı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.