使用 OleDb 或 IronXL 將資料表匯出到 Excel(C#)
在 C# 中將 DataTable 匯出為 Excel 檔案——且無需依賴任何 Office 套件——只要選用合適的函式庫,操作便十分簡單。 你呼叫 WorkBook.Create(),從 dataTable.Columns 寫入標題,循環遍歷 dataTable.Rows 填入儲存格,然後使用 workbook.SaveAs("output.xlsx") 儲存。 最終產出為格式完整的 XLSX 檔案,可在任何平台上運作,包括 .NET 10、Linux 容器及 Azure 無伺服器函式。
本指南將傳統的 奧勒岡資料庫 方法與現代的 IronXL for .NET 方法進行比較。 您將了解為何 奧勒岡資料庫 驅動程式會引發部署與相容性問題,以及如何以乾淨且易於維護的程式碼取代它,該程式碼能處理欄位標題、資料類型、儲存格格式設定及大型資料集,且無需使用 SQL 語法或安裝僅限 Windows 使用的驅動程式。
如何安裝 IronXL 進行 DataTable 匯出?
在編寫任何匯出程式碼之前,請先將 IronXL 加入您的專案中。 在 Visual Studio 中開啟套件管理員控制台並執行:
Install-Package IronXL
dotnet add package IronXL
Install-Package IronXL
dotnet add package IronXL
IronXL 不依賴 Microsoft Office、Access 資料庫引擎或任何 COM 互通層。 安裝套件後,您可以在 Windows、Linux、macOS、Docker、Azure 和 AWS 上執行相同的程式碼,無需修改任何一行。
為何 奧勒岡資料庫 需要安裝驅動程式
傳統的 奧勒岡資料庫 方法將 Excel 檔案視為資料庫。 您使用 Microsoft.ACE.OLEDB.12.0 提供者(或較舊的 Microsoft.Jet.OLEDB.4.0 檔案)建立 奧勒岡資料庫Connection,然後針對電子表格執行 SQL CREATE TABLE 和 @@--CODE-9 命令。 此工具可在已安裝 Microsoft Office 或獨立版 Access Database Engine 再發行套件的開發者電腦上運作。 然而,生產環境——尤其是雲端函式、Docker 容器,以及運行無頭模式 .NET 10 的伺服器群組——通常不具備該驅動程式,且安裝它需要提升的權限,並要求驅動程式與您的程序位元數相符。
為什麼開發人員仍使用 奧勒岡資料庫 進行 Excel 匯出?
奧勒岡資料庫 之所以成為 Excel 自動化的首選,是因為它原本就是 .NET Framework 的一部分。 開發人員已經了解 ADO.NET,因此重複使用 奧勒岡資料庫Connection、奧勒岡資料庫Command 和 奧勒岡資料庫DataAdapter 來寫入 Excel 感覺很自然。 不需要第三方軟體包,而 CREATE TABLE 和 INSERT INTO 的 SQL 式語法,對於熟悉資料庫程式設計的人來說,其意圖顯而易見。
以下是使用 奧勒岡資料庫 匯出 DataTable 的傳統模式:
using System.Data;
using System.Data.奧勒岡資料庫;
// Build a sample DataTable
DataTable dataTable = new DataTable("Products");
dataTable.Columns.Add("ProductID", typeof(int));
dataTable.Columns.Add("ProductName", typeof(string));
dataTable.Columns.Add("Price", typeof(decimal));
dataTable.Rows.Add(1, "Widget", 29.99m);
dataTable.Rows.Add(2, "Gadget", 49.99m);
dataTable.Rows.Add(3, "Gizmo", 19.99m);
// 奧勒岡資料庫 connection string -- file must already exist on disk
string filename = @"C:\Output\Products.xlsx";
string connectionString =
$"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={filename};" +
"Extended Properties='Excel 12.0 Xml;HDR=YES'";
using 奧勒岡資料庫Connection connection = new(connectionString);
connection.Open();
// Create the sheet structure with SQL DDL
string create = "CREATE TABLE [Sheet1$] (ProductID INT, ProductName CHAR(255), Price DOUBLE)";
using (var createCmd = new 奧勒岡資料庫Command(create, connection))
createCmd.Execute無nQuery();
// Insert rows one at a time
string insert = "INSERT INTO [Sheet1$] (ProductID, ProductName, Price) VALUES (?, ?, ?)";
using 奧勒岡資料庫Command insertCmd = new(insert, connection);
insertCmd.Parameters.Add(new 奧勒岡資料庫Parameter("ProductID", 奧勒岡資料庫Type.Integer));
insertCmd.Parameters.Add(new 奧勒岡資料庫Parameter("ProductName", 奧勒岡資料庫Type.VarChar, 255));
insertCmd.Parameters.Add(new 奧勒岡資料庫Parameter("Price", 奧勒岡資料庫Type.Double));
foreach (DataRow row in dataTable.Rows)
{
insertCmd.Parameters[0].Value = row["ProductID"];
insertCmd.Parameters[1].Value = row["ProductName"];
insertCmd.Parameters[2].Value = row["Price"];
insertCmd.Execute無nQuery();
}
using System.Data;
using System.Data.奧勒岡資料庫;
// Build a sample DataTable
DataTable dataTable = new DataTable("Products");
dataTable.Columns.Add("ProductID", typeof(int));
dataTable.Columns.Add("ProductName", typeof(string));
dataTable.Columns.Add("Price", typeof(decimal));
dataTable.Rows.Add(1, "Widget", 29.99m);
dataTable.Rows.Add(2, "Gadget", 49.99m);
dataTable.Rows.Add(3, "Gizmo", 19.99m);
// 奧勒岡資料庫 connection string -- file must already exist on disk
string filename = @"C:\Output\Products.xlsx";
string connectionString =
$"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={filename};" +
"Extended Properties='Excel 12.0 Xml;HDR=YES'";
using 奧勒岡資料庫Connection connection = new(connectionString);
connection.Open();
// Create the sheet structure with SQL DDL
string create = "CREATE TABLE [Sheet1$] (ProductID INT, ProductName CHAR(255), Price DOUBLE)";
using (var createCmd = new 奧勒岡資料庫Command(create, connection))
createCmd.Execute無nQuery();
// Insert rows one at a time
string insert = "INSERT INTO [Sheet1$] (ProductID, ProductName, Price) VALUES (?, ?, ?)";
using 奧勒岡資料庫Command insertCmd = new(insert, connection);
insertCmd.Parameters.Add(new 奧勒岡資料庫Parameter("ProductID", 奧勒岡資料庫Type.Integer));
insertCmd.Parameters.Add(new 奧勒岡資料庫Parameter("ProductName", 奧勒岡資料庫Type.VarChar, 255));
insertCmd.Parameters.Add(new 奧勒岡資料庫Parameter("Price", 奧勒岡資料庫Type.Double));
foreach (DataRow row in dataTable.Rows)
{
insertCmd.Parameters[0].Value = row["ProductID"];
insertCmd.Parameters[1].Value = row["ProductName"];
insertCmd.Parameters[2].Value = row["Price"];
insertCmd.Execute無nQuery();
}
Imports System.Data
Imports System.Data.奧勒岡資料庫
' Build a sample DataTable
Dim dataTable As New DataTable("Products")
dataTable.Columns.Add("ProductID", GetType(Integer))
dataTable.Columns.Add("ProductName", GetType(String))
dataTable.Columns.Add("Price", GetType(Decimal))
dataTable.Rows.Add(1, "Widget", 29.99D)
dataTable.Rows.Add(2, "Gadget", 49.99D)
dataTable.Rows.Add(3, "Gizmo", 19.99D)
' 奧勒岡資料庫 connection string -- file must already exist on disk
Dim filename As String = "C:\Output\Products.xlsx"
Dim connectionString As String = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={filename};" &
"Extended Properties='Excel 12.0 Xml;HDR=YES'"
Using connection As New 奧勒岡資料庫Connection(connectionString)
connection.Open()
' Create the sheet structure with SQL DDL
Dim create As String = "CREATE TABLE [Sheet1$] (ProductID INT, ProductName CHAR(255), Price DOUBLE)"
Using createCmd As New 奧勒岡資料庫Command(create, connection)
createCmd.Execute無nQuery()
End Using
' Insert rows one at a time
Dim insert As String = "INSERT INTO [Sheet1$] (ProductID, ProductName, Price) VALUES (?, ?, ?)"
Using insertCmd As New 奧勒岡資料庫Command(insert, connection)
insertCmd.Parameters.Add(New 奧勒岡資料庫Parameter("ProductID", 奧勒岡資料庫Type.Integer))
insertCmd.Parameters.Add(New 奧勒岡資料庫Parameter("ProductName", 奧勒岡資料庫Type.VarChar, 255))
insertCmd.Parameters.Add(New 奧勒岡資料庫Parameter("Price", 奧勒岡資料庫Type.Double))
For Each row As DataRow In dataTable.Rows
insertCmd.Parameters(0).Value = row("ProductID")
insertCmd.Parameters(1).Value = row("ProductName")
insertCmd.Parameters(2).Value = row("Price")
insertCmd.Execute無nQuery()
Next
End Using
End Using
此程式碼會將每個 DataRow 作為獨立的資料庫往返操作進行插入。對於大型資料集而言,由於 奧勒岡資料庫 並未提供批次插入機制,該迴圈將成為效能瓶頸。 每行資料在移至下一行之前,都會觸發完整的 SQL 解析、參數綁定及寫入週期。
奧勒岡資料庫 匯出 Excel 的主要限制有哪些?
了解 奧勒岡資料庫 為何不足,有助於您向團隊說明遷移的必要性,並選擇合適的替代方案。
驅動程式依賴項與位元數衝突
必須在執行您的應用程式的每台機器上單獨安裝 Microsoft.ACE.OLEDB.12.0 提供者。 若您的程序為 64 位元,但僅有 32 位元的 Access 資料庫引擎可用(當 32 位元的 Microsoft Office 與 64 位元的 .NET 執行環境並存時,這是一種常見的配置),則連線會在執行時拋出例外。微軟已針對這些位元數限制進行文件說明,並建議驅動程式與呼叫程序的位元數應保持一致,但在共享主機或容器化環境中,這通常難以實現。
不支援跨平台
奧勒岡資料庫 是一項僅限 Windows 使用的技術。 .NET 10 原生支援 Linux 和 macOS,且現代架構越來越傾向於在 Linux 節點上的 Docker 容器中執行應用程式工作負載。 因為 System.Data.奧勒岡資料庫 命名空間在非 Windows 作業系統上會引發 Platform無tSupportedException 錯誤,所以任何使用 奧勒岡資料庫 的程式碼路徑都會完全阻止在這些平台上執行。
不支援儲存格格式設定功能
奧勒岡資料庫 將試算表視為一個平面資料庫表。 您可以插入原始數值,但無法設定儲存格字型、背景顏色、邊框、數字格式或欄位寬度。 若您的匯出需求包含需具備標題列樣式、貨幣格式或條件式色彩標示等 Professional 外觀的報表,奧勒岡資料庫 無法滿足此需求。 您需要進行第二輪處理,改用其他函式庫或 Excel Interop COM 物件,但後者會增加其自身的 Office 依賴項。
Excel 檔案必須已存在
奧勒岡資料庫 無法從頭開始建立新的 Excel 工作簿。 在建立連線之前,目標路徑中必須已存在該檔案。 這需要預先準備好的範本檔案,或是透過其他函式庫建立工作簿的額外步驟,這會為部署套件增添不必要的複雜性。
不支援 DELETE 操作
Excel 的 奧勒岡資料庫 驅動程式支援 INSERT 和有限的 UPDATE 操作,但不支援使用 DELETE FROM 刪除行。 任何需要在匯出後刪除資料列的資料處理流程,都必須仰賴手動檔案操作或重新建立整個檔案,而這兩種方式透過 奧勒岡資料庫 介面操作都並非直觀簡易。
如何使用 IronXL 將 DataTable 匯出至 Excel?
IronXL 將整個 奧勒岡資料庫 處理流程替換為直接的物件模型。 無需連接字串、無需 SQL 指令,亦無驅動程式需求。 您建立了 WorkBook,新增了 WorkSheet,並為每個儲存格呼叫了 SetCellValue():
using IronXL;
using System.Data;
// Build the same DataTable
DataTable dataTable = new DataTable("Products");
dataTable.Columns.Add("ProductID", typeof(int));
dataTable.Columns.Add("ProductName", typeof(string));
dataTable.Columns.Add("Price", typeof(decimal));
dataTable.Rows.Add(1, "Widget", 29.99m);
dataTable.Rows.Add(2, "Gadget", 49.99m);
dataTable.Rows.Add(3, "Gizmo", 19.99m);
// Create a new workbook and worksheet -- no template file needed
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("Products");
// Write column headers into the first row
for (int col = 0; col < dataTable.Columns.Count; col++)
{
worksheet.SetCellValue(0, col, dataTable.Columns[col].ColumnName);
}
// Write data rows
for (int row = 0; row < dataTable.Rows.Count; row++)
{
for (int col = 0; col < dataTable.Columns.Count; col++)
{
worksheet.SetCellValue(row + 1, col, dataTable.Rows[row][col].ToString());
}
}
workbook.SaveAs("Products.xlsx");
using IronXL;
using System.Data;
// Build the same DataTable
DataTable dataTable = new DataTable("Products");
dataTable.Columns.Add("ProductID", typeof(int));
dataTable.Columns.Add("ProductName", typeof(string));
dataTable.Columns.Add("Price", typeof(decimal));
dataTable.Rows.Add(1, "Widget", 29.99m);
dataTable.Rows.Add(2, "Gadget", 49.99m);
dataTable.Rows.Add(3, "Gizmo", 19.99m);
// Create a new workbook and worksheet -- no template file needed
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("Products");
// Write column headers into the first row
for (int col = 0; col < dataTable.Columns.Count; col++)
{
worksheet.SetCellValue(0, col, dataTable.Columns[col].ColumnName);
}
// Write data rows
for (int row = 0; row < dataTable.Rows.Count; row++)
{
for (int col = 0; col < dataTable.Columns.Count; col++)
{
worksheet.SetCellValue(row + 1, col, dataTable.Rows[row][col].ToString());
}
}
workbook.SaveAs("Products.xlsx");
Imports IronXL
Imports System.Data
' Build the same DataTable
Dim dataTable As New DataTable("Products")
dataTable.Columns.Add("ProductID", GetType(Integer))
dataTable.Columns.Add("ProductName", GetType(String))
dataTable.Columns.Add("Price", GetType(Decimal))
dataTable.Rows.Add(1, "Widget", 29.99D)
dataTable.Rows.Add(2, "Gadget", 49.99D)
dataTable.Rows.Add(3, "Gizmo", 19.99D)
' Create a new workbook and worksheet -- no template file needed
Dim workbook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim worksheet As WorkSheet = workbook.CreateWorkSheet("Products")
' Write column headers into the first row
For col As Integer = 0 To dataTable.Columns.Count - 1
worksheet.SetCellValue(0, col, dataTable.Columns(col).ColumnName)
Next
' Write data rows
For row As Integer = 0 To dataTable.Rows.Count - 1
For col As Integer = 0 To dataTable.Columns.Count - 1
worksheet.SetCellValue(row + 1, col, dataTable.Rows(row)(col).ToString())
Next
Next
workbook.SaveAs("Products.xlsx")
WorkBook.Create(ExcelFileFormat.XLSX) 在記憶體中建立新的工作簿-無需事先存在任何檔案。 CreateWorkSheet("Products") 新增一個命名製表符。 這些嵌套迴圈完全對應 DataTable 的行數與列數,並將每個值寫入單一儲存格中。 SaveAs() 將工作簿刷新到磁碟,產生一個完全有效的 XLSX 檔案。
輸出
如何使用 奧勒岡資料庫 或 IronXL 將資料表匯出至 Excel(C#):圖 1 - Excel 輸出
若要深入了解可用選項,請參閱"匯出 DataSet 和 DataTable"操作指南,其中涵蓋了其他重載方式與批次匯出模式。
在匯出 DataTable 時,該如何新增儲存格格式?
在完成基本匯出後,最常見的需求之一是對標題列進行樣式設定,以區別於資料列。 IronXL 提供了一套完整的樣式設定 API,這是 奧勒岡資料庫 無法比擬的:
using IronXL;
using IronXL.Styles;
using System.Data;
DataTable dataTable = new DataTable("Products");
dataTable.Columns.Add("ProductID", typeof(int));
dataTable.Columns.Add("ProductName", typeof(string));
dataTable.Columns.Add("Price", typeof(decimal));
dataTable.Rows.Add(1, "Widget", 29.99m);
dataTable.Rows.Add(2, "Gadget", 49.99m);
dataTable.Rows.Add(3, "Gizmo", 19.99m);
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("Products");
// Write and style the header row
for (int col = 0; col < dataTable.Columns.Count; col++)
{
var headerCell = worksheet[$"{(char)('A' + col)}1"];
headerCell.Value = dataTable.Columns[col].ColumnName;
headerCell.Style.Font.Bold = true;
headerCell.Style.BackgroundColor = "#4472C4";
headerCell.Style.Font.FontColor = "#FFFFFF";
}
// Write data rows with price column formatted as currency
for (int row = 0; row < dataTable.Rows.Count; row++)
{
for (int col = 0; col < dataTable.Columns.Count; col++)
{
var cell = worksheet[$"{(char)('A' + col)}{row + 2}"];
cell.Value = dataTable.Rows[row][col].ToString();
// Apply currency format to the Price column
if (dataTable.Columns[col].ColumnName == "Price")
cell.FormatString = "$#,##0.00";
}
}
// Auto-size columns so content is not clipped
worksheet.AutoSizeColumn(0);
worksheet.AutoSizeColumn(1);
worksheet.AutoSizeColumn(2);
workbook.SaveAs("ProductsStyled.xlsx");
using IronXL;
using IronXL.Styles;
using System.Data;
DataTable dataTable = new DataTable("Products");
dataTable.Columns.Add("ProductID", typeof(int));
dataTable.Columns.Add("ProductName", typeof(string));
dataTable.Columns.Add("Price", typeof(decimal));
dataTable.Rows.Add(1, "Widget", 29.99m);
dataTable.Rows.Add(2, "Gadget", 49.99m);
dataTable.Rows.Add(3, "Gizmo", 19.99m);
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("Products");
// Write and style the header row
for (int col = 0; col < dataTable.Columns.Count; col++)
{
var headerCell = worksheet[$"{(char)('A' + col)}1"];
headerCell.Value = dataTable.Columns[col].ColumnName;
headerCell.Style.Font.Bold = true;
headerCell.Style.BackgroundColor = "#4472C4";
headerCell.Style.Font.FontColor = "#FFFFFF";
}
// Write data rows with price column formatted as currency
for (int row = 0; row < dataTable.Rows.Count; row++)
{
for (int col = 0; col < dataTable.Columns.Count; col++)
{
var cell = worksheet[$"{(char)('A' + col)}{row + 2}"];
cell.Value = dataTable.Rows[row][col].ToString();
// Apply currency format to the Price column
if (dataTable.Columns[col].ColumnName == "Price")
cell.FormatString = "$#,##0.00";
}
}
// Auto-size columns so content is not clipped
worksheet.AutoSizeColumn(0);
worksheet.AutoSizeColumn(1);
worksheet.AutoSizeColumn(2);
workbook.SaveAs("ProductsStyled.xlsx");
Imports IronXL
Imports IronXL.Styles
Imports System.Data
Dim dataTable As New DataTable("Products")
dataTable.Columns.Add("ProductID", GetType(Integer))
dataTable.Columns.Add("ProductName", GetType(String))
dataTable.Columns.Add("Price", GetType(Decimal))
dataTable.Rows.Add(1, "Widget", 29.99D)
dataTable.Rows.Add(2, "Gadget", 49.99D)
dataTable.Rows.Add(3, "Gizmo", 19.99D)
Dim workbook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim worksheet As WorkSheet = workbook.CreateWorkSheet("Products")
' Write and style the header row
For col As Integer = 0 To dataTable.Columns.Count - 1
Dim headerCell = worksheet($"{ChrW(AscW("A"c) + col)}1")
headerCell.Value = dataTable.Columns(col).ColumnName
headerCell.Style.Font.Bold = True
headerCell.Style.BackgroundColor = "#4472C4"
headerCell.Style.Font.FontColor = "#FFFFFF"
Next
' Write data rows with price column formatted as currency
For row As Integer = 0 To dataTable.Rows.Count - 1
For col As Integer = 0 To dataTable.Columns.Count - 1
Dim cell = worksheet($"{ChrW(AscW("A"c) + col)}{row + 2}")
cell.Value = dataTable.Rows(row)(col).ToString()
' Apply currency format to the Price column
If dataTable.Columns(col).ColumnName = "Price" Then
cell.FormatString = "$#,##0.00"
End If
Next
Next
' Auto-size columns so content is not clipped
worksheet.AutoSizeColumn(0)
worksheet.AutoSizeColumn(1)
worksheet.AutoSizeColumn(2)
workbook.SaveAs("ProductsStyled.xlsx")
這會產生一個檔案,其中包含藍色標題列、白色標題文字,以及以美元符號顯示且保留兩位小數的價格值。 儲存格字型大小指南以及邊框與對齊方式參考說明,詳述了所有可用的樣式設定選項。
處理大型 DataTable 匯出
對於包含數千行的資料集而言,效能至關重要。 IronXL 在每次磁碟寫入 SaveAs() 之前,會將所有單元格值寫入內存,這比 奧勒岡資料庫 每行一個 Execute無nQuery() 的模式效率要高得多。 若需匯出非常龐大的表格,請參閱《將 DataTable 匯出至 Excel 的最快方法》指南,其中介紹了節省記憶體的串流技術。
您亦可將匯出邏輯與公式、範圍及命名資料表進行分組。 《建立試算表教學》與《在 .NET 中編寫 Excel 指南》提供了完整的範例,說明如何從 DataTables 建立多工作表的工作簿。
如何在 ASP.NET 中將 DataTable 匯出至 Excel?
在網頁應用程式中,您通常會將工作簿直接串流至瀏覽器,而非儲存至磁碟。 IronXL 支援此功能,它使用 workbook.ToByteArray(),傳回可寫入 HTTP 回應的二進位內容:
// In an ASP.NET controller action
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("Report");
// Assume dataTable is populated from your data source
for (int col = 0; col < dataTable.Columns.Count; col++)
worksheet.SetCellValue(0, col, dataTable.Columns[col].ColumnName);
for (int row = 0; row < dataTable.Rows.Count; row++)
for (int col = 0; col < dataTable.Columns.Count; col++)
worksheet.SetCellValue(row + 1, col, dataTable.Rows[row][col].ToString());
byte[] fileBytes = workbook.ToByteArray();
return File(fileBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Report.xlsx");
// In an ASP.NET controller action
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("Report");
// Assume dataTable is populated from your data source
for (int col = 0; col < dataTable.Columns.Count; col++)
worksheet.SetCellValue(0, col, dataTable.Columns[col].ColumnName);
for (int row = 0; row < dataTable.Rows.Count; row++)
for (int col = 0; col < dataTable.Columns.Count; col++)
worksheet.SetCellValue(row + 1, col, dataTable.Rows[row][col].ToString());
byte[] fileBytes = workbook.ToByteArray();
return File(fileBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Report.xlsx");
' In an ASP.NET controller action
Dim workbook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim worksheet As WorkSheet = workbook.CreateWorkSheet("Report")
' Assume dataTable is populated from your data source
For col As Integer = 0 To dataTable.Columns.Count - 1
worksheet.SetCellValue(0, col, dataTable.Columns(col).ColumnName)
Next
For row As Integer = 0 To dataTable.Rows.Count - 1
For col As Integer = 0 To dataTable.Columns.Count - 1
worksheet.SetCellValue(row + 1, col, dataTable.Rows(row)(col).ToString())
Next
Next
Dim fileBytes As Byte() = workbook.ToByteArray()
Return File(fileBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Report.xlsx")
《ASP.NET 將 DataTable 匯出至 Excel 教學》詳細說明了 ASP.NET 應用程式的完整控制器與檢視層串接流程。 《DataTable 轉 Excel C# 指南》涵蓋了更多應用情境,包括多工作表匯出及 DataSet 支援。
奧勒岡資料庫 與 IronXL 快速比較
| 能力 | 奧勒岡資料庫 | IronXL |
|---|---|---|
| 需安裝驅動程式 | 是 (ACE.OLEDB 或 Jet) | 無 |
| 跨平台(.NET 10 / Linux) | 無 | 是 |
| 從頭建立新的工作簿 | 無 | 是 |
| 儲存格格式與樣式 | 無 | 是 |
| 配方支持 | 無 | 是 |
| 批次插入效能 | 一行一行(慢速) | 內存式(快速) |
| 支援 DELETE 語句 | 無 | 是 |
| Docker / 容器支援 | 無 | 是 |
在匯出過程中,您如何處理欄位資料類型?
當 DataTable 欄位包含數值或日期值時,若將其寫入為字串,會導致 Excel 將該儲存格視為文字,進而停用排序、篩選及公式參照功能。 IronXL 在您直接傳遞值而不是呼叫 .ToString(): 時會保留原生類型。
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("TypedData");
DataTable table = new DataTable();
table.Columns.Add("ID", typeof(int));
table.Columns.Add("Amount", typeof(decimal));
table.Columns.Add("Date", typeof(DateTime));
table.Rows.Add(1, 1500.75m, new DateTime(2025, 6, 15));
table.Rows.Add(2, 3200.00m, new DateTime(2025, 7, 4));
// Write headers
for (int col = 0; col < table.Columns.Count; col++)
worksheet.SetCellValue(0, col, table.Columns[col].ColumnName);
// Write typed values -- no .ToString() conversion
for (int row = 0; row < table.Rows.Count; row++)
{
worksheet.SetCellValue(row + 1, 0, (int)table.Rows[row]["ID"]);
worksheet.SetCellValue(row + 1, 1, (double)(decimal)table.Rows[row]["Amount"]);
worksheet[$"C{row + 2}"].Value = (DateTime)table.Rows[row]["Date"];
worksheet[$"C{row + 2}"].FormatString = "yyyy-MM-dd";
}
workbook.SaveAs("TypedData.xlsx");
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("TypedData");
DataTable table = new DataTable();
table.Columns.Add("ID", typeof(int));
table.Columns.Add("Amount", typeof(decimal));
table.Columns.Add("Date", typeof(DateTime));
table.Rows.Add(1, 1500.75m, new DateTime(2025, 6, 15));
table.Rows.Add(2, 3200.00m, new DateTime(2025, 7, 4));
// Write headers
for (int col = 0; col < table.Columns.Count; col++)
worksheet.SetCellValue(0, col, table.Columns[col].ColumnName);
// Write typed values -- no .ToString() conversion
for (int row = 0; row < table.Rows.Count; row++)
{
worksheet.SetCellValue(row + 1, 0, (int)table.Rows[row]["ID"]);
worksheet.SetCellValue(row + 1, 1, (double)(decimal)table.Rows[row]["Amount"]);
worksheet[$"C{row + 2}"].Value = (DateTime)table.Rows[row]["Date"];
worksheet[$"C{row + 2}"].FormatString = "yyyy-MM-dd";
}
workbook.SaveAs("TypedData.xlsx");
Imports System
Imports System.Data
Dim workbook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim worksheet As WorkSheet = workbook.CreateWorkSheet("TypedData")
Dim table As New DataTable()
table.Columns.Add("ID", GetType(Integer))
table.Columns.Add("Amount", GetType(Decimal))
table.Columns.Add("Date", GetType(DateTime))
table.Rows.Add(1, 1500.75D, New DateTime(2025, 6, 15))
table.Rows.Add(2, 3200.00D, New DateTime(2025, 7, 4))
' Write headers
For col As Integer = 0 To table.Columns.Count - 1
worksheet.SetCellValue(0, col, table.Columns(col).ColumnName)
Next
' Write typed values -- no .ToString() conversion
For row As Integer = 0 To table.Rows.Count - 1
worksheet.SetCellValue(row + 1, 0, CInt(table.Rows(row)("ID")))
worksheet.SetCellValue(row + 1, 1, CDbl(CDec(table.Rows(row)("Amount"))))
worksheet($"C{row + 2}").Value = CType(table.Rows(row)("Date"), DateTime)
worksheet($"C{row + 2}").FormatString = "yyyy-MM-dd"
Next
workbook.SaveAs("TypedData.xlsx")
Excel 現在可以對"金額"欄位進行數值排序,並使用日期選擇器篩選"日期"欄位。 如需更多資料格式範例,請參閱"設定儲存格資料格式"指南。 若需在匯出後讀取資料,請參閱"Excel 轉 DataTable"教學,其中涵蓋了此反向操作。
遷移現有的 奧勒岡資料庫 匯出程式碼
從 奧勒岡資料庫 遷移至 IronXL 通常所需時間少於一個衝刺週期。 結構上的變更如下:
- 刪除所有
using System.Data.奧勒岡資料庫引用和對任何 ACE 驅動程式包裝包的 NuGet 引用。 - 將
奧勒岡資料庫Connection初始化區塊替換為WorkBook.Create(ExcelFileFormat.XLSX)。 - 將
CREATE TABLE指令替換為workbook.CreateWorkSheet("SheetName")。 - 將
INSERT INTO循環替換為嵌套的SetCellValue()調用,每個單元格一個調用。 - 將
connection.Close()替換為workbook.SaveAs("output.xlsx")。
如果下游使用者尚未升級到 Excel 2007 或更高版本,您也可以呼叫具有 workbook.SaveAs() 副檔名的 .xls 來產生舊格式檔案。 "轉換試算表檔案類型"指南列出了所有受支援的輸出格式。
如何測試及取得 IronXL 的授權?
IronXL 提供試用授權,可在開發過程中免費使用。 您需在首次呼叫 IronXL 之前,於程式碼中套用此金鑰:
IronXL.License.LicenseKey = "YOUR-LICENSE-KEY-HERE";
IronXL.License.LicenseKey = "YOUR-LICENSE-KEY-HERE";
Imports IronXL
IronXL.License.LicenseKey = "YOUR-LICENSE-KEY-HERE"
授權金鑰設定指南詳述了所有配置選項,包括設定檔與環境變數。 針對雲端部署,Docker 和 Linux 的入門頁面涵蓋了各平台的特定設定步驟。
微軟已針對 奧勒岡資料庫 情境下 Access 資料庫引擎的已知限制進行了文件說明,而 NuGet.org 則提供 IronXL 套件,包含完整的版本歷史記錄與下載統計數據。 官方 Open XML SDK 文件闡述了 IronXL 所實作的底層 XLSX 規格。
下一步計劃是什麼?
現在,您已掌握了一種實用方法,可在無需 奧勒岡資料庫 驅動程式、無需 SQL 語法且不受平台限制的情況下,將 DataTable 匯出為 XLSX 檔案。 核心工作流程 -- WorkBook.Create(), CreateWorkSheet(), SetCellValue() 循環,然後 SaveAs() -- 可以從三行樣本擴展到數十萬行的資料集。
請先將現有的 奧勒岡資料庫 匯出功能替換為上文所示的基礎 IronXL 模式,待資料匯出功能驗證無誤後,再透過樣式 API 進行格式化。 IronXL 的入門指南與功能概覽是進一步了解該程式庫完整支援範圍的絕佳閱讀資源。 若您在同一處理流程中需處理 CSV 檔案,請參閱《C# DataTable 轉 CSV 指南》,該指南說明如何從同一個 DataTable 物件產生逗號分隔的輸出。
常見問題解答
在 C# 中使用 OleDb 將 DataTable 匯出至 Excel 時有哪些限制?
由於 OleDb 屬於舊式技術,在 C# 中使用它將 DataTable 匯出至 Excel 可能會令人感到沮喪。開發人員經常遇到相容性問題、效能較慢以及錯誤處理更為複雜等限制,這使得 IronXL 等現代替代方案更具吸引力。
IronXL 如何改善將 DataTable 匯出至 Excel 的流程?
IronXL 提供了一種將 DataTable 匯出至 Excel 的現代化解決方案,具備更佳的效能、更廣泛的相容性,以及更簡化的程式碼。它消除了常見的 OleDb 操作困擾,讓 .NET 開發人員能更輕鬆地管理 Excel 匯出作業。
為何應考慮將 DataTable 匯出功能從 OleDb 切換至 IronXL?
改用 IronXL for .NET 進行 DataTable 匯出具有多項優勢,包括提升效能、簡化實作流程,以及增強與現代 .NET 應用程式的相容性,從而減少開發所需的時間與精力。
IronXL 能否比 OleDb 更有效地處理大型 DataTable 匯出作業?
是的,IronXL 專為高效處理大型 DataTable 匯出而設計,相較於 OleDb,它能提供更快的處理速度並降低記憶體使用量,因此非常適合處理龐大資料集的應用程式。
IronXL 是否與最新版本的 C# 和 .NET 相容?
IronXL 完全相容於最新版本的 C# 和 .NET,確保能與現代應用程式無縫整合,同時提供持續更新以支援新功能與改進。
像 IronXL 這樣的現代替代方案,相較於傳統的 OleDb 有哪些優勢?
像 IronXL 這樣的現代替代方案具備多項優勢,例如提升效能、更簡易的錯誤處理、與各種 Excel 格式更好的相容性,以及簡化的程式碼,這些都能大幅提升開發者的生產力。
相較於 OleDb,IronXL 是如何處理錯誤管理的?
IronXL 透過清晰的例外處理機制,提供簡化的錯誤管理功能,從而降低與 OleDb 相關的複雜性及潛在問題,使開發人員能更輕鬆地進行應用程式除錯與維護。
在基於 UI 的 .NET 應用程式中,將 DataTable 匯出至 Excel 的常見使用情境有哪些?
在基於使用者介面的 .NET 應用程式中,將 DataTable 匯出至 Excel 常用於生成報表、資料分析及使用者友善的資料處理,此操作通常透過事件處理常式並採用物件發送者模式來觸發。


