如何在不安装 Microsoft Office 的情况下使用 C# 创建 Excel (.XLS 和 .XLSX) 文件?

2156

我如何在不需要安装Excel的计算机上使用C#创建Excel电子表格?


68
“不需要安装Excel”并不意味着不专业。这是关于依赖性的问题。原始问题的文本为:“理想情况下,我希望使用开源代码,这样我就不必添加任何第三方依赖项,并且我想避免直接使用Excel创建文件(使用OLE自动化)。”不幸的是,问题被大幅简化了。 - Tony
10
假设您想要做一些不使用库或外部代码的事情,我无法对 xls 文件进行说明,但对于 xlsx 文件,为什么不从一个现有的文件开始,将其重命名为 zip 文件并探索其内容呢?进行一点反向工程将会告诉您很多信息。各个文件夹和子文件夹中有几个不同的 xml 文件和 rels 文件。尝试探索一下,看看是否可以复制它,或者找到关于各种 xml 命名空间/模式的文档。 - Alexander Ryan Baggett
48个回答

1186
你可以使用一个叫做ExcelLibrary的库。这是一个免费、开源的库,发布在Google Code上: ExcelLibrary 它看起来是PHP ExcelWriter的一个移植版本。它目前还不能写入新的.xlsx格式文件,但他们正在努力添加该功能。
它非常简单、小巧、易于使用。此外,它还有一个DataSetHelper,让您可以使用DataSets和DataTables轻松地处理Excel数据。
ExcelLibrary似乎仍然只适用于旧版Excel格式(.xls文件),但未来可能会增加对新版2007/2010格式的支持。
您还可以使用EPPlus,它仅适用于Excel 2007/2010格式文件(.xlsx文件)。还有NPOI,它可以与两者一起使用。
每个库都有一些已知的缺陷,如评论中所述。总体而言,随着时间的推移,EPPlus似乎是最好的选择。它似乎也更活跃地更新和记录。
另外,正如@АртёмЦарионов所指出的那样,EPPlus支持数据透视表,而ExcelLibrary可能具有一些支持(ExcelLibrary中的数据透视表问题)。
以下是一些快速参考链接:
ExcelLibrary - GNU Lesser GPL
EPPlus - GNU (LGPL) - 不再维护
EPPlus 5 - Polyform Noncommercial - 从2020年5月开始
NPOI - Apache License

以下是ExcelLibrary的示例代码:

下面是一个从数据库中获取数据并创建工作簿的示例。请注意,ExcelLibrary代码是底部的单行代码:

//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);

创建Excel文件就是这么简单。您也可以手动创建Excel文件,但上面的功能确实给我留下了深刻印象。

268
ExcelLibrary已被出色的EPPlus所取代 - http://epplus.codeplex.com。Jan定期更新它。我们一直在使用它,这是我们使用过的最好的开源项目之一。 - Mark A
4
需要注意的是,ExcelLibrary在处理大型数据集(超过5000行且列数众多)时存在许多性能问题。目前我正在工作中对代码进行大量修改,以便在项目中使用它。 - rossisdead
11
闭源Excel操作库ClosedXML怎么样?它可能在你的项目中非常有用。 - Amadeus Sanchez
2
EPPlus在版本5之前是LGPL许可证。如果您在代码中使用版本5或更高版本,并且没有许可证密钥,将会抛出异常。 - Britt Kelly
显示剩余5条评论

647

如果您喜欢xlsx格式,可以尝试我的库EPPlus。它始于ExcelPackage的源代码,但后来进行了全面重写。

它支持范围、单元格样式、图表、形状、图片、命名范围、自动筛选和很多其他内容。

您有两个选择:

  • EPPlus 4,采用LGPL许可证(原分支,开发至2020年)

  • EPPlus 5,采用Polyform Noncommercial 1.0.0许可证(自2020年起)。

根据EPPlus 5的readme.md文件:

在新许可下,EPPlus在某些情况下仍然可以免费使用,但在商业企业中使用需要购买商业许可证。

EPPlus网站:https://www.epplussoftware.com/


18
这些例子非常有帮助。我能够在几个小时内从使用微软interop库(极其缓慢)改变为使用此库(版本4.x)。我的基准测试会写一个包含两个标签和约750,000个单元格的文件。使用MS interop需要13分钟,而使用EPPlus只需要10秒,速度提高了大约80倍。非常开心! - Paul Chernoch
@JanKällman 您应该更新您的 CodePlex 页面,以显示您已经有这些方法可用:LoadFromCollection<T>LoadFromDataTable等(通过此处发现)。 - PeterX
3
为了清晰表达,在这个线程中,LGPL允许软件被链接到而不发生GPL的感染部分。你只需要开源你对ClosedXml所做的更改,或者如果你直接将源代码(而不是引用ClosedXml程序集)放入你的应用程序中,则需要开源你的应用程序。 - Chris Marisic
9
我们可以使用interop快速地填充大型Excel表格。秘诀是进行批量更新。创建一个对象 [,] 块,填充它,然后一次性将该矩阵写入Excel: excelWorksheet.get_Range(range).Value2 = block; - Marc Meketon
1
我认为建议使用付费产品并不是解决这个问题的办法。 - Niels Abildgaard

220

5
需要注意的是,这个DLL文件大小略大于5MB,且仅支持Office 2007格式。但对我来说,这绝对是最简单、最快速的解决方案。 - Josh Brown
20
提醒一下,v2.5已经发布了,可以从这里下载。 - Snuffleupagus
15
SDK将XML映射成类,每个XML标签都被映射到一个标签上,然后你必须正确构建类层次结构(每个实例都有一组子实例/标签)。这意味着你必须了解Excel文件的XML结构,它非常复杂。使用EPPlus等包装器更容易,可以简化操作。 - Tsahi Asher
2
一个很好的Microsoft Open XML SDK示例 - Open XML Writer可以在http://polymathprogrammer.com/2012/08/06/how-to-properly-use-openxmlwriter-to-write-large-excel-files/找到。或者查看Stack Overflow解决方案https://dev59.com/c2XWa4cB1Zd3GeqPQtSD#42304339 - Greg
5
我发现微软的Open XML SDK中的Open XML Writer非常好用。使用以上的解决方案(特别是Vincent Tom的示例(Poly Math)),可以轻松构建一个类似于CSV文件的记录流式写入器,但实际上你在编写的是XML格式的数据。 Open XML是微软认为其新Office格式的思维方式。如果您想要查看其XML内容,您可以随时将文件扩展名从.xlsx改为.zip并进行探索。 - Greg
显示剩余3条评论

179

7
关于NPOI的注释-行和列引用从零开始。对于填充现有模板非常有效。 - John M

120

您可以使用OLEDB来创建和操作Excel文件。请查看此链接:Reading and Writing Excel using OLEDB.

典型示例:

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

编辑 - 更多链接:


5
有人能确认一下在x64环境下运行是否可行吗?我相当确定只有在应用程序以32位模式编译或运行时,Jet才能正常工作。 - Lamar
3
我刚测试了这个连接,它在 Windows Server 2008 R2 x64 RC 上失败了,看起来需要安装 2007 Office System Driver: Data Connectivity Components [http://www.microsoft.com/downloads/details.aspx?FamilyID=7554F536-8C28-4598-9B72-EF94E038C891&displaylang=en]。 - Chris Richner
28
非常小心处理这个 -- 这是一个丑陋的巨大补救措施(例如,有时它猜测列类型并且丢弃所有不符合条件的数据)。 - dbkk
9
如果使用这种方法,应该非常小心。我发现对于不是以完美格式存在的数据来说,这种方法很容易出错。 - Kenny Mann
11
作为在一个大项目中不得不使用OleDb的人,我建议你远离它!有时候它无法检索单元格的值,仅仅是因为它无法理解格式。它没有删除操作。即使稍微改变一下提供程序,它的工作方式也完全不同且难以预测。我建议选择一个经过验证的商业解决方案。 - platypus
显示剩余4条评论

84

商业解决方案SpreadsheetGear for .NET可以实现。

您可以在这里查看ASP.NET(C#和VB)的实时示例,并在此处下载评估版本。

免责声明:我拥有SpreadsheetGear LLC。


15
你们的产品很棒,但我认为很多人在这里都期望能获得免费解决方案。这可能是下投票的原因。 - md1337
我认为推荐付费解决方案并不能真正解释如何解决这个问题。 - Niels Abildgaard

72
一个非常轻量级的选项可能是使用HTML表格。只需在文件中创建head、body和table标签,将其保存为带有.xls扩展名的文件。有一些微软特定的属性可以用来样式化输出,包括公式。
我知道你可能不会在Web应用程序中编写代码,但这里是通过HTML表格组成Excel文件的示例。如果你正在编写控制台应用程序、桌面应用程序或服务,这种技术也可以使用。

9
虽然只用于展示可以导出Excel文件的功能,但它是如此临时而有效(更不用说打开时Excel会发出警告),并且如此简单,值得作为一种解决方案存在。 - Luka Ramishvili
3
这个解决方案对我很有效,只需注意不能使用 .xlsx 扩展名。 - Jill
我的组织中有些人无法在Office 2010及以上版本中打开以这种方式制作的Excel文件。不知道问题出在哪里,但我不得不自己编写OpenXML实现(请参见Sogger的答案)。 - Kristen Hammack
一个更加轻量级的版本是创建一个 csv 文件,Windows 会将其与 Excel 相关联。 - John Coleman
如果您这样做,要注意出现向用户发出的安全警告:“警告,文件内容与扩展名不匹配”。当您从银行下载时尤其令人担忧。我不建议采用本答案中提到的方法。 - Caius Jard

69

我使用过几个选项:

如果必须使用XLSX: ExcelPackage 是一个不错的起点,但当开发者停止工作时就死了。 ExML 接着从那里开始并添加了一些功能。ExML 不是一个坏选择,我仍在几个生产网站上使用它。

然而,对于我所有的新项目,我都使用 NPOI ,这是 Apache POI 的 .NET 移植版。 NPOI 2.0 (Alpha) 也支持 XLSX 格式。


如果你需要支持XLS,请小心使用ExcelPackage。我曾经遇到过很多问题,最终转而使用ExcelLibrary。 - Jeremy
绝对正确。ExcelPackage/ExML 只有在需要 XLSX 支持时才是一个好选择。 - Nate
5
请注意,ExcelPackage 已经有了它的后续版本:EPPlus(https://epplus.codeplex.com/),支持 XLSX 格式。与 NPOI 相比,我的唯一担忧是在有大量列的情况下性能是否足够好。请注意,不要改变原文的意思。 - Pragmateek

62

如果你正在创建Excel 2007/2010文件,请尝试使用这个开源项目:https://github.com/closedxml/closedxml

它提供了一种面向对象的方式来操作文件(类似于VBA),而不必处理XML文档的烦恼。它可以被任何.NET语言,比如C#和Visual Basic(VB),使用。

ClosedXML允许你在没有Excel应用程序的情况下创建Excel 2007/2010文件。典型的例子是在Web服务器上创建Excel报表:

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

9
我曾试图在一个构建相当大的Excel工作表的项目中使用这个库,它的功能很棒,但性能极差。我刚刚为我正在处理的项目做了一个比较:ClosedXML(版本0.53.3)花费了92,489毫秒,而EPPlus(版本2.9.03,仅用于测试,因为它是GPL许可证)只花费了16,500毫秒。 - Druid
1
@Druid,假设您不修改ClosedXML的源代码,它的许可证是LGPL,因此可以免费使用http://epplus.codeplex.com/license。 - Chris Marisic
我很欣赏ClosedXML是开源的(MIT)。在我写这篇文章的时候,GitHub上LGPL许可的EPPlus项目已经被归档,其最后一个版本发布于2019年1月。 - Jeremy Cook

55

您实际上可能想要查看在C#中可用的Interop类(例如Microsoft.Office.Interop.Excel)。您说不使用OLE(这不是),但是Interop类非常易于使用。请查看此处的C#文档(Excel的Interop从C# PDF的第1072页开始)。

如果您还没有尝试过它们,您可能会感到印象深刻。

请注意Microsoft对此的立场:

Microsoft目前不建议也不支持从任何无人参与、非交互式客户端应用程序或组件(包括ASP、ASP.NET、DCOM和NT服务)自动化Microsoft Office应用程序,因为Office在此环境下运行时可能表现不稳定和/或死锁。


6
但你必须确保手动处理所有内容,否则将会导致内存泄漏。 - MagicKat
11
根据我的经验,我注意到这个互操作性确实使用了 Excel。每次我们使用它时,如果机器上没有安装 Excel,就会出现 COM 异常。请注意,这是原文的翻译,没有其他额外的解释或内容返回。 - MagicKat
12
@Geoffrey:啊,好的,你要让我费点功夫 :) --> http://support.microsoft.com/kb/257757 Microsoft目前不建议也不支持从任何非交互式客户端应用程序自动化Microsoft Office应用程序... - Jennifer Zouak
4
我经过一周的互操作挣扎后来到这个讨论,除非你的需求非常简单,否则这是行不通的。电子表格格式化支持极差,这可能是生成 .xls 文件而不是纯粹的 .csv 文件的原因。例如,你是否尝试过在单元格中输出超过911个字符,或者尝试以一致的方式设置合并单元格的宽度?我尝试过,并且我无法告诉你我现在有多讨厌这个烂东西...做自己一个忙,选择在这个讨论中提到的免费库之一。 - md1337
2
他直接说他不想安装Office。 - JSON
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接