ASP.NET匯出到Excel:IronXL、ClosedXML和EPPlus的對比
將資料匯出到Excel是ASP.NET Core網頁應用程式中的標準需求。 不論您是產生成績報告、允許使用者下載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導出 | 否 | 否 | 否 | 是的 |
| 商業授權 | 不適用 | MIT | Polyform | 商業 |
| .NET Core支援 | 是的 | 是的 | 是的 | 是的 |
如何在ASP.NET Core專案中安裝IronXL?
在編寫任何匯出程式碼之前,透過NuGet套件管理器或.NET CLI將IronXL新增至您的專案。 IronXL不依賴Microsoft Office或COM互運性,因此在.NET支持的任何操作系統上安裝都很簡單。
dotnet add package IronXL.Excel
或者,使用Visual Studio中的套件管理器主控台:
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
傳統輸出
ASP.NET導出到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輸出
ASP.NET導出到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提供了SaveAsXml方法——這些功能在ClosedXML或EPPlus中均不可用。 IronXL程式碼範例和API引用中可以找到更多模式。
IronXL如何處理DataTable和資料庫整合?
許多ASP.NET Core應用程式在匯出之前從SQL Server或其他關聯資料庫獲取資料。 IronXL提供了一級支援來直接將DataTable載入到工作表中,消除了手動迴圈行的需要。
以下範例使用ADO.NET查詢資料庫並從結果DataTable填充Excel工作表:
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輸出
ASP.NET導出到Excel:C#開發人員最佳工具比較:圖3 - ClosedXML匯出到Excel輸出
ClosedXML使用基於整數的儲存格地址(Cell(row, col)),而不是IronXL使用的範圍字串表示法。 兩種方法都生成有效的XLSX檔案。 ClosedXML以MIT授權釋出,適用於開源專案而無商業授權顧慮。 ClosedXML GitHub倉庫提供了問題跟踪和社區貢獻的範例。
EPPlus在其Polyform非商業授權下提供類似功能,用於非商業用途,而生產部署需要商業授權。 在將其用於商業產品之前,請查看EPPlus授權概述。 EPPlus和ClosedXML都生成有效的Excel檔案,但二者均不提供如IronXL的原生CSV、JSON或XML匯出。
下表比較了與生產ASP.NET Core應用程式相關的特定功能:
| 功能 | IronXL | ClosedXML | EPPlus |
|---|---|---|---|
| CSV、JSON和XML匯出 | 原生 | 不可用 | 不可用 |
| DataTable整合 | 是的 | 是的 | 是的 |
| 技術支援 | 授權包含 | 僅社區 | 付費等級 |
| Microsoft Office依賴 | 否ne | 否ne | 否ne |
| 跨平台(Linux上的.NET) | 是的 | 是的 | 是的 |
| 授權型別 | 商業 | MIT | Polyform / 商業 |
如何選擇適合專案的程式庫?
選擇正確的Excel匯出程式庫取決於三個因素:所需的輸出格式、專案的授權限制,以及您是否需要專業支援。
當選擇IronXL時,您的應用程式需要多格式輸出(XLSX、CSV、JSON、XML),或當您正在構建需要保證支援渠道的商業產品時,或當您需要進階Excel功能如公式評估、字型設置或圖表生成時。 IronXL的文件詳細涵蓋每個API表面,支援團隊直接回應授權持有者。 查看IronXL部落格獲取更多範例與教程。
當選擇ClosedXML時,您的專案是開源或非商業用途,只需要XLSX輸出。 MIT授權不對再發佈施加限制,並且API經由社區資源充分文件化。
當選擇EPPlus時,現有程式碼庫已使用EPPlus,並且向其他程式庫移植的成本比購買商業授權更高。
對於評估IronXL及其替代品的團隊,IronXL試用授權允許在承諾購買前進行全功能測試。 在IronXL範例頁面上可獲取更多讀寫Excel文件的程式碼範例。
您的下一步應怎麼做?
既然您已經審閱了ASP.NET Core可用的Excel匯出方法,您現在可以採取以下步驟以向前推進:
- 安裝IronXL使用
dotnet add package IronXL.Excel,並參考入門指南建立您的首個工作簿。 - 比較程式碼模式,通過檢查IronXL範例頁面中與用例匹配的情況(如資料庫匯出、多工作表工作簿或帶樣式報告)來比較。
- 評價授權,通過造訪IronXL授權頁面理解開發、試運行和生產部署的選擇。
- 探索附加格式,若應用程式需要從同一程式碼庫中匯出多種格式的資料,測試
SaveAsCsv,SaveAsJson和SaveAsXml方法。 - 從舊程式碼遷移,辨識解決方案中任何現有的
Response.ContentType = "application/vnd.ms-excel"模式,並將其更換為IronXL工作簿建立,以消除對使用者的格式警告。
對於生產部署,購買授權以解鎖專業支援並確保遵守IronXL授權條款。
常見問題
IronXL在ASP.NET Core中導出到Excel的主要功能是什麼?
IronXL生成真實的XLSX、CSV、JSON和XML檔案,不需要Microsoft Office。它提供直觀的API來管理工作簿和工作表、單元格級樣式設計、公式評估和DataTable整合,所有這些都是在標準.NET管理程式碼中完成的。
IronXL與ClosedXML在ASP.NET Core專案中的比較如何?
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上運行。



