Làm cách nào để tạo tệp Excel (.XLS và .XLSX) trong C # mà không cần cài đặt Microsoft Office?


1892

Làm cách nào tôi có thể tạo bảng tính Excel bằng C # mà không yêu cầu cài đặt Excel trên máy đang chạy mã?


"... mà không cần cài đặt Ms Office?" một phần của câu hỏi nghe có vẻ rất không chuyên nghiệp. Bạn có thể tạo bất kỳ loại tệp nào từ chương trình C # (với một xlshoặc xlsxtệp là một trong số đó). Không có yêu cầu rằng có một chương trình trên máy tính của bạn có thể đọc được nó (giả sử, nhị phân).
Mike

30
@Mike Phần "không cần cài đặt Excel" không liên quan gì đến tính chuyên nghiệp. Đó là về sự phụ thuộc. Văn bản gốc của câu hỏi được viết là: "Lý tưởng nhất là tôi muốn nguồn mở vì vậy tôi không phải thêm bất kỳ phụ thuộc của bên thứ ba nào vào mã của mình và tôi muốn tránh sử dụng Excel trực tiếp để tạo tệp (sử dụng OLE Tự động hóa.) " Thật không may câu hỏi đã được đơn giản hóa mạnh mẽ.
Tony

5
Giả sử bạn đang cố gắng làm một cái gì đó sans thư viện hoặc mã bên ngoài, tôi không thể nói cho tệp xls, nhưng đối với các tệp xlsx, tại sao không bắt đầu bằng cách lấy một tệp hiện có, đổi tên thành tệp zip và khám phá nội dung? Một chút kỹ thuật đảo ngược sẽ cho bạn biết khá nhiều. Có một số tệp xml khác nhau và các tệp tin rels trong các thư mục và thư mục con khác nhau. Hãy thử khám phá điều đó và xem liệu đó có phải là thứ bạn có thể sao chép hoặc xem liệu bạn có thể tìm tài liệu về các không gian tên / lược đồ xml khác nhau không.
Alexander Ryan Baggett

@AlexanderRyanBaggett Điều này cực kỳ hữu ích! Đã xem qua bài đăng này trong khi làm việc tạo báo cáo tự động và khám phá tài liệu dưới dạng lưu trữ zip cung cấp khá nhiều thông tin chi tiết về việc tạo tệp tài liệu.
SentientF Meat

Câu trả lời:


1055

Bạn có thể sử dụng một thư viện gọi là ExcelL Library. Đây là một thư viện mã nguồn mở miễn phí được đăng trên Google Code:

Thư viện Excel

Đây có vẻ là một cổng của PHP ExcelWriter mà bạn đã đề cập ở trên. Nó sẽ không ghi vào định dạng .xlsx mới, nhưng họ đang làm việc để thêm chức năng đó vào.

Nó rất đơn giản, nhỏ và dễ sử dụng. Thêm vào đó, nó có DataSetHelper cho phép bạn sử dụng DataSets và DataTables để dễ dàng làm việc với dữ liệu Excel.

ExcelL Library dường như vẫn chỉ hoạt động đối với định dạng Excel cũ hơn (tệp .xls), nhưng có thể sẽ thêm hỗ trợ trong tương lai cho các định dạng 2007/2010 mới hơn.

Bạn cũng có thể sử dụng EPPlus , chỉ hoạt động cho các tệp định dạng Excel 2007/2010 (tệp .xlsx). Ngoài ra còn có NPOI hoạt động với cả hai.

Có một vài lỗi được biết đến với mỗi thư viện như được ghi chú trong các bình luận. Trong tất cả, EPPlus dường như là sự lựa chọn tốt nhất khi thời gian trôi qua. Nó dường như được tích cực cập nhật và tài liệu là tốt.

Ngoài ra, như ghi nhận của @ АртёмЦарионов dưới đây, EPPlus đã hỗ trợ cho Pivot Bàn ExcelLibrary thể có một số hỗ trợ ( vấn đề bảng Pivot trong ExcelLibrary )

Dưới đây là một vài liên kết để tham khảo nhanh:
ExcelL Library - GNU Lesser GPL
EPPlus - GNU Lesser General License (LGPL)
NPOI - Giấy phép Apache

Dưới đây là một số mã ví dụ cho ExcelL Library:

Dưới đây là một ví dụ lấy dữ liệu từ cơ sở dữ liệu và tạo sổ làm việc từ nó. Lưu ý rằng mã ExcelL Library là dòng duy nhất ở dưới cùng:

//Create the data set and table
DataSet ds = new DataSet("New_DataSet");
DataTable dt = new DataTable("New_DataTable");

//Set the locale for each
ds.Locale = System.Threading.Thread.CurrentThread.CurrentCulture;
dt.Locale = System.Threading.Thread.CurrentThread.CurrentCulture;

//Open a DB connection (in this example with OleDB)
OleDbConnection con = new OleDbConnection(dbConnectionString);
con.Open();

//Create a query and fill the data table with the data from the DB
string sql = "SELECT Whatever FROM MyDBTable;";
OleDbCommand cmd = new OleDbCommand(sql, con);
OleDbDataAdapter adptr = new OleDbDataAdapter();

adptr.SelectCommand = cmd;
adptr.Fill(dt);
con.Close();

//Add the table to the data set
ds.Tables.Add(dt);

//Here's the easy part. Create the Excel worksheet from the data set
ExcelLibrary.DataSetHelper.CreateWorkbook("MyExcelFile.xls", ds);

Tạo tệp Excel dễ dàng như vậy. Bạn cũng có thể tự tạo các tệp Excel, nhưng chức năng trên là điều thực sự gây ấn tượng với tôi.


247
ExcelL Library đã được thay thế bởi EPPlus đặc biệt - epplus.codeplex.com . Jan cập nhật nó thường xuyên. Đã sử dụng nó và nó là một trong những dự án nguồn mở tốt nhất mà chúng tôi đã làm việc cùng.
Đánh dấu

3
Cần lưu ý rằng ExcelL Library có rất nhiều vấn đề về hiệu năng khi xử lý các bộ dữ liệu lớn (lớn hơn 5000 hàng với nhiều cột). Hiện đang thực hiện một sửa đổi lớn của cơ sở mã tại nơi làm việc để chúng tôi có thể sử dụng nó trong một dự án.
ross thẩm quyền

EPPlus dường như ít lỗi hơn nhiều so với ExcelL Library, NHƯNG đó là GPL và do đó chỉ là một giải pháp cho các dự án nguồn mở.
Seth


6
Còn về CloseXML thì sao? Tôi có thể chứng minh là hữu ích trong các dự án của bạn.
Amadeus Sánchez

589

Nếu bạn hài lòng với định dạng xlsx, hãy thử dự án GitHub của tôi, EPPlus . Nó bắt đầu với nguồn từ ExcelPackage, nhưng hôm nay nó được viết lại hoàn toàn. Nó hỗ trợ các phạm vi, kiểu dáng ô, biểu đồ, hình dạng, hình ảnh, phạm vi được đặt tên, Trình lọc tự động và rất nhiều thứ khác.


77
Giấy phép hiện là LGPL, ghi chú phát hành tại đây: epplus.codeplex.com/release/view/79802
Simon D

13
Các ví dụ rất hữu ích. Tôi đã có thể thay đổi mã của mình từ việc sử dụng thư viện interop của Microsoft (chậm khủng khiếp) sang thư viện này (phiên bản 4.x) trong vài giờ. Điểm chuẩn của tôi viết một tệp có hai tab và khoảng 750.000 ô. Sử dụng MS interop phải mất 13 phút. Sử dụng EPPlus mất 10 giây, tăng tốc khoảng 80 lần. Rất vui!
Paul Chernoch

3
Để rõ ràng trong chủ đề này, LGPL cho phép phần mềm được liên kết đến mà không có phần lây nhiễm của GPL xảy ra. Bạn chỉ cần mở các thay đổi nguồn bạn thực hiện đối với CloseXml hoặc nếu bạn trực tiếp đặt mã nguồn (trái ngược với tham chiếu các cụm công cụ đã đóng) trong ứng dụng của bạn thì bạn cần mở nguồn ứng dụng của mình.
Chris Marisic

4
@Paul Chernoch: Chúng tôi điền vào các bảng Excel lớn với sự can thiệp rất nhanh. Bí quyết là làm một bản cập nhật số lượng lớn. Tạo một khối đối tượng [,], điền vào đó, sau đó viết ma trận đó vào Excel cùng một lúc: excelWorksheet.get_Range (phạm vi) .Value2 = block;
Marc Meketon

2
Có vẻ như giấy phép đang chuyển từ giấy phép LGPL sang giấy phép Polyform Phi thương mại 1.0.0
Luke

175

Và những gì về việc sử dụng Open XML SDK 2.0 cho Microsoft Office?

Một vài lợi ích:

  • Không yêu cầu cài đặt Office
  • Được tạo bởi Microsoft = tài liệu MSDN phong nha
  • Chỉ cần một .Net dll để sử dụng trong dự án
  • SDK đi kèm với nhiều công cụ như diff, trình xác nhận, v.v.

Liên kết:


3
Điều quan trọng cần lưu ý là DLL cho việc này chỉ hơn 5 MB và giới hạn ở các định dạng Office 2007. Nhưng chắc chắn là giải pháp dễ nhất và nhanh nhất phù hợp với tôi.
Josh Brown

18
Chỉ cần một cái đầu lên là v2.5 đã ra và có thể tải xuống ở đây .
Snuffleupagus

10
SDK mô hình hóa XML thành các lớp, sao cho mỗi thẻ XML được ánh xạ tới một thẻ và sau đó bạn phải xây dựng hệ thống phân cấp lớp (mỗi trường hợp có một tập hợp các thể hiện / thẻ con) một cách chính xác. Điều này có nghĩa là bạn phải biết cấu trúc XML của một tệp Excel, rất phức tạp. Việc sử dụng trình bao bọc như EPPlus, được đề cập ở trên dễ dàng hơn nhiều, giúp đơn giản hóa mọi thứ.
Tsahi Asher

2
Có thể tìm thấy một mẫu tuyệt vời của Microsoft Open XML SDK - Open XML Writer tại polymathprogrammer.com/2012/08/06/ Khăn hoặc xem giải pháp Stack Overflow stackoverflow.com/questions/11370672/ trộm
Greg

4
Tôi thấy Trình soạn thảo XML mở của Microsoft Open XML rất tuyệt. Sử dụng các giải pháp ở trên, (đặc biệt là mẫu của Vincent Tom (Poly Math)), thật dễ dàng để xây dựng một nhà văn truyền qua các tập dữ liệu lớn và viết các bản ghi theo cách tương tự và không quá phức tạp với những gì bạn làm CSV; nhưng đó là thay vì bạn viết xml. Open XML là suy nghĩ mà Microsoft coi đó là các định dạng Office mới. Và bạn luôn có thể đổi tên chúng từ các tệp .xslx thành .zip nếu bạn cảm thấy muốn chọc vào nội dung XML của chúng.
Greg

167

Tôi đã sử dụng thành công các dự án nguồn mở sau:

  • ExcelPackage cho các định dạng OOXML (Office 2007)

  • NPOI cho định dạng .XLS (Office 2003). NPOI 2.0 (Beta) cũng hỗ trợ XLSX.

Hãy xem bài viết trên blog của tôi:

Tạo bảng tính Excel .XLS và .XLSX bằng C #

NPOI với Bảng Excel và Biểu đồ động


6
Một lưu ý về NPOI - Tham chiếu Hàng và Cột là không dựa trên. Không hoạt động tốt để điền vào một mẫu hiện có.
John M

108

Bạn có thể sử dụng OLEDB để tạo và thao tác các tệp Excel. Kiểm tra điều này: Đọc và viết Excel bằng OLEDB .

Ví dụ điển hình:

using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\temp\\test.xls;Extended Properties='Excel 8.0;HDR=Yes'"))
{
  conn.Open();
  OleDbCommand cmd = new OleDbCommand("CREATE TABLE [Sheet1] ([Column1] string, [Column2] string)", conn);
  cmd.ExecuteNonQuery();
}

EDIT - Một số liên kết khác:


4
Ai đó có thể xác nhận nếu điều này hoạt động khi chạy trong x64? Tôi khá chắc chắn Jet chỉ hoạt động nếu ứng dụng của bạn được biên dịch hoặc chạy ở chế độ 32 bit.
Lamar

2
Tôi vừa thử nghiệm kết nối này và nó đã bị lỗi trên Windows Server 2008 R2 x64 RC, có vẻ như người ta phải cài đặt Trình điều khiển hệ thống Office 2007: Các thành phần kết nối dữ liệu [ microsoft.com/doads/iêu
Chris Richner

25
Hãy cẩn thận với điều này - đó là một mối quan hệ xấu xí lớn (ví dụ, đôi khi nó đoán một loại cột và loại bỏ tất cả dữ liệu không phù hợp).
dbkk

9
Người ta phải rất cẩn thận nếu sử dụng phương pháp này. Tôi thấy dữ liệu không ổn định ở định dạng hoàn hảo.
Kenny Mann

9
Là một người phải sử dụng OleDb trong một dự án lớn, tôi nói HÃY TUYỆT VỜI TỪ NÓ! Đôi khi, nó không thể truy xuất giá trị ô chỉ vì không thể hiểu định dạng. Nó không có thao tác xóa. Nó hoạt động hoàn toàn khác nhau và không thể đoán trước ngay cả với một thay đổi nhỏ nhất của nhà cung cấp. Tôi muốn nói đi cho một giải pháp thương mại đã được chứng minh.
Caner Öncü

80

Giải pháp thương mại, SpreadsheetGear cho .NET sẽ làm điều đó.

Bạn có thể xem các mẫu ASP.NET (C # và VB) trực tiếp tại đây và tải xuống phiên bản đánh giá tại đây .

Tuyên bố miễn trừ trách nhiệm: Tôi sở hữu Bảng tínhGear LLC


10
Bạn có một sản phẩm tuyệt vời nhưng tôi nghĩ rất nhiều người ở đây đang mong đợi các giải pháp miễn phí. Điều đó có thể giải thích các phiếu giảm.
md1337

65

Một vài lựa chọn tôi đã sử dụng:

Nếu XLSX là bắt buộc: ExcelPackage là một khởi đầu tốt nhưng đã chết khi nhà phát triển bỏ công việc trên nó. ExML nhặt từ đó và thêm một vài tính năng. ExML không phải là một lựa chọn tồi, tôi vẫn đang sử dụng nó trong một vài trang web sản xuất.

Tuy nhiên, đối với tất cả các dự án mới của tôi, tôi đang sử dụng NPOI , cổng .NET của Apache POI . NPOI 2.0 (Alpha) cũng hỗ trợ XLSX.


Hãy cẩn thận với ExcelPackage nếu bạn cần hỗ trợ XLS. Tôi đã có một thời gian khó khăn với nó và cuối cùng chuyển sang ExcelL Library.
Jeremy

Chắc chắn là đúng. ExcelPackage / ExML chỉ là một lựa chọn tốt nếu bạn cần hỗ trợ XLSX.
Nate

5
Lưu ý rằng ExcelPackage có một người kế nhiệm: EPPlus ( epplus.codeplex.com ) hỗ trợ XLSX. Mối quan tâm duy nhất của tôi, so với NPOI chẳng hạn, là hiệu suất, ví dụ như khi có rất nhiều cột.
Pragmateek

63

Một tùy chọn cực kỳ nhẹ có thể là sử dụng các bảng HTML. Chỉ cần tạo các thẻ đầu, thân và bảng trong một tệp và lưu nó dưới dạng tệp có đuôi .xls. Có các thuộc tính cụ thể của Microsoft mà bạn có thể sử dụng để định kiểu đầu ra, bao gồm các công thức.

Tôi nhận ra rằng bạn có thể không mã hóa điều này trong một ứng dụng web, nhưng đây là một ví dụ về thành phần của tệp Excel thông qua bảng HTML. Kỹ thuật này có thể được sử dụng nếu bạn đang mã hóa ứng dụng bảng điều khiển, ứng dụng máy tính để bàn hoặc dịch vụ.


6
Nó rất đặc biệt nhưng nó hoạt động (không đề cập đến excel đưa ra cảnh báo khi mở) và rất đơn giản, nó xứng đáng có một vị trí như một giải pháp. Mặc dù chỉ để hiển thị rằng bạn có thể xuất tệp excel :))
Luka Ramishvili

3
Giải pháp này hoạt động tốt với tôi, chỉ cần lưu ý rằng bạn không thể sử dụng phần mở rộng .xlsx
Jill

Một số người trong tổ chức của tôi không thể mở tệp excel theo cách này trong Office 2010 trở lên. Không biết vấn đề là gì, nhưng tôi đã phải triển khai triển khai OpenXML của riêng mình. (xem câu trả lời Sogger của)
Kristen Hammack

49

Nếu bạn đang tạo tệp Excel 2007/2010, hãy thử dự án nguồn mở này: https://github.com/closesxml/closesxml

Nó cung cấp một cách hướng đối tượng để thao tác các tệp (tương tự VBA) mà không phải đối phó với sự phức tạp của Tài liệu XML. Nó có thể được sử dụng bởi bất kỳ ngôn ngữ .NET nào như C # và Visual Basic (VB).

CloseXML cho phép bạn tạo các tệp Excel 2007/2010 mà không cần ứng dụng Excel. Ví dụ điển hình là tạo báo cáo Excel trên máy chủ web:

var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("Sample Sheet");
worksheet.Cell("A1").Value = "Hello World!";
workbook.SaveAs("HelloWorld.xlsx");

9
Tôi đã thử sử dụng điều này trong một dự án xây dựng các bảng Excel khá lớn. Thư viện tuyệt vời, nhưng cực kỳ kém về hiệu suất. Tôi vừa thực hiện một so sánh cho dự án mà tôi đang thực hiện: closXML (v 0.53.3) mất 92.489 ms trong khi EPPlus (v 2.9.03, để thử nghiệm - chúng tôi không thể sử dụng vì GPL) mất 16.500 ms.
Druid

1
@Druid giấy phép là LGPL giả sử bạn không sửa đổi mã nguồn thành CloseXML, nó miễn phí sử dụng epplus.codeplex.com/license
Chris


47

Bạn thực sự có thể muốn kiểm tra các lớp interop có sẵn trong C # (ví dụ: Microsoft.Office.Interop.ExcelBạn nói không có OLE (điều này không phải), nhưng các lớp interop rất dễ sử dụng. Hãy xem Tài liệu C # tại đây (Interop cho Excel bắt đầu trang 1072 của C # PDF).

Bạn có thể bị ấn tượng nếu bạn chưa thử chúng.

Xin được cảnh báo về lập trường của Microsoft về vấn đề này:

Microsoft hiện không khuyến nghị và không hỗ trợ Tự động hóa các ứng dụng Microsoft Office từ bất kỳ ứng dụng hoặc thành phần máy khách không tương tác, không giám sát nào (bao gồm cả ASP, ASP.NET, DCOM và NT Services), vì Office có thể thể hiện hành vi không ổn định và / hoặc bế tắc khi Office được chạy trong môi trường này.


6
Nhưng bạn phải chắc chắn rằng bạn loại bỏ mọi thứ bằng tay, nếu không bạn sẽ bị rò rỉ bộ nhớ
MagicKat

8
@Ricky B: Ngoài ra, theo kinh nghiệm của tôi với interop là nó sử dụng excel. Mỗi lần chúng tôi sử dụng nó, nếu Excel không được cài đặt trên máy, chúng tôi sẽ nhận được các ngoại lệ COM.
MagicKat

1
Với OLE, ngay cả với những lần xử lý rất cẩn thận, cuối cùng nó cũng bị rò rỉ bộ nhớ hoặc sự cố. Điều này được cho là ổn đối với các ứng dụng / máy trạm tham dự, nhưng đối với các máy chủ không được khuyến nghị (MS có KB nêu rõ điều này). Đối với máy chủ của chúng tôi, chúng tôi chỉ cần khởi động lại hàng đêm. Một lần nữa, nó hoạt động tốt.
Jennifer Zouak

11
@Geoffrey: ah OK, bạn sẽ khiến tôi làm việc cho nó :) -> support.microsoft.com/kb/257757 Microsoft hiện không khuyến nghị và không hỗ trợ, Tự động hóa các ứng dụng Microsoft Office từ mọi ứng dụng không được giám sát, không- ứng dụng khách tương tác ...
Jennifer Zouak

4
Tôi sẽ đến cuộc thảo luận này sau khi vật lộn hơn một tuần trên interop, và trừ khi nhu cầu của bạn rất đơn giản, điều này sẽ không hiệu quả. Sự hỗ trợ cho việc định dạng bảng tính của bạn là rất nhiều, đây được cho là lý do để tạo tệp .xls chứ không chỉ là tệp .csv phẳng. Ví dụ: bạn đã thử xuất nhiều hơn 911 ký tự trong một ô hay bạn đã thử thiết lập độ rộng của các ô được hợp nhất một cách nhất quán chưa? Tôi có, và tôi không thể nói cho bạn biết bây giờ tôi ghét cái thứ nhảm nhí này đến mức nào ... Hãy tự mình làm và đi với một trong những thư viện miễn phí được đề cập trong cuộc thảo luận này.
md1337

34

Dưới đây là một hoàn toàn miễn phí C # thư viện, cho phép bạn xuất khẩu từ một DataSet, DataTablehoặc List<>vào một chính hãng Excel 2007 tập tin .xlsx, sử dụng các thư viện OpenXML:

http://mikeledgeledridease.com/pages/CSharp/ExportToExcel.htmlm

Mã nguồn đầy đủ được cung cấp - miễn phí - cùng với hướng dẫn và ứng dụng demo.

Sau khi thêm lớp này vào ứng dụng của bạn, bạn có thể xuất Bộ dữ liệu của mình sang Excel chỉ bằng một dòng mã:

CreateExcelFile.CreateExcelDocument(myDataSet, "C:\\Sample.xlsx");

Nó không đơn giản hơn thế nhiều ...

Và nó thậm chí không yêu cầu Excel phải có mặt trên máy chủ của bạn.


1
Điều này có vẻ hơi sai lệch, vì bạn đang yêu cầu quyên góp để có được tất cả các tính năng.
UrbanEsc

Điều đó đúng một phần: Phiên bản hoàn toàn miễn phí sẽ tạo ra một tệp .xlsx hoàn hảo cho bạn và tất cả mã nguồn được cung cấp. Nếu bạn quyên góp $ 10 trở lên cho một trong hai tổ chức từ thiện đó (trong đó tôi hoàn toàn không nhận được gì), thì bạn sẽ nhận được phiên bản "tốt hơn" cho biết cách thực hiện định dạng, ngày, v.v. Với chi phí của các sản phẩm của bên thứ ba, tôi nghĩ Thay vào đó, tặng 10 đô la cho một lý do chính đáng cũng rất xứng đáng!
Mike Gledhill


23

Bạn có thể muốn xem GemBox.S Lansheet .

Họ có một phiên bản miễn phí với tất cả các tính năng nhưng giới hạn ở 150 hàng trên mỗi tờ và 5 tờ cho mỗi sổ làm việc, nếu điều đó nằm trong nhu cầu của bạn.

Tôi chưa cần phải sử dụng nó, nhưng có vẻ thú vị.


21

Syncfusion Essential XlsIO có thể làm điều này. Nó không phụ thuộc vào văn phòng của Microsoft và cũng có hỗ trợ cụ thể cho các nền tảng khác nhau.

Mẫu mã:

//Creates a new instance for ExcelEngine.
ExcelEngine excelEngine = new ExcelEngine();
//Loads or open an existing workbook through Open method of IWorkbooks
IWorkbook workbook = excelEngine.Excel.Workbooks.Open(fileName);
//To-Do some manipulation|
//To-Do some manipulation
//Set the version of the workbook.
workbook.Version = ExcelVersion.Excel2013;
//Save the workbook in file system as xlsx format
workbook.SaveAs(outputFileName);

Toàn bộ bộ điều khiển có sẵn miễn phí thông qua chương trình cấp phép cộng đồng nếu bạn đủ điều kiện (doanh thu dưới 1 triệu USD). Lưu ý: Tôi làm việc cho Syncfusion.


18

Tốt,

bạn cũng có thể sử dụng thư viện của bên thứ ba như Aspose .

Thư viện này có lợi ích là nó không yêu cầu cài đặt Excel trên máy của bạn, điều này sẽ rất lý tưởng trong trường hợp của bạn.


Để chính xác hơn, bạn có thể sử dụng Aspose.Cells cho .NET để tạo các tệp Excel (XLS, XLSX) trong ứng dụng .NET của bạn.
Shahzad Latif

9
Có, bạn có thể, nếu bạn không phải trả một khoản phí giấy phép tối thiểu là $ 999. Hãy thử thư viện MikesKnowledgeBase ... rẻ hơn 999 đô la so với cái này !!
Mike Gledhill

17

OpenXML cũng là một giải pháp thay thế tốt giúp tránh cài đặt MS Excel trên Máy chủ. Open XML SDK 2.0 do Microsoft cung cấp giúp đơn giản hóa công việc thao tác các gói Open XML và các thành phần lược đồ Open XML nằm bên trong một gói. Giao diện lập trình ứng dụng XML mở (API) gói gọn nhiều tác vụ phổ biến mà các nhà phát triển thực hiện trên các gói Open XML.

Hãy xem OpenXML: Giải pháp thay thế giúp tránh cài đặt MS Excel trên Máy chủ


17

Các thư viện XML Office 2003 khác nhau hoạt động khá tốt cho các tệp excel nhỏ hơn. Tuy nhiên, tôi thấy kích thước tuyệt đối của một sổ làm việc lớn được lưu ở định dạng XML là một vấn đề. Ví dụ: một sổ làm việc tôi làm việc với nó sẽ là 40 MB ở định dạng XLSX mới (và được đóng gói chặt chẽ hơn) trở thành tệp XML 360 MB.

Theo như nghiên cứu của tôi, có hai gói thương mại cho phép xuất ra các định dạng tệp nhị phân cũ hơn. Họ đang:

Tôi cũng không rẻ (lần lượt là 500USD và 800USD). nhưng cả hai đều hoạt động độc lập với chính Excel.

Điều tôi sẽ tò mò là mô-đun đầu ra Excel cho những người thích OpenOffice.org. Tôi tự hỏi nếu chúng có thể được chuyển từ Java sang .Net.


Cái này hoạt động trên cả .net và java, và không đắt tiền. SmartXLS smartxls.com
liya


15

Gần đây tôi đã sử dụng FlexCel.NET và thấy nó là một thư viện tuyệt vời! Tôi không nói rằng về quá nhiều sản phẩm phần mềm. Không có điểm nào trong việc đưa ra toàn bộ doanh số bán hàng ở đây, bạn có thể đọc tất cả các tính năng trên trang web của họ.

Nó là một sản phẩm thương mại, nhưng bạn có được nguồn đầy đủ nếu bạn mua nó. Vì vậy, tôi cho rằng bạn có thể biên dịch nó vào hội đồng của bạn nếu bạn thực sự muốn. Mặt khác, nó chỉ là một lắp ráp bổ sung cho xcopy - không có cấu hình hoặc cài đặt hoặc bất cứ thứ gì tương tự.

Tôi không nghĩ rằng bạn sẽ tìm mọi cách để làm điều này mà không có thư viện của bên thứ ba như .NET framework, rõ ràng, không có sự hỗ trợ nào cho nó và OLE Automatic chỉ là cả một thế giới đau khổ.


15

Tôi đã viết một mã đơn giản để xuất dữ liệu sang excel mà không cần sử dụng đối tượng excel bằng cách sử dụng System.IO.StreamWriter.

Dưới đây là mã sẽ đọc tất cả các bảng từ tập dữ liệu và viết chúng vào từng tờ một. Tôi đã giúp đỡ từ bài viết này .

public static void exportToExcel(DataSet source, string fileName)
{
        const string endExcelXML = "</Workbook>";
        const string startExcelXML = "<xml version>\r\n<Workbook " +
                 "xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n" +
                 " xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n " +
                 "xmlns:x=\"urn:schemas-    microsoft-com:office:" +
                 "excel\"\r\n xmlns:ss=\"urn:schemas-microsoft-com:" +
                 "office:spreadsheet\">\r\n <Styles>\r\n " +
                 "<Style ss:ID=\"Default\" ss:Name=\"Normal\">\r\n " +
                 "<Alignment ss:Vertical=\"Bottom\"/>\r\n <Borders/>" +
                 "\r\n <Font/>\r\n <Interior/>\r\n <NumberFormat/>" +
                 "\r\n <Protection/>\r\n </Style>\r\n " +
                 "<Style ss:ID=\"BoldColumn\">\r\n <Font " +
                 "x:Family=\"Swiss\" ss:Bold=\"1\"/>\r\n </Style>\r\n " +
                 "<Style     ss:ID=\"StringLiteral\">\r\n <NumberFormat" +
                 " ss:Format=\"@\"/>\r\n </Style>\r\n <Style " +
                 "ss:ID=\"Decimal\">\r\n <NumberFormat " +
                 "ss:Format=\"0.0000\"/>\r\n </Style>\r\n " +
                 "<Style ss:ID=\"Integer\">\r\n <NumberFormat " +
                 "ss:Format=\"0\"/>\r\n </Style>\r\n <Style " +
                 "ss:ID=\"DateLiteral\">\r\n <NumberFormat " +
                 "ss:Format=\"mm/dd/yyyy;@\"/>\r\n </Style>\r\n " +
                 "</Styles>\r\n ";
        System.IO.StreamWriter excelDoc = null;
        excelDoc = new System.IO.StreamWriter(fileName);

        int sheetCount = 1;
        excelDoc.Write(startExcelXML);
        foreach (DataTable table in source.Tables)
        {
            int rowCount = 0;
            excelDoc.Write("<Worksheet ss:Name=\"" + table.TableName + "\">");
            excelDoc.Write("<Table>");
            excelDoc.Write("<Row>");
            for (int x = 0; x < table.Columns.Count; x++)
            {
                excelDoc.Write("<Cell ss:StyleID=\"BoldColumn\"><Data ss:Type=\"String\">");
                excelDoc.Write(table.Columns[x].ColumnName);
                excelDoc.Write("</Data></Cell>");
            }
            excelDoc.Write("</Row>");
            foreach (DataRow x in table.Rows)
            {
                rowCount++;
                //if the number of rows is > 64000 create a new page to continue output
                if (rowCount == 64000)
                {
                    rowCount = 0;
                    sheetCount++;
                    excelDoc.Write("</Table>");
                    excelDoc.Write(" </Worksheet>");
                    excelDoc.Write("<Worksheet ss:Name=\"" + table.TableName + "\">");
                    excelDoc.Write("<Table>");
                }
                excelDoc.Write("<Row>"); //ID=" + rowCount + "
                for (int y = 0; y < table.Columns.Count; y++)
                {
                    System.Type rowType;
                    rowType = x[y].GetType();
                    switch (rowType.ToString())
                    {
                        case "System.String":
                            string XMLstring = x[y].ToString();
                            XMLstring = XMLstring.Trim();
                            XMLstring = XMLstring.Replace("&", "&");
                            XMLstring = XMLstring.Replace(">", ">");
                            XMLstring = XMLstring.Replace("<", "<");
                            excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
                                           "<Data ss:Type=\"String\">");
                            excelDoc.Write(XMLstring);
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.DateTime":
                            //Excel has a specific Date Format of YYYY-MM-DD followed by  
                            //the letter 'T' then hh:mm:sss.lll Example 2005-01-31T24:01:21.000
                            //The Following Code puts the date stored in XMLDate 
                            //to the format above
                            DateTime XMLDate = (DateTime)x[y];
                            string XMLDatetoString = ""; //Excel Converted Date
                            XMLDatetoString = XMLDate.Year.ToString() +
                                 "-" +
                                 (XMLDate.Month < 10 ? "0" +
                                 XMLDate.Month.ToString() : XMLDate.Month.ToString()) +
                                 "-" +
                                 (XMLDate.Day < 10 ? "0" +
                                 XMLDate.Day.ToString() : XMLDate.Day.ToString()) +
                                 "T" +
                                 (XMLDate.Hour < 10 ? "0" +
                                 XMLDate.Hour.ToString() : XMLDate.Hour.ToString()) +
                                 ":" +
                                 (XMLDate.Minute < 10 ? "0" +
                                 XMLDate.Minute.ToString() : XMLDate.Minute.ToString()) +
                                 ":" +
                                 (XMLDate.Second < 10 ? "0" +
                                 XMLDate.Second.ToString() : XMLDate.Second.ToString()) +
                                 ".000";
                            excelDoc.Write("<Cell ss:StyleID=\"DateLiteral\">" +
                                         "<Data ss:Type=\"DateTime\">");
                            excelDoc.Write(XMLDatetoString);
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.Boolean":
                            excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
                                        "<Data ss:Type=\"String\">");
                            excelDoc.Write(x[y].ToString());
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.Int16":
                        case "System.Int32":
                        case "System.Int64":
                        case "System.Byte":
                            excelDoc.Write("<Cell ss:StyleID=\"Integer\">" +
                                    "<Data ss:Type=\"Number\">");
                            excelDoc.Write(x[y].ToString());
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.Decimal":
                        case "System.Double":
                            excelDoc.Write("<Cell ss:StyleID=\"Decimal\">" +
                                  "<Data ss:Type=\"Number\">");
                            excelDoc.Write(x[y].ToString());
                            excelDoc.Write("</Data></Cell>");
                            break;
                        case "System.DBNull":
                            excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
                                  "<Data ss:Type=\"String\">");
                            excelDoc.Write("");
                            excelDoc.Write("</Data></Cell>");
                            break;
                        default:
                            throw (new Exception(rowType.ToString() + " not handled."));
                    }
                }
                excelDoc.Write("</Row>");
            }
            excelDoc.Write("</Table>");
            excelDoc.Write(" </Worksheet>");
            sheetCount++;
        }


        excelDoc.Write(endExcelXML);
        excelDoc.Close();
    }

1
Giống như bài báo đã nói, đó là XML mà Excel sẽ đọc chứ không thực sự là tệp XLS, điều đó có nghĩa là nó chỉ có thể hoạt động trong Excel chứ không phải các chương trình khác đọc bảng tính. Nhưng nó có lẽ tốt hơn các câu trả lời bảng HTML tương đương ở đây!
Rup

Hỗ trợ xlsx ? OpenXML ?
Kiquenet

14

Chỉ muốn thêm một tham chiếu khác vào giải pháp của bên thứ ba trực tiếp giải quyết vấn đề của bạn: http://www.officewriter.com

(Tuyên bố miễn trừ trách nhiệm: Tôi làm việc cho SoftArtisans, công ty sản xuất OfficeWriter)



12

Đây là một cách để làm điều đó với LINQ to XML, hoàn thành với mã mẫu:

Nhập và xuất nhanh dữ liệu Excel với LINQ sang XML

Nó hơi phức tạp, vì bạn phải nhập không gian tên và vv, nhưng nó cho phép bạn tránh mọi phụ thuộc bên ngoài.

(Tất nhiên, tất nhiên, đó là VB .NET, không phải C #, nhưng bạn luôn có thể cô lập các công cụ VB .NET trong dự án riêng của mình để sử dụng XML Literals và làm mọi thứ khác trong C #.)


12

Một số nhà cung cấp thành phần bên thứ 3 như Infragistic hoặc Syncfusion cung cấp khả năng xuất Excel rất tốt mà không yêu cầu Microsoft Excel phải được cài đặt.

Vì các nhà cung cấp này cũng cung cấp các thành phần lưới UI tiên tiến, các thành phần này đặc biệt tiện dụng nếu bạn muốn kiểu dáng và bố cục của xuất excel để mô phỏng trạng thái hiện tại của lưới trong giao diện người dùng của ứng dụng của bạn.

Nếu xuất của bạn dự định được thực hiện phía máy chủ, tập trung vào dữ liệu sẽ được xuất và không có liên kết đến giao diện người dùng, thì tôi sẽ chọn một trong các tùy chọn nguồn mở miễn phí (ví dụ: ExcelL Library).

Trước đây tôi đã tham gia vào các dự án đã cố gắng sử dụng tự động hóa phía máy chủ trên bộ Microsoft Office. Dựa trên kinh nghiệm này, tôi rất muốn giới thiệu cách tiếp cận đó.


12
public class GridViewExportUtil
{
    public static void Export(string fileName, GridView gv)
    {
        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.AddHeader(
            "content-disposition", string.Format("attachment; filename={0}", fileName));
        HttpContext.Current.Response.ContentType = "application/ms-excel";

        using (StringWriter sw = new StringWriter())
        {
            using (HtmlTextWriter htw = new HtmlTextWriter(sw))
            {
                //  Create a form to contain the grid
                Table table = new Table();

                //  add the header row to the table
                if (gv.HeaderRow != null)
                {
                    GridViewExportUtil.PrepareControlForExport(gv.HeaderRow);
                    table.Rows.Add(gv.HeaderRow);
                }

                //  add each of the data rows to the table
                foreach (GridViewRow row in gv.Rows)
                {
                    GridViewExportUtil.PrepareControlForExport(row);
                    table.Rows.Add(row);
                }

                //  add the footer row to the table
                if (gv.FooterRow != null)
                {
                    GridViewExportUtil.PrepareControlForExport(gv.FooterRow);
                    table.Rows.Add(gv.FooterRow);
                }

                //  render the table into the htmlwriter
                table.RenderControl(htw);

                //  render the htmlwriter into the response
                HttpContext.Current.Response.Write(sw.ToString());
                HttpContext.Current.Response.End();
            }
        }
    }

    /// <summary>
    /// Replace any of the contained controls with literals
    /// </summary>
    /// <param name="control"></param>
    private static void PrepareControlForExport(Control control)
    {
        for (int i = 0; i < control.Controls.Count; i++)
        {
            Control current = control.Controls[i];
            if (current is LinkButton)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as LinkButton).Text));
            }
            else if (current is ImageButton)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as ImageButton).AlternateText));
            }
            else if (current is HyperLink)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as HyperLink).Text));
            }
            else if (current is DropDownList)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as DropDownList).SelectedItem.Text));
            }
            else if (current is CheckBox)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as CheckBox).Checked ? "True" : "False"));
            }

            if (current.HasControls())
            {
                GridViewExportUtil.PrepareControlForExport(current);
            }
        }
    }
}

Xin chào giải pháp này là xuất chế độ xem lưới của bạn sang tệp excel của bạn, nó có thể giúp bạn thoát ra


7
Không, điều này tạo ra HTML được đánh dấu là một tệp Excel chứ không phải là một tệp Excel thực sự. Có, chính Excel sẽ mở OK, nhưng các chương trình khác sử dụng bảng tính - ví dụ như trình xem Excel miễn phí của Microsoft - sẽ không chấp nhận. Bạn sẽ làm tốt hơn để tạo một tệp Excel thực bằng một trong các thư viện ở đây.
Rup

Bạn cũng nên sử dụng System.Net.Mime.ContentDisposeition để tạo văn bản tiêu đề xử lý nội dung thay vì nối thêm chuỗi - sẽ đối phó với tên tệp có chứa khoảng trắng, v.v.
Rup

12

Bạn có thể tạo các tệp Excel được định dạng độc đáo bằng thư viện này: http://officehelper.codeplex.com/documentation
Xem mẫu dưới đây:

using (ExcelHelper helper = new ExcelHelper(TEMPLATE_FILE_NAME, GENERATED_FILE_NAME))
{
    helper.Direction = ExcelHelper.DirectionType.TOP_TO_DOWN;
    helper.CurrentSheetName = "Sheet1";
    helper.CurrentPosition = new CellRef("C3");

    //the template xlsx should contains the named range "header"; use the command "insert"/"name".
    helper.InsertRange("header");

    //the template xlsx should contains the named range "sample1";
    //inside this range you should have cells with these values:
    //<name> , <value> and <comment>, which will be replaced by the values from the getSample()
    CellRangeTemplate sample1 = helper.CreateCellRangeTemplate("sample1", new List<string> {"name", "value", "comment"}); 
    helper.InsertRange(sample1, getSample());

    //you could use here other named ranges to insert new cells and call InsertRange as many times you want, 
    //it will be copied one after another;
    //even you can change direction or the current cell/sheet before you insert

    //typically you put all your "template ranges" (the names) on the same sheet and then you just delete it
    helper.DeleteSheet("Sheet3");
}        

nơi mẫu trông như thế này:

private IEnumerable<List<object>> getSample()
{
    var random = new Random();

    for (int loop = 0; loop < 3000; loop++)
    {
        yield return new List<object> {"test", DateTime.Now.AddDays(random.NextDouble()*100 - 50), loop};
    }
}

10

Cách đơn giản nhất và nhanh nhất để tạo tệp Excel từ C # là sử dụng Công cụ năng suất XML mở. Công cụ năng suất XML mở đi kèm với cài đặt Open XML SDK. Công cụ đảo ngược các kỹ sư bất kỳ tệp Excel thành mã C #. Mã C # sau đó có thể được sử dụng để tạo lại tệp đó.

Tổng quan về quá trình liên quan là:

  1. Cài đặt SDK XML mở bằng công cụ.
  2. Tạo tệp Excel bằng ứng dụng khách Excel mới nhất với giao diện mong muốn. Đặt tên cho nó DesiredLook.xlsx.
  3. Với công cụ mở DesiredLook.xlsxvà nhấp vào nút Reflect Code gần trên cùng. nhập mô tả hình ảnh ở đây
  4. Mã C # cho tệp của bạn sẽ được tạo trong khung bên phải của công cụ. Thêm phần này vào giải pháp C # của bạn và tạo các tệp với giao diện mong muốn đó.

Là một phần thưởng, phương pháp này hoạt động cho mọi tệp Word và PowerPoint. Là nhà phát triển C #, sau đó bạn sẽ thực hiện thay đổi mã để phù hợp với nhu cầu của bạn.

Tôi đã phát triển một ứng dụng WPF đơn giản trên github sẽ chạy trên Windows cho mục đích này. Có một lớp giữ chỗ được gọi là GeneratedClassnơi bạn có thể dán mã được tạo. Nếu bạn quay lại một phiên bản của tệp, nó sẽ tạo một tệp excel như thế này:

nhập mô tả hình ảnh ở đây


1
Tôi chưa thử giải pháp Open XML SDK này nhưng Wow, tôi chắc chắn sẽ kiểm tra nó. Tôi đã làm việc với các công cụ như thế này trong nhiều năm và không biết gì về công cụ này. Tôi đã xuất bản FOSS đơn giản của riêng mình để chuyển đổi tệp sang XLSX bằng .NET: github.com/TonyGravagno/NebulaXConvert
TonyG 26/07/18


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.