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 許可頁面。
傳統的 GridView 匯出方式如何運作?
在傳統的 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
遺留輸出

此方法需要重寫 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 輸出。
。
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 輸出。

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 匯出程式庫取決於三個因素:所需的輸出格式、專案的許可限制以及是否需要專業支援。
當您的應用程式需要多格式輸出(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 工作簿創建,從舊代碼遷移,從而消除用戶遇到的格式警告。
對於生產部署,請購買許可證以解鎖專業支援並確保遵守 IronXL 許可條款。
!{--01001100010010010100001001010010010000010101001001011001010111110100011101000101010101 01000101111101010011010101000100000101010010010101000100010101000100010111110101011101001000110 1010101000100100001011111010100000101001001001111010001000101010101010000110101010100101010101011 10101010001010010010010010010000010100110001011111010000100100110001001111101000011010010111111010000110100101110--
常見問題解答
IronXL for .NET Core 匯出至 Excel 的主要功能為何?
IronXL生成真實的XLSX, CSV, JSON和XML文件,無需Microsoft Office。它提供了一個直觀的API來管理工作簿和工作表、單元格級別樣式、公式評估以及DataTable整合,所有這些都在標準.NET管理代碼中。
IronXL 與用於 ASP.NET Core 專案的 ClosedXML 相比如何?
IronXL支持多種匯出格式(XLSX, CSV, JSON, XML),並提供商業授權的專業支持。ClosedXML在MIT授權下生成有效的XLSX文件,非常適合需要僅限試算表輸出的開源專案。
IronXL 是否適合在 ASP.NET 中從資料庫建立 Excel 報表?
是的。IronXL可以直接與DataTable對象和ADO.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自動化。它可在.NET支持的Windows、Linux和macOS上運行。

