Đọc tệp Excel từ C #


233

Có thư viện mã nguồn mở hoặc miễn phí để đọc các tệp Excel (.xls) trực tiếp từ chương trình C # không?

Không cần quá cầu kỳ, chỉ cần chọn một bảng tính và đọc dữ liệu dưới dạng chuỗi. Cho đến nay, tôi đã sử dụng chức năng xuất văn bản sang Unicode của Excel và phân tích tệp kết quả (được phân định bằng tab), nhưng tôi muốn loại bỏ bước thủ công.

Câu trả lời:


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

Đây là những gì tôi thường sử dụng. Nó hơi khác một chút vì tôi thường dán AsEnumerable () khi chỉnh sửa các bảng:

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

vì điều này cho phép tôi sử dụng LINQ để tìm kiếm và xây dựng các cấu trúc từ các trường.

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

Nếu có vẻ như Chọn trong phương pháp này cố gắng đoán kiểu dữ liệu của cột và buộc loại dữ liệu đoán đó. Ví dụ: nếu bạn có một cột có hầu hết các giá trị kép, nó sẽ không giống như bạn vượt qua x.Field <string>, nhưng mong đợi x.Field <double>. Điều này có đúng không?
Kevin Le - Khnle

1
Chỉ cần nhìn nó trên MSDN. Có vẻ như <T> chỉ được sử dụng để cố gắng truyền nội dung trong cột thành một loại. Trong ví dụ này và chỉ truyền dữ liệu trong các cột thành chuỗi. Nếu bạn muốn tăng gấp đôi, bạn sẽ cần gọi double.Pude (x.Field <string> ("Cost") hoặc đại loại như thế. Field là một phương thức mở rộng cho DataRow và có vẻ như không có phiên bản không chung chung.
Robin Robinson

Việc thêm một double.Pude vào truy vấn Linq có làm chậm nó nhiều không?
Loại ẩn danh

23
Lưu ý rằng nếu bạn đang đọc xlsx, bạn cần sử dụng chuỗi kết nối này thay thế:string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; Extended Properties=Excel 12.0;", fileName)
Andreas Grech

7
Đáng buồn là trình điều khiển Jet.OLEDB không tương thích 64 bit; bạn sẽ cần phải chuyển sang mục tiêu x86 thay vì Bất kỳ CPU nào (nếu bạn vẫn muốn tiếp tục với phương pháp này). Hoặc cài đặt trình điều khiển ACE 64 bit và thay đổi chuỗi liên kết để sử dụng trình điều khiển này (như được chỉ định bởi Andreas) - microsoft.com/en-us/doad/ Kẻ
Duncan

83

Nếu nó chỉ là dữ liệu đơn giản có trong tệp Excel, bạn có thể đọc dữ liệu qua ADO.NET. Xem các chuỗi kết nối được liệt kê ở đây:

http://www.connectionstrings.com/?carrier=excel2007 hoặc http://www.connectionstrings.com/?carrier=excel

-Ryan

Cập nhật: sau đó bạn có thể chỉ cần đọc bảng tính thông qua một cái gì đó như select * from [Sheet1$]


1
Cách này là nhanh nhất.
StingyJack

17
Tất nhiên điều đó không đúng, Stingy. Bạn phải sàng lọc tất cả dữ liệu và viết mã DB xảo quyệt (thủ công các mô hình của bạn, các cột ánh xạ tới các thuộc tính, yadda yadda). Cách nhanh nhất là để một số SOB nghèo khác làm điều này cho bạn . Đó là lý do tại sao mọi người sử dụng các khung thay vì viết mọi thứ từ dưới lên.

12
Phương pháp vô giá trị! Cắt bớt cột văn bản thành 255 ký tự khi đọc. Coi chừng! Xem: stackoverflow.com/questions/1519288/ động cơ ACE làm điều tương tự!
Triynko

5
Xin lưu ý rằng việc sử dụng ADO.NET để đọc dữ liệu từ exel yêu cầu Microsoft Access hoặc Microsoft Access Database Engine Redistributable được cài đặt.
zihotki

3
Trình điều khiển cũng sẽ đoán các loại cột dựa trên một số hàng đầu tiên. Nếu bạn có một cột trông giống như số nguyên ở các hàng đầu tiên, bạn sẽ gặp lỗi khi bạn nhấn một số nguyên (ví dụ: float, chuỗi)
Brian Low

27

Cách tiếp cận ADO.NET rất nhanh chóng và dễ dàng, nhưng nó có một vài điều kỳ quặc mà bạn cần lưu ý, đặc biệt là về cách xử lý DataTypes.

Bài viết tuyệt vời này sẽ giúp bạn tránh một số cạm bẫy phổ biến: http://blog.lab49.com/archives/196


Bạn đã trả lời câu hỏi của tôi (dưới dạng một bình luận ở trên).
Kevin Le - Khnle

22

Đây là những gì tôi đã sử dụng cho 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
bảng tính không được xác định ... có vẻ hơi kỳ lạ đối với tôi sau khi xác định rõ ràng mọi thứ khác.
Jeremy Holovacs

21

Làm thế nào về Excel Data Reader?

http://exceldatareader.codeplex.com/

Tôi đã sử dụng trong sự tức giận, trong môi trường sản xuất, để kéo một lượng lớn dữ liệu từ nhiều tệp Excel khác nhau vào SQL Server Compact. Nó hoạt động rất tốt và nó khá mạnh mẽ.


2
Tôi sẽ đọc dữ liệu Excel thứ hai; nó cũng đã dẫn đến thư viện Các bài kiểm tra hướng dữ liệu Excel cực kỳ hữu ích, sử dụng thuộc tính TestCaseSource của NUnit 2.5 để thực hiện các bài kiểm tra dựa trên dữ liệu bằng bảng tính Excel một cách dễ dàng. Chỉ cần lưu ý rằng Resharper chưa hỗ trợ TestCaseSource, vì vậy bạn phải sử dụng trình chạy NUnit.
David Keaveny

Thật không may, có một số vấn đề với thư viện này mà chúng tôi vừa gặp phải. Đầu tiên, chúng tôi đã có một số trường tiền tệ được phát hành dưới dạng ngày. Thứ hai, nó bị sập nếu bảng tính có bất kỳ tờ nào trống trong đó. Vì vậy, mặc dù rất dễ tích hợp, chúng tôi hiện đang đánh giá lại liệu có nên tiếp tục sử dụng thư viện này hay không. Nó dường như không được phát triển tích cực.
Ian1971

Nó cũng giả sử sự hiện diện của một số thành phần tùy chọn trong tệp xlsx khiến nó không thể đọc được dữ liệu nếu chúng vắng mặt.
RichieHulum

Chúng tôi đang gặp sự cố với các tệp Excel đến từ Dịch vụ báo cáo máy chủ SQL. Họ chỉ không làm việc, trừ khi bạn mở chúng và lưu chúng (thậm chí chưa được chỉnh sửa). @RichieHulum: bạn đang nói về những yếu tố tùy chọn nào (hy vọng điều này có thể giúp tôi với các tệp SSRS Excel của tôi)?
Peter

@Peter: Tôi nghĩ rằng đó là một <dimension>yếu tố bị thiếu trong <worksheet>đó đã gây rắc rối cho tôi.
RichieHulum

16

Đây là một số mã tôi đã viết trong C # bằng .NET 1.1 vài năm trước. Không chắc chắn nếu đây sẽ là chính xác những gì bạn cần (và có thể không phải là mã tốt nhất của tôi :)).

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

Không thể đồng ý nhiều Cherian hơn. Mã này đã nhiều năm tuổi ... trước khi tôi thành thạo với Resharper :)
hitec

2
Mã này là xấu, nhưng nó cho thấy làm thế nào để có được tên tờ, thật tuyệt!
Sam

15

Koogra là một thành phần nguồn mở được viết bằng C # để đọc và ghi các tệp Excel.


Không có vẻ đặc biệt hoạt động nữa, so với, nói, NPOI
David Burton

12

Trong khi bạn đặc biệt yêu cầu .xls, ngụ ý các định dạng tệp cũ hơn, đối với các định dạng OpenXML (ví dụ: xlsx), tôi rất khuyến nghị SDK OpenXML ( http://msdn.microsoft.com/en-us/l Library / bb448854.aspx )


8

Tôi đã đọc rất nhiều từ các tệp Excel trong C # một lúc trước và chúng tôi đã sử dụng hai cách tiếp cận:

  • API COM, nơi bạn truy cập trực tiếp vào các đối tượng của Excel và thao tác với chúng thông qua các phương thức và thuộc tính
  • Trình điều khiển ODBC cho phép sử dụng Excel như cơ sở dữ liệu.

Cách tiếp cận thứ hai nhanh hơn nhiều : đọc một bảng lớn với 20 cột và 200 dòng sẽ mất 30 giây qua COM và nửa giây qua ODBC. Vì vậy, tôi muốn giới thiệu cách tiếp cận cơ sở dữ liệu nếu tất cả những gì bạn cần là dữ liệu.

Chúc mừng

Carl



6

Tôi muốn hiển thị một phương thức đơn giản để đọc tệp xls / xlsx bằng .NET. Tôi hy vọng rằng những điều sau đây sẽ hữu ích cho bạn.

 DataTable riêng ReadExcelToTable (đường dẫn chuỗi)    
 {

     //Chuỗi kết nối

     chuỗi Conn Chuỗi = "Nhà cung cấp = Microsoft.ACE.OLEDB.12.0; Nguồn dữ liệu =" + đường dẫn + "; Thuộc tính mở rộng = 'Excel 8.0; HDR = NO; IMEX = 1';";  
     //cùng tên 
     // chuỗi Conn Chuỗi = Nhà cung cấp = Microsoft.JET.OLEDB.4.0; Nguồn dữ liệu = "+ path + //"; Thuộc tính mở rộng = 'Excel 8.0; HDR = NO; IMEX = 1'; "; 

     bằng cách sử dụng (OleDbConnection Conn = new OleDbConnection (chuỗi ký tự))
     {
        Conn.Open ();
        // Nhận tất cả tên tờ
        DataTable sheetName = Conn.GetOleDbSchemaTable (OleDbSchemaGuid.Tables, đối tượng mới [] {null, null, null, "Bảng"});  

        // Lấy tên tờ đầu tiên
        chuỗi FirstSheetName = sheetName.Rows [0] [2] .ToString (); 

        //Chuỗi truy vấn 
        chuỗi sql = string.Format ("CHỌN * TỪ [{0}]", FirstSheetName); 
        OleDbDataAd CHƯƠNG ada = new OleDbDataAd CHƯƠNG (sql, chuỗi ký tự);
        Tập dữ liệu tập hợp = tập dữ liệu mới ();
        ada.Fill (bộ);
        return set.Tables [0];   
   }
 }

Mã được lấy từ bài viết: http://www.c-sharpcorner.com/uploadfile/d2dcfc/read-excel-file-with-net/ . Bạn có thể biết thêm chi tiết từ nó.


2
rất hữu ích, đặc biệt là phần đọc tên.
martinstoeckli

4

Không miễn phí, nhưng với Office mới nhất có API .Net tự động hóa rất đẹp. (đã có API từ lâu nhưng COM khó chịu) Bạn có thể thực hiện mọi thứ bạn muốn / cần trong mã trong khi ứng dụng Office vẫn là một quy trình nền ẩn.


3
@ Loại ẩn danh Tôi đã đọc câu hỏi và đang cung cấp một giải pháp thay thế hữu ích cho việc triển khai OSS mong muốn ... bởi vì, tôi chắc chắn rằng không có gì có sẵn. Và, đánh giá bằng câu trả lời được chấp nhận, yêu cầu cài đặt Office không phải là vấn đề.
xanadont

3

Hãy tha thứ cho tôi nếu tôi không ở đây, nhưng đây không phải là mục đích của PIA Office ?


5
Có, nhưng điều đó sẽ liên quan đến việc tạo một cá thể Excel.Application, tải tệp xls, v.v. Nếu yêu cầu hoàn toàn là đọc một số dữ liệu từ tệp thì việc sử dụng một trong các phương pháp ADO.NET được mô tả sẽ dễ dàng và nhẹ nhàng hơn nhiều trong các câu trả lời khác.
Adam Ralph

Quá chậm, sử dụng Office PIA làm đường cơ sở, mọi thứ khác đều nhanh hơn - thậm chí chỉ cần sử dụng một mảng Object được truyền từ thuộc tính .Value2. Mà vẫn đang sử dụng PIA.
Loại ẩn danh

3

Gần đây, một phần để cải thiện LINQ .... Tôi đã sử dụng API tự động hóa của Excel để lưu tệp dưới dạng Bảng tính XML và sau đó xử lý tệp đó bằng LINQ sang XML.


Tôi nghi ngờ bạn có thể bảo vệ nó khỏi Excel, nhưng không phải từ người đàn ông có trình biên dịch ... giống như bất cứ điều gì ... nó chỉ là byte.
kenny

@gsvirdi, đăng câu hỏi riêng về bảo mật tệp Excel, câu hỏi này là về hiệu suất.
Loại ẩn danh


3

SmartXLS là một thành phần bảng tính excel khác hỗ trợ hầu hết các tính năng của Biểu đồ excel, công cụ công thức và có thể đọc / ghi định dạng excel2007 openxml.



2

Tôi khuyên dùng Thư viện FileHelpers là thư viện .NET miễn phí và dễ sử dụng để nhập / xuất dữ liệu từ EXCEL, độ dài cố định hoặc các bản ghi được phân tách trong tệp, chuỗi hoặc luồng + Khác.

Phần Tài liệu Liên kết Dữ liệu Excel http://filehelpers.sourceforge.net/example_exceldirthink.html


1
Tôi sẽ không làm bạn thất vọng, nhưng gần đây tôi đã bắt đầu sử dụng FileHelpers và đã bị sốc về việc nó ... tệ đến mức nào. Chẳng hạn, cách duy nhất để ánh xạ các cột trong csv sang các thuộc tính ... xin lỗi, FIELDS, của một mô hình là tạo các trường theo thứ tự các cột . Tôi không biết về bạn, nhưng tôi sẽ không dựa vào một trình biên dịch của trình biên dịch cho một trong những cân nhắc thiết kế trung tâm nhất của khung f8king của tôi.


2

Bảng tínhGear là tuyệt vời. Có, đó là một chi phí, nhưng so với việc thay đổi các giải pháp khác, nó đáng giá. Nó nhanh, đáng tin cậy, rất toàn diện, và tôi phải nói rằng sau khi sử dụng sản phẩm này trong công việc phần mềm toàn thời gian của tôi trong hơn một năm rưỡi, hỗ trợ khách hàng của họ thật tuyệt vời!


Thật khó để biện minh khi có rất nhiều cách đơn giản và hiệu quả (miễn phí) để đọc và viết vào Excel.
Loại ẩn danh

2

Giải pháp mà chúng tôi đã sử dụng, cần thiết để:

  • Cho phép đọc / ghi tệp Excel được tạo
  • Hãy nhanh trong hoạt động (không giống như sử dụng COMS)
  • Là MS Office độc lập (cần thiết để có thể sử dụng mà không cần cài đặt MS Office)
  • Được miễn phí hoặc mã nguồn mở (nhưng được phát triển tích cực)

Có một số lựa chọn, nhưng chúng tôi thấy NPoi (cổng .NET của dự án nguồn mở Poi hiện có của Java ) là tốt nhất: http://npoi.codeplex.com/

Nó cũng cho phép làm việc với các định dạng tệp .doc và .ppt


2

Nếu đó chỉ là dữ liệu dạng bảng. Tôi muốn giới thiệu người trợ giúp dữ liệu tệp của Marcos Melli có thể tải xuống ở đây .



1

bạn có thể viết một bảng tính excel tải một bảng tính excel nhất định và lưu nó dưới dạng csv (thay vì thực hiện thủ công).

sau đó bạn có thể tự động hóa nó từ c #.

và một khi đã có trong csv, chương trình c # có thể tìm kiếm điều đó.

(ngoài ra, nếu ai đó yêu cầu bạn lập trình trong excel, tốt nhất là giả vờ bạn không biết làm thế nào)

(chỉnh sửa: ah vâng, rob và ryan đều đúng)


1

Tôi biết rằng mọi người đã thực hiện một "phần mở rộng" Excel cho mục đích này.
Bạn ít nhiều tạo một nút trong Excel có nội dung "Xuất ra chương trình X", sau đó xuất và gửi dữ liệu theo định dạng mà chương trình có thể đọc.

http://msdn.microsoft.com/en-us/l Library / ms186213.aspx nên là một nơi tốt để bắt đầu.

Chúc may mắn


1

Chỉ cần thực hiện một dự án demo nhanh yêu cầu quản lý một số tệp excel. Thành phần .NET từ phần mềm GemBox phù hợp với nhu cầu của tôi. Nó có một phiên bản miễn phí với một vài hạn chế.

http://www.gemboxsoftware.com/GBS trànsheet.htmlm


FYI: Tôi đã thử nó và nó không đáp ứng nhu cầu của tôi để có thể đọc một tập tin được mã hóa.
Chad

1

Gói Excel là một thành phần mã nguồn mở (GPL) để đọc / ghi tệp Excel 2007. Tôi đã sử dụng nó trong một dự án nhỏ và API rất đơn giản. Chỉ hoạt động với XLSX (Excel 200 &), không hoạt động với XLS.

Mã nguồn cũng có vẻ được tổ chức tốt và dễ dàng để có được xung quanh (nếu bạn cần mở rộng chức năng hoặc khắc phục các sự cố nhỏ như tôi đã làm).

Lúc đầu, tôi đã thử cách tiếp cận ADO.Net (chuỗi kết nối Excel), nhưng nó có nhiều hack khó chịu - ví dụ nếu hàng thứ hai chứa một số, nó sẽ trả về ints cho tất cả các trường trong cột bên dưới và lặng lẽ thả bất kỳ dữ liệu nào không phù hợp


1

Chúng tôi sử dụng CloseXML trong các hệ thống khá lớn.

  • Miễn phí
  • Dễ dàng để cài đặt
  • Mã hóa thẳng
  • Hỗ trợ rất nhạy
  • Nhóm phát triển cực kỳ cởi mở với các đề xuất mới. Thông thường các tính năng mới và sửa lỗi được triển khai trong cùng một tuần

1

Take.ioBảng tính sẽ làm công việc này cho bạn, và miễn phí. Chỉ cần nhìn vào điều này .


Đây là một thư viện nhỏ thực sự tuyệt vời. Nó chỉ chuyển đổi mọi thứ thành Danh sách các danh sách các chuỗi, điều này phù hợp với loại công việc tôi cần.
Drewmate

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.