ASP.NET导出到Excel: IronXL 、ClosedXML和EPPlus的对比
将数据导出到 Excel 是ASP.NET Core Web 应用程序的标准要求。 无论您是生成销售报告、允许用户下载 GridView 内容,还是从数据库查询生成 CSV 文件,您选择的方法都决定了生成的文件能否在 Microsoft Excel 中正常打开,还是会触发格式警告。 本文比较了 C# 开发人员可用的最常用 Excel 导出方法——传统的基于 HTML 的流式传输和现代库解决方案(包括IronXL、ClosedXML 和 EPPlus)——以便您可以为您的项目选择合适的工具。
立即开始免费试用,了解IronXL如何在ASP.NET Core应用程序中处理 Excel 文件生成。
在 ASP.NET Core 中将数据导出到 Excel 的常用方法有哪些?
ASP.NET Core开发人员在添加 Excel 导出功能时有多种方法可供选择。 每种方法在输出文件的质量、实施所需的工作量以及对商业项目的许可影响方面都有所不同。
传统MIME类型流媒体是最古老的技术。 服务器将响应 Content-Type 标头设置为 application/vnd.ms-excel,并将 HTML 表格写入输出流。 浏览器将其解释为 Excel 下载,但该文件包含 HTML 标记,而不是真正的电子表格数据。 Microsoft Excel 会检测到格式不匹配,并在打开文件前显示格式警告。此方法不支持公式、文本列或正确的单元格格式。
基于库的解决方案会添加一个NuGet包,该包使用 Microsoft 定义的Open XML 格式构建真正的 XLSX 文件。 可选方案包括IronXL、ClosedXML 和 EPPlus。 这三款软件都能生成有效的 Excel 文件,打开时不会出现警告,支持单元格级格式设置,并且与.NET Core兼容。 官方的.NET文件下载文档涵盖了所有这些方法所使用的底层ASP.NET Core机制。
下表总结了主要区别:
| 特征 | MIME 类型 / HTML | ClosedXML | EPPlus | IronXL |
|---|---|---|---|---|
| 真正的 XLSX 输出 | 无 | 是 | 是 | 是 |
| 支持 CSV 文件 | 手册 | 数量有限 | 数量有限 | 本地 |
| 打开时未发出 Excel 警告 | 无 | 是 | 是 | 是 |
| 配方支持 | 无 | 是 | 是 | 是 |
| JSON 和 XML 导出 | 无 | 无 | 无 | 是 |
| 商业许可 | 不适用 | 麻省理工学院 | 聚合物 | 商业的 |
| .NET Core 支持 | 是 | 是 | 是 | 是 |
如何在ASP.NET Core项目中安装IronXL ?
在编写任何导出代码之前,请通过NuGet包管理器或.NET CLI 将IronXL添加到您的项目中。 IronXL不依赖于 Microsoft Office 或 COM 互操作,因此在任何.NET支持的操作系统上安装都很简单。
dotnet add package IronXL.Excel
dotnet add package IronXL.Excel
或者,您也可以使用 Visual Studio 中的程序包管理器控制台:
Install-Package IronXL.Excel
Install-Package IronXL.Excel
安装完该软件包后,将 using IronXL; 添加到任何需要生成 Excel 文件的控制器或服务类中。 基本导出场景无需额外配置。 有关许可和部署选项,请访问IronXL许可页面。
传统的网格视图导出方法是如何工作的?
在传统的 WebForms 和一些较旧的 MVC 模式中,开发人员通过将 GridView 数据渲染为 HTML 并将其流式传输到浏览器来导出数据,同时使用误导性的 Content-Type 标头。 该应用程序调用 Response.AddHeader 来设置文件名,并直接写入 HTML 输出。
// Traditional approach -- exports HTML disguised as Excel
public void ExportToExcel(object sender, EventArgs e)
{
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("content-disposition", "attachment;filename=Report.xls");
StringWriter stringWriter = new StringWriter();
HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);
// Render grid content as HTML
DataGrid1.RenderControl(htmlTextWriter);
Response.Write(stringWriter.ToString());
Response.End();
}
public override void VerifyRenderingInServerForm(Control control)
{
// Required to prevent server form rendering errors
}
// Traditional approach -- exports HTML disguised as Excel
public void ExportToExcel(object sender, EventArgs e)
{
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("content-disposition", "attachment;filename=Report.xls");
StringWriter stringWriter = new StringWriter();
HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);
// Render grid content as HTML
DataGrid1.RenderControl(htmlTextWriter);
Response.Write(stringWriter.ToString());
Response.End();
}
public override void VerifyRenderingInServerForm(Control control)
{
// Required to prevent server form rendering errors
}
' Traditional approach -- exports HTML disguised as Excel
Public Sub ExportToExcel(sender As Object, e As EventArgs)
Response.Clear()
Response.Buffer = True
Response.ContentType = "application/vnd.ms-excel"
Response.AddHeader("content-disposition", "attachment;filename=Report.xls")
Dim stringWriter As New StringWriter()
Dim htmlTextWriter As New HtmlTextWriter(stringWriter)
' Render grid content as HTML
DataGrid1.RenderControl(htmlTextWriter)
Response.Write(stringWriter.ToString())
Response.End()
End Sub
Public Overrides Sub VerifyRenderingInServerForm(control As Control)
' Required to prevent server form rendering errors
End Sub
传统输出
!a href="/static-assets/excel/blog/asp-net-export-to-excel/asp-net-export-to-excel-1.webp">ASP.NET Export to Excel:C# 开发人员的最佳工具比较:图片 1 - 传统 Excel 导出输出。
此方法需要重写 VerifyRenderingInServerForm 以绕过服务器端验证。 生成的文件包含 HTML 而不是真正的电子表格数据,因此当用户打开该文件时,Microsoft Excel 会显示格式警告。 输出结果不支持工作表公式、键入的数据列或单元格级别的格式设置。 对于任何新的ASP.NET Core开发,都应该避免使用这种模式,而应使用合适的 Excel 库。
IronXL 如何简化 ASP.NET Core 中的 Excel 文件生成?
IronXL提供了一个 API,用于创建真正的 XLSX 文件,无需 Microsoft Office 或 COM 互操作。该库完全使用托管代码构建工作簿对象,因此无需额外依赖项即可在 Linux、macOS 和 Windows 上运行。
以下示例创建一个工作簿,将销售数据填充到工作表中,将标题行设置为粗体格式,并将文件流式传输到浏览器:
using IronXL;
using Microsoft.AspNetCore.Mvc;
public class ExportController : Controller
{
[HttpPost]
public IActionResult ExportReport()
{
// Create workbook and worksheet
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("Sales Data");
// Add header row
worksheet["A1"].Value = "Product";
worksheet["B1"].Value = "Quantity";
worksheet["C1"].Value = "Revenue";
// Populate data rows
worksheet["A2"].Value = "Widget A";
worksheet["B2"].Value = 150;
worksheet["C2"].Value = 4500.00;
worksheet["A3"].Value = "Widget B";
worksheet["B3"].Value = 230;
worksheet["C3"].Value = 6900.00;
// Apply bold formatting to headers
var headerRange = worksheet["A1:C1"];
headerRange.Style.Font.Bold = true;
// Stream file to browser
byte[] fileBytes = workbook.ToByteArray();
string filename = $"SalesReport_{DateTime.无w:yyyyMMdd}.xlsx";
return File(fileBytes,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
filename);
}
}
using IronXL;
using Microsoft.AspNetCore.Mvc;
public class ExportController : Controller
{
[HttpPost]
public IActionResult ExportReport()
{
// Create workbook and worksheet
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("Sales Data");
// Add header row
worksheet["A1"].Value = "Product";
worksheet["B1"].Value = "Quantity";
worksheet["C1"].Value = "Revenue";
// Populate data rows
worksheet["A2"].Value = "Widget A";
worksheet["B2"].Value = 150;
worksheet["C2"].Value = 4500.00;
worksheet["A3"].Value = "Widget B";
worksheet["B3"].Value = 230;
worksheet["C3"].Value = 6900.00;
// Apply bold formatting to headers
var headerRange = worksheet["A1:C1"];
headerRange.Style.Font.Bold = true;
// Stream file to browser
byte[] fileBytes = workbook.ToByteArray();
string filename = $"SalesReport_{DateTime.无w:yyyyMMdd}.xlsx";
return File(fileBytes,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
filename);
}
}
Imports IronXL
Imports Microsoft.AspNetCore.Mvc
Public Class ExportController
Inherits Controller
<HttpPost>
Public Function ExportReport() As IActionResult
' Create workbook and worksheet
Dim workbook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim worksheet As WorkSheet = workbook.CreateWorkSheet("Sales Data")
' Add header row
worksheet("A1").Value = "Product"
worksheet("B1").Value = "Quantity"
worksheet("C1").Value = "Revenue"
' Populate data rows
worksheet("A2").Value = "Widget A"
worksheet("B2").Value = 150
worksheet("C2").Value = 4500.0
worksheet("A3").Value = "Widget B"
worksheet("B3").Value = 230
worksheet("C3").Value = 6900.0
' Apply bold formatting to headers
Dim headerRange = worksheet("A1:C1")
headerRange.Style.Font.Bold = True
' Stream file to browser
Dim fileBytes As Byte() = workbook.ToByteArray()
Dim filename As String = $"SalesReport_{DateTime.Now:yyyyMMdd}.xlsx"
Return File(fileBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", filename)
End Function
End Class
IronXL 输出
!a href="/static-assets/excel/blog/asp-net-export-to-excel/asp-net-export-to-excel-2.webp">ASP.NET Export to Excel:C# 开发人员的最佳工具比较:图片 2 - IronXL 输出到 Excel
WorkBook.Create 在内存中创建一个新的 Excel 文档。 CreateWorkSheet 添加一个命名选项卡,用户可在 Excel 窗口底部看到该选项卡。 单元格值使用 Excel 风格的范围表示法("A1", "B2")进行赋值,大多数 C# 开发人员认为这种表示法易于阅读和维护。
ToByteArray() 方法将完成的工作簿转换为字节数组,ASP.NET Core File() 响应方法将其直接流式传输到用户的浏览器,并带有正确的 MIME 类型和内容处置标头。 下载的文件在Excel中打开后没有任何格式警告。
IronXL还支持通过SaveAsCsv 方法导出为 CSV 格式:
// Export as CSV instead of XLSX
workbook.SaveAsCsv("output.csv");
// Export as CSV instead of XLSX
workbook.SaveAsCsv("output.csv");
对于需要将工作表数据导出为 JSON 或 XML 的情况,IronXL 提供了 SaveAsJson 和 SaveAsXml 方法 -- ClosedXML 或 EPPlus 中没有这些功能。 您可以在IronXL代码示例和API 参考中找到更多模式。
IronXL如何处理数据表和数据库集成?
许多ASP.NET Core应用程序在导出数据之前会从 SQL Server 或其他关系数据库中获取数据。 IronXL 为将 DataTable 直接加载到工作表中提供了一流的支持,无需手动遍历行。
以下示例使用 ADO.NET 查询数据库,并将结果填充到 Excel 工作表中 DataTable:
using IronXL;
using System.Data;
using System.Data.SqlClient;
using Microsoft.AspNetCore.Mvc;
public class ReportController : Controller
{
private readonly string _connectionString;
public ReportController(IConfiguration config)
{
_connectionString = config.GetConnectionString("DefaultConnection");
}
[HttpGet]
public IActionResult DownloadReport()
{
DataTable table = new DataTable();
using (SqlConnection connection = new SqlConnection(_connectionString))
{
string query = "SELECT OrderId, CustomerName, Total, OrderDate FROM Orders";
using SqlDataAdapter adapter = new SqlDataAdapter(query, connection);
adapter.Fill(table);
}
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("Orders");
// Write column headers from DataTable schema
for (int col = 0; col < table.Columns.Count; col++)
{
worksheet[0, col].Value = table.Columns[col].ColumnName;
}
// Write data rows
for (int row = 0; row < table.Rows.Count; row++)
{
for (int col = 0; col < table.Columns.Count; col++)
{
worksheet[row + 1, col].Value = table.Rows[row][col].ToString();
}
}
byte[] fileBytes = workbook.ToByteArray();
return File(fileBytes,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"Orders.xlsx");
}
}
using IronXL;
using System.Data;
using System.Data.SqlClient;
using Microsoft.AspNetCore.Mvc;
public class ReportController : Controller
{
private readonly string _connectionString;
public ReportController(IConfiguration config)
{
_connectionString = config.GetConnectionString("DefaultConnection");
}
[HttpGet]
public IActionResult DownloadReport()
{
DataTable table = new DataTable();
using (SqlConnection connection = new SqlConnection(_connectionString))
{
string query = "SELECT OrderId, CustomerName, Total, OrderDate FROM Orders";
using SqlDataAdapter adapter = new SqlDataAdapter(query, connection);
adapter.Fill(table);
}
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("Orders");
// Write column headers from DataTable schema
for (int col = 0; col < table.Columns.Count; col++)
{
worksheet[0, col].Value = table.Columns[col].ColumnName;
}
// Write data rows
for (int row = 0; row < table.Rows.Count; row++)
{
for (int col = 0; col < table.Columns.Count; col++)
{
worksheet[row + 1, col].Value = table.Rows[row][col].ToString();
}
}
byte[] fileBytes = workbook.ToByteArray();
return File(fileBytes,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"Orders.xlsx");
}
}
Imports IronXL
Imports System.Data
Imports System.Data.SqlClient
Imports Microsoft.AspNetCore.Mvc
Public Class ReportController
Inherits Controller
Private ReadOnly _connectionString As String
Public Sub New(config As IConfiguration)
_connectionString = config.GetConnectionString("DefaultConnection")
End Sub
<HttpGet>
Public Function DownloadReport() As IActionResult
Dim table As New DataTable()
Using connection As New SqlConnection(_connectionString)
Dim query As String = "SELECT OrderId, CustomerName, Total, OrderDate FROM Orders"
Using adapter As New SqlDataAdapter(query, connection)
adapter.Fill(table)
End Using
End Using
Dim workbook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim worksheet As WorkSheet = workbook.CreateWorkSheet("Orders")
' Write column headers from DataTable schema
For col As Integer = 0 To table.Columns.Count - 1
worksheet(0, col).Value = table.Columns(col).ColumnName
Next
' Write data rows
For row As Integer = 0 To table.Rows.Count - 1
For col As Integer = 0 To table.Columns.Count - 1
worksheet(row + 1, col).Value = table.Rows(row)(col).ToString()
Next
Next
Dim fileBytes As Byte() = workbook.ToByteArray()
Return File(fileBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Orders.xlsx")
End Function
End Class
这种模式使控制器保持简洁且易于测试。 数据库查询和工作簿构建完全分离,因此可以轻松更换数据源或添加用于汇总数据的附加工作表。 有关如何将现有 Excel 文件读入 DataTable 的指导,请参阅 IronXL 读取 Excel 文件的操作指南。
ClosedXML 和 EPPlus 如何比较?
ClosedXML为 Microsoft 的 Open XML SDK 提供了一个易于访问的 API。 从NuGet安装:
Install-Package ClosedXML
Install-Package ClosedXML
以下示例展示了典型的 ClosedXML 导出操作:
using ClosedXML.Excel;
using Microsoft.AspNetCore.Mvc;
public class ExportController : Controller
{
[HttpGet]
public IActionResult ExportWithClosedXML()
{
using var workbook = new XLWorkbook();
var worksheet = workbook.AddWorksheet("Data");
worksheet.Cell(1, 1).Value = "Name";
worksheet.Cell(1, 2).Value = "Amount";
worksheet.Cell(2, 1).Value = "Alpha";
worksheet.Cell(2, 2).Value = 1200;
using var stream = new MemoryStream();
workbook.SaveAs(stream);
return File(stream.ToArray(),
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"export.xlsx");
}
}
using ClosedXML.Excel;
using Microsoft.AspNetCore.Mvc;
public class ExportController : Controller
{
[HttpGet]
public IActionResult ExportWithClosedXML()
{
using var workbook = new XLWorkbook();
var worksheet = workbook.AddWorksheet("Data");
worksheet.Cell(1, 1).Value = "Name";
worksheet.Cell(1, 2).Value = "Amount";
worksheet.Cell(2, 1).Value = "Alpha";
worksheet.Cell(2, 2).Value = 1200;
using var stream = new MemoryStream();
workbook.SaveAs(stream);
return File(stream.ToArray(),
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"export.xlsx");
}
}
Imports ClosedXML.Excel
Imports Microsoft.AspNetCore.Mvc
Imports System.IO
Public Class ExportController
Inherits Controller
<HttpGet>
Public Function ExportWithClosedXML() As IActionResult
Using workbook As New XLWorkbook()
Dim worksheet = workbook.AddWorksheet("Data")
worksheet.Cell(1, 1).Value = "Name"
worksheet.Cell(1, 2).Value = "Amount"
worksheet.Cell(2, 1).Value = "Alpha"
worksheet.Cell(2, 2).Value = 1200
Using stream As New MemoryStream()
workbook.SaveAs(stream)
Return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "export.xlsx")
End Using
End Using
End Function
End Class
ClosedXML 输出
!a href="/static-assets/excel/blog/asp-net-export-to-excel/asp-net-export-to-excel-3.webp">ASP.NET Export to Excel:C# 开发人员的最佳工具比较:图片 3 - ClosedXML 输出到 Excel
ClosedXML 使用基于整数的单元格寻址(Cell(row, col)),而不是 IronXL 使用的范围字符串表示法。 两种方法都能生成有效的 XLSX 文件。 ClosedXML 采用 麻省理工学院 许可证发布,因此适用于无需担心商业许可问题的开源项目。 ClosedXML GitHub存储库提供问题跟踪和社区贡献的示例。
EPPlus在其 聚合物 非商业许可下提供类似的功能,供非商业用途使用,而生产部署则需要商业许可。 在商业产品中使用EPPlus 之前,请查阅其许可概述。 EPPlus 和 ClosedXML 都能生成有效的 Excel 文件,但它们都不像IronXL那样提供原生 CSV、JSON 或 XML 导出功能。
下表比较了与生产环境ASP.NET Core应用程序相关的特定功能:
| 能力 | IronXL | ClosedXML | EPPlus |
|---|---|---|---|
| CSV、JSON 和 XML 导出 | 本地 | 不可用 | 不可用 |
| 数据表集成 | 是 | 是 | 是 |
| 技术支持 | 许可证包含在内 | 仅限社区 | 付费层级 |
| Microsoft Office 依赖项 | 无 | 无 | 无 |
| 跨平台(Linux 上的.NET ) | 是 | 是 | 是 |
| 许可证类型 | 商业的 | 麻省理工学院 | 聚合物 / 商业 |
如何为你的项目选择合适的库?
选择正确的 Excel 导出库取决于三个因素:所需的输出格式、项目的许可限制以及是否需要Professional支持。
IronXL您的应用程序需要多格式输出(XLSX、CSV、JSON、XML)、当您构建需要有保障的支持渠道的商业产品时,或者当您需要高级 Excel 功能(例如公式计算、单元格样式或图表生成)时,请选择 IronXL。 IronXL 的文档详细介绍了每个 API 接口,支持团队直接回复许可证持有者。 请查看IronXL博客,了解更多款式和教程。
如果您的项目是开源或非商业性的,并且只需要 XLSX 输出,请选择 ClosedXML 。 麻省理工学院 许可证对重新分发没有任何限制,并且 API 通过社区资源得到了很好的文档说明。
如果现有代码库已经使用 EPPlus,并且迁移到另一个库的成本高于购买商业许可证的成本,则选择 EPPlus 。
对于正在评估IronXL与其他替代方案的团队来说, IronXL试用许可证允许他们在决定购买之前进行全功能测试。 IronXL示例页面上提供了更多用于读取和写入 Excel 文件的代码示例。
下一步计划是什么?
现在您已经了解了ASP.NET Core可用的 Excel 导出方法,可以按照以下步骤继续操作:
- 使用
dotnet add package IronXL.Excel安装 IronXL ,并按照入门指南创建您的第一个工作簿。 - 通过查看IronXL示例页面,比较代码模式,找到与您的用例相匹配的场景,例如数据库导出、多工作表工作簿或样式报告。
- 访问IronXL许可页面,了解开发、测试和生产部署的选项,从而评估许可。
- 如果您的应用程序需要从同一代码库导出多种格式的数据,请通过测试
SaveAsCsv、SaveAsJson和SaveAsXml方法来探索其他格式。 - 通过识别解决方案中任何现有的
Response.ContentType = "application/vnd.ms-excel"模式并将其替换为 IronXL 工作簿创建,从旧代码迁移,从而消除用户遇到的格式警告。
对于生产部署,请购买许可证以解锁Professional支持并确保遵守IronXL许可条款。
常见问题解答
IronXL 在 ASP.NET Core 中导出到 Excel 的主要功能是什么?
IronXL无需 Microsoft Office 即可生成真正的 XLSX、CSV、JSON 和 XML 文件。它提供了一个直观的 API,用于工作簿和工作表管理、单元格级样式设置、公式计算和数据表集成,所有这些都集成在标准的.NET托管代码中。
IronXL 与用于 ASP.NET Core 项目的 ClosedXML 相比有何优势?
IronXL支持多种导出格式(XLSX、CSV、JSON、XML),并提供商业许可的专业支持。ClosedXML 生成符合 MIT 许可证的有效 XLSX 文件,非常适合只需要电子表格输出的开源项目。
IronXL 是否适合在 ASP.NET 中从数据库创建 Excel 报告?
是的。IronXL 直接处理 DataTable 对象和.NET查询结果,因此可以轻松地从 SQL Server 或其他关系数据库填充工作表,并将生成的文件流式传输到浏览器。
使用IronXL比EPPlus有什么优势?
IronXL原生支持 CSV、JSON 和 XML 导出,每个商业许可证都包含专业技术支持,且不设非商业用途限制。EPPlus 则需要单独的商业许可证才能用于生产环境,并且不提供原生多格式导出功能。
IronXL可以高效处理大型数据集吗?
IronXL专为服务器端工作负载而设计,无需 Microsoft Excel 或 COM 互操作即可处理大型数据集。对于非常大的导出文件,通过ASP.NET Core File() 响应直接流式传输字节数组,避免了将整个文件缓冲到内存中。
IronXL 是否需要安装 Microsoft Office 才能导出到 Excel?
不IronXL完全基于托管的.NET代码运行,不依赖于 Microsoft Office、COM 互操作或 Office 自动化。它可在 Windows、Linux 和 macOS 等所有支持.NET 的平台上运行。

