Membaca file Excel dari C #


233

Apakah ada pustaka sumber terbuka atau gratis untuk membaca file Excel (.xls) langsung dari program C #?

Tidak perlu terlalu mewah, cukup dengan memilih lembar kerja dan membaca data sebagai string. Sejauh ini, saya telah menggunakan fungsi teks Ekspor ke Unicode dari Excel, dan mem-parsing hasil (tab-delimited) file, tapi saya ingin menghilangkan langkah manual.

Jawaban:


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"];

Inilah yang biasanya saya gunakan. Ini sedikit berbeda karena saya biasanya menempel AsEnumerable () di edit tabel:

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

karena ini memungkinkan saya menggunakan LINQ untuk mencari dan membangun struct dari bidang.

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"),
                    });

Jika sepertinya Select dalam pendekatan ini mencoba menebak tipe data kolom dan memaksakan tipe data yang ditebak itu. Misalnya, jika Anda memiliki kolom dengan sebagian besar nilai ganda, itu tidak akan suka Anda melewati x.Field <string>, tetapi mengharapkan x.Field <double>. Apakah ini benar?
Kevin Le - Khnle

1
Hanya mencarinya di MSDN. Sepertinya <T> hanya digunakan untuk mencoba membuang konten di kolom ke jenis. Dalam contoh ini dan hanya membuang data di kolom ke string. Jika Anda menginginkan ganda, Anda harus memanggil double.Parse (x.Field <string> ("Biaya") atau sesuatu seperti itu. Field adalah metode ekstensi untuk DataRow dan sepertinya tidak ada versi non generik.
Robin Robinson

Apakah menambahkan double.Parse ke permintaan Linq memperlambatnya banyak?
Jenis Anonim

23
Perhatikan bahwa jika Anda membaca xlsx, Anda harus menggunakan string koneksi ini sebagai gantinya:string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; Extended Properties=Excel 12.0;", fileName)
Andreas Grech

7
Sayangnya driver Jet.OLEDB tidak kompatibel 64-bit; Anda harus beralih ke target x86 daripada CPU Apa pun (jika Anda masih ingin melanjutkan metode ini). Sebagai alternatif, instal driver ACE 64-bit dan ubah string conn untuk menggunakan driver ini (seperti yang ditunjukkan oleh Andreas) - microsoft.com/en-us/download/…
Duncan

83

Jika hanya data sederhana yang terkandung dalam file Excel Anda dapat membaca data melalui ADO.NET. Lihat string koneksi yang tercantum di sini:

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

-Ryan

Perbarui: maka Anda bisa membaca lembar kerja melalui sesuatu seperti select * from [Sheet1$]


1
Cara ini adalah yang tercepat.
StingyJack

17
Tentu saja itu tidak benar, Pelit. Anda harus menyaring semua data dan menulis kode DB jelek (kerajinan tangan model Anda, memetakan kolom ke properti, yadda yadda). Cara tercepat adalah membiarkan beberapa SOB miskin lainnya melakukan ini untuk Anda . Itu sebabnya orang menggunakan kerangka kerja alih-alih menulis semuanya dari bawah ke atas.

12
Metode yang tidak berharga! Memotong kolom teks hingga 255 karakter saat dibaca. Awas! Lihat: stackoverflow.com/questions/1519288/... mesin ACE melakukan hal yang sama!
Triynko

5
Sadarilah bahwa menggunakan ADO.NET untuk membaca data dari exel memerlukan Microsoft Access atau Microsoft Access Database Engine Redistributable yang diinstal.
zihotki

3
Pengemudi juga akan menebak jenis kolom berdasarkan pada beberapa baris pertama. Jika Anda memiliki kolom dengan apa yang tampak seperti bilangan bulat di baris pertama, Anda akan menemukan kesalahan ketika Anda menekan non-integer (misalnya float, string)
Brian Low

27

Pendekatan ADO.NET cepat dan mudah, tetapi memiliki beberapa keanehan yang harus Anda ketahui, terutama mengenai bagaimana DataTypes ditangani.

Artikel yang luar biasa ini akan membantu Anda menghindari beberapa perangkap umum: http://blog.lab49.com/archives/196


Anda menjawab pertanyaan saya (dalam bentuk komentar di atas).
Kevin Le - Khnle

22

Ini yang saya gunakan untuk Excel 2003:

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
lembar kerja tidak didefinisikan ... tampaknya agak aneh bagi saya setelah mendefinisikan dengan jelas segala sesuatu yang lain.
Jeremy Holovacs

21

Bagaimana dengan Pembaca Data Excel?

http://exceldatareader.codeplex.com/

Saya menggunakannya di kemarahan, di lingkungan produksi, untuk menarik sejumlah besar data dari berbagai file Excel ke SQL Server Compact. Ini bekerja dengan sangat baik dan agak kuat.


2
Saya akan kedua Pembaca Data Excel; itu juga mengarah ke pustaka Excel Data Driven Tests yang sangat berguna, yang menggunakan atribut TestCaseSource NUnit 2.5 untuk membuat tes yang digerakkan data menggunakan lembar kerja Excel sangat mudah. Berhati-hatilah karena Resharper belum mendukung TestCaseSource, jadi Anda harus menggunakan pelari NUnit.
David Keaveny

Sayangnya, ada beberapa masalah dengan perpustakaan ini yang baru saja kami temui. Pertama, kami memiliki beberapa bidang mata uang yang keluar sebagai tanggal. Kedua itu mogok jika buku kerja memiliki lembar kosong di dalamnya. Jadi, meskipun sangat mudah untuk diintegrasikan, kami sekarang mengevaluasi kembali apakah akan tetap menggunakan perpustakaan ini. Tampaknya tidak sedang dikembangkan secara aktif.
Ian1971

Itu juga mengasumsikan kehadiran beberapa elemen opsional dalam file xlsx yang menyebabkannya gagal membaca data jika mereka tidak ada.
RichieHindle

Kami mengalami masalah dengan file Excel yang berasal dari Layanan Pelaporan SQL Server. Mereka tidak berfungsi, kecuali Anda membukanya dan menyimpannya (bahkan belum diedit). @RichieHindle: elemen opsional apa yang Anda bicarakan (berharap ini dapat membantu saya dengan file SSRS Excel saya)?
Peter

@ Peter: Saya pikir itu adalah <dimension>elemen yang hilang <worksheet>yang menyebabkan masalah bagi saya.
RichieHindle

16

Berikut adalah beberapa kode yang saya tulis di C # menggunakan .NET 1.1 beberapa tahun yang lalu. Tidak yakin apakah ini akan tepat seperti yang Anda butuhkan (dan mungkin bukan kode terbaik saya :)).

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;
        }
    }
}

Tidak bisa menyetujui lebih banyak Cherian. Kode ini berusia bertahun-tahun ... bahkan sebelum aku mahir dengan Resharper :)
hitec

2
Kode ini jelek, tetapi ini menunjukkan cara mendapatkan nama sheet, hebat!
Sam

15

Koogra adalah komponen open-source yang ditulis dalam C # yang membaca dan menulis file Excel.


Tidak terlihat aktif lagi, dibandingkan dengan, katakanlah, NPOI
David Burton


8

Saya melakukan banyak membaca dari file Excel di C # beberapa waktu lalu, dan kami menggunakan dua pendekatan:

  • COM API, tempat Anda mengakses objek Excel secara langsung dan memanipulasi mereka melalui metode dan properti
  • Pengandar ODBC yang memungkinkan untuk menggunakan Excel seperti database.

Pendekatan terakhir jauh lebih cepat: membaca tabel besar dengan 20 kolom dan 200 baris akan memakan waktu 30 detik melalui COM, dan setengah detik melalui ODBC. Jadi saya akan merekomendasikan pendekatan database jika yang Anda butuhkan hanyalah data.

Bersulang,

Carl



6

Saya ingin menunjukkan metode sederhana untuk membaca file xls / xlsx dengan .NET. Saya harap yang berikut ini akan membantu Anda.

 ReadTcelToTable DataTable pribadi (jalur string)    
 {

     // Koneksi String

     string connstring = "Penyedia = Microsoft.ACE.OLEDB.12.0; Sumber Data =" + path + "; Extended Properties = 'Excel 8.0; HDR = NO; IMEX = 1';";  
     // nama yang sama 
     // string connstring = Penyedia = Microsoft.JET.OLEDB.4.0; Sumber Data = "+ path + //"; Extended Properties = 'Excel 8.0; HDR = NO; IMEX = 1'; "; 

     menggunakan (OleDbConnection conn = new OleDbConnection (connstring))
     {
        samb.Buka ();
        // Dapatkan Semua Lembar Nama
        DataTable sheetsName = conn.GetOleDbSchemaTable (OleDbSchemaGuid.Tables, objek baru [] {null, null, null, "Table"});  

        // Dapatkan Nama Lembar Pertama
        string firstSheetName = sheetsName.Rows [0] [2] .ToString (); 

        // String Kueri 
        string sql = string.Format ("SELECT * FROM [{0}]", firstSheetName); 
        OleDbDataAdapter ada = OleDbDataAdapter baru (sql, connstring);
        Set DataSet = DataSet baru ();
        ada.Fill (set);
        return set.Tabel [0];   
   }
 }

Kode berasal dari artikel: http://www.c-sharpcorner.com/uploadfile/d2dcfc/read-excel-file-with-net/ . Anda bisa mendapatkan detail lebih banyak dari itu.


2
Itu sangat membantu, terutama bagian tentang membaca nama-nama sheet.
martinstoeckli

4

Tidak gratis, tetapi dengan Office terbaru ada otomatisasi .Net API yang sangat bagus. (telah ada API untuk waktu yang lama tetapi COM jahat) Anda dapat melakukan semua yang Anda inginkan / butuhkan dalam kode semua sementara aplikasi Office tetap merupakan proses latar belakang tersembunyi.


3
@ Anonim-tipe Saya membaca pertanyaan dan menawarkan alternatif yang bermanfaat untuk implementasi OSS yang diinginkan ... karena, yah, saya cukup yakin tidak ada yang tersedia. Dan, dilihat dari jawaban yang diterima, persyaratan untuk menginstal Office tidak menjadi masalah.
xanadont

3

Maafkan saya jika saya di luar markas di sini, tetapi bukankah ini untuk Kantor PIA ?


5
Ya, tetapi itu akan melibatkan pembuatan contoh aplikasi Excel, memuat file xls, dll. Jika persyaratannya murni untuk membaca beberapa data dari file maka jauh lebih mudah dan jauh lebih ringan untuk menggunakan salah satu metode ADO.NET yang dijelaskan dalam jawaban lain.
Adam Ralph

Terlalu lambat, menggunakan Office PIA sebagai baseline, segalanya lebih cepat - bahkan hanya menggunakan array Object yang dilewatkan dari properti .Value2. Yang masih menggunakan PIA.
Jenis Anonim

3

Akhir-akhir ini, sebagian untuk menjadi lebih baik di LINQ .... Saya telah menggunakan API otomatisasi Excel untuk menyimpan file sebagai XML Spreadsheet dan kemudian memproses file tersebut menggunakan LINQ ke XML.


Saya menduga Anda dapat melindunginya dari Excel, tetapi tidak dari manusia dengan kompiler ... seperti apa pun ... itu hanya byte.
kenny

@gsvirdi, kirim pertanyaan terpisah tentang keamanan file Excel, pertanyaan ini tentang kinerja.
Tipe Anonim


3

SmartXLS adalah komponen spreadsheet excel lain yang mendukung sebagian besar fitur Chart excel, mesin formula, dan dapat membaca / menulis format openxml excel2007.



2

Saya merekomendasikan Perpustakaan FileHelpers yang bebas dan mudah digunakan. Perpustakaan NET untuk mengimpor / mengekspor data dari EXCEL, panjang tetap atau catatan dibatasi dalam file, string atau stream + Lebih Banyak.

Bagian Dokumentasi Tautan Data Excel http://filehelpers.sourceforge.net/example_exceldatalink.html


1
Saya tidak akan mengecewakan Anda, tetapi saya baru-baru ini mulai menggunakan FileHelpers dan terkejut melihat betapa ... buruknya itu. Sebagai contoh, satu-satunya cara untuk memetakan kolom dalam csv ke properti ... permisi, BIDANG, dari model adalah membuat bidang dalam urutan kolom . Saya tidak tahu tentang Anda, tetapi saya tidak akan bergantung pada kekhasan kompiler untuk salah satu pertimbangan desain paling sentral dari kerangka f8king saya.


2

SpreadsheetGear mengagumkan. Ya itu pengeluaran, tetapi dibandingkan dengan mengutak-atik solusi lain ini, ini sepadan dengan biayanya. Ini cepat, dapat diandalkan, sangat komprehensif, dan harus saya katakan setelah menggunakan produk ini dalam pekerjaan perangkat lunak penuh saya selama lebih dari satu setengah tahun, dukungan pelanggan mereka luar biasa!


Sulit dibenarkan ketika ada begitu banyak cara sederhana dan efektif (gratis) membaca dan menulis ke Excel.
Jenis Anonim

2

Solusi yang kami gunakan, diperlukan untuk:

  • Izinkan Membaca / Menulis file yang dihasilkan Excel
  • Jadilah Cepat dalam kinerja (tidak seperti menggunakan com)
  • Jadilah MS Office Independen (harus dapat digunakan tanpa klien memasang MS Office)
  • Jadilah Bebas atau Sumber Terbuka (tetapi dikembangkan secara aktif)

Ada beberapa pilihan, tetapi kami menemukan NPoi (.NET port dari proyek open source Poi lama di Jawa ) menjadi yang terbaik: http://npoi.codeplex.com/

Ini juga memungkinkan bekerja dengan format file .doc dan .ppt


2

Jika itu hanya data tabular. Saya akan merekomendasikan file data helpers oleh Marcos Melli yang dapat diunduh di sini .



1

Anda bisa menulis excel spreadsheet yang memuat spreadsheet excel yang diberikan dan menyimpannya sebagai csv (daripada melakukannya secara manual).

maka Anda dapat mengotomatisasi itu dari c #.

dan sekali di csv, program c # dapat grok itu.

(juga, jika seseorang meminta Anda untuk memprogram dalam excel, yang terbaik adalah berpura-pura tidak tahu caranya)

(sunting: ah ya, merampok dan ryan keduanya benar)




1

Paket Excel adalah komponen open-source (GPL) untuk membaca / menulis file Excel 2007. Saya menggunakannya pada proyek kecil, dan API langsung. Hanya bekerja dengan XLSX (Excel 200 &), tidak dengan XLS.

Kode sumber juga tampaknya terorganisir dengan baik dan mudah untuk diselesaikan (jika Anda perlu memperluas fungsionalitas atau memperbaiki masalah kecil seperti yang saya lakukan).

Pada awalnya, saya mencoba pendekatan ADO.Net (Excel connection string), tetapi penuh dengan peretasan yang tidak baik - misalnya jika baris kedua berisi angka, ia akan mengembalikan int untuk semua bidang di kolom di bawah ini dan dengan diam-diam menjatuhkan data apa pun itu tidak cocok.


1

Kami menggunakan ClosedXML dalam sistem yang agak besar.

  • Gratis
  • Mudah dipasang
  • Pengodean lurus ke depan
  • Dukungan sangat responsif
  • Tim pengembang adalah extremly terbuka untuk saran baru. Seringkali fitur baru dan perbaikan bug diimplementasikan dalam minggu yang sama

1

Take.ioSpreadsheet akan melakukan pekerjaan ini untuk Anda, dan tanpa biaya. Coba lihat ini .


Ini adalah perpustakaan kecil yang hebat. Itu hanya mengubah segalanya menjadi Daftar Daftar string, yang baik untuk jenis pekerjaan yang saya butuhkan untuk itu.
Drewmate

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.