跳至頁尾內容
使用 IRONXL

如何使用 Interop 而不是 IronXL 將資料表匯出到 Excel C#

資料匯出至 Excel 文件簡介

對於需要有效率地分析、視覺化和共享資訊的組織而言,將資料從資料庫或應用程式匯出到 Excel 文件是一項基本要求。 Excel 文件因其用戶友好的介面而廣受認可,使用戶能夠輕鬆地與數據進行互動和解釋。 透過將資料集轉換為 .XLSX 格式,開發人員可以確保資料保持可存取性和結構化,而無需考慮使用者的技術背景。 該過程不僅可以保持原始資料集的完整性,還可以實現系統之間的無縫資料傳輸。 為了實現這一點,開發人員可以利用各種 Excel 程式庫,例如 IronXL、EPPlus、NPOI 和 ClosedXML,從而以程式設計方式建立、讀取和操作 Excel 文件,而無需在伺服器或用戶端電腦上安裝 Microsoft Excel。這些庫使用戶能夠產生專業的 Excel 格式報告和資料匯出,從而滿足各種業務和分析需求。

Interop 和 IronXL 的主要差異是什麼?

在深入程式碼之前,了解這兩種方法之間的根本區別有助於為任何專案做出正確的選擇。 比較內容涵蓋技術架構、部署需求以及使用 DataTable 匯出到 Excel 場景時的實際開發經驗。

特徵Microsoft Office InteropIronXL
需安裝辦公室軟體是的-必須安裝 Microsoft Excel。否——獨立庫
伺服器端支援微軟不推薦完全支持
平台支援僅限 Windows 系統Windows、Linux、macOS、Azure
支援 .NET Core/.NET 5+有限的完全支援(.NET 6、7、8、9、10)
資源管理需要清理 COM 對象標準 .NET 處置
安裝方法COM 參考 + Office 安裝透過 NuGet 安裝套件
螺紋模型單線程公寓 (STA)線程安全操作
大型資料集記憶體密集型進程高效的基於文件的方法
文件格式XLSX、XLS、CSVXLSX、XLS、CSV、JSON、XML
授權需要 Office 許可證商業許可可獲取

架構上的差異是根本性的:Excel Interop 透過 COM 自動執行 Microsoft Excel 應用程式本身,而 IronXL 直接讀取和寫入 Excel 檔案格式,無需啟動任何外部進程。 這種區別會影響從記憶體使用到部署複雜性等方方面面。

如何使用 Interop 將資料表匯出到 Excel C#?

傳統方法是使用Microsoft.Office.Interop.Excel命名空間直接自動化 Excel。 此方法要求在執行程式碼的電腦上安裝 Microsoft Excel。

先決條件

使用互通前,請確保:

  1. 開發和部署電腦上都安裝了 Microsoft Excel。
  2. 在 Visual Studio 中新增對"Microsoft Excel 物件庫"的 COM 參考
  3. 內含Microsoft.Office.Interop.Excel命名空間

互通程式碼範例

以下程式碼示範如何使用 Microsoft Office Interop 將DataTable匯出到 Excel 檔案:

using Microsoft.Office.Interop.Excel;
using System.Data;
using System.Runtime.InteropServices;

// Create a sample DataTable with employee data
DataTable dt = new DataTable("Employees");
dt.Columns.Add("EmployeeID", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Department", typeof(string));
dt.Columns.Add("Salary", typeof(decimal));

// Fill the DataTable with sample rows
dt.Rows.Add(1, "John Smith", "Engineering", 75000);
dt.Rows.Add(2, "Sarah Johnson", "Marketing", 65000);
dt.Rows.Add(3, "Michael Chen", "Finance", 70000);
dt.Rows.Add(4, "Emily Davis", "Engineering", 80000);

// Initialize Excel Application object
Application excelApp = new Application
{
    Visible = false,
    DisplayAlerts = false
};

// Create new Workbook and get the active Worksheet
Workbook workbook = excelApp.Workbooks.Add();
Worksheet worksheet = (Worksheet)workbook.ActiveSheet;

try
{
    // Write column headers to the first row
    for (int i = 0; i < dt.Columns.Count; i++)
    {
        worksheet.Cells[1, i + 1] = dt.Columns[i].ColumnName;
    }
    // Write data rows starting from row 2
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        for (int j = 0; j < dt.Columns.Count; j++)
        {
            worksheet.Cells[i + 2, j + 1] = dt.Rows[i][j].ToString();
        }
    }
    // Define file path and save the Excel file
    string filePath = @"C:\Reports\EmployeeReport_Interop.xlsx";
    workbook.SaveAs(filePath);
    Console.WriteLine("Excel file created successfully using Interop.");
}
catch (Exception ex)
{
    Console.WriteLine("Error exporting data to Excel: " + ex.Message);
}
finally
{
    // Close workbook and quit Excel application
    workbook.Close();
    excelApp.Quit();
    // Critical: Release COM objects to prevent memory leaks
    Marshal.ReleaseComObject(worksheet);
    Marshal.ReleaseComObject(workbook);
    Marshal.ReleaseComObject(excelApp);
}
using Microsoft.Office.Interop.Excel;
using System.Data;
using System.Runtime.InteropServices;

// Create a sample DataTable with employee data
DataTable dt = new DataTable("Employees");
dt.Columns.Add("EmployeeID", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Department", typeof(string));
dt.Columns.Add("Salary", typeof(decimal));

// Fill the DataTable with sample rows
dt.Rows.Add(1, "John Smith", "Engineering", 75000);
dt.Rows.Add(2, "Sarah Johnson", "Marketing", 65000);
dt.Rows.Add(3, "Michael Chen", "Finance", 70000);
dt.Rows.Add(4, "Emily Davis", "Engineering", 80000);

// Initialize Excel Application object
Application excelApp = new Application
{
    Visible = false,
    DisplayAlerts = false
};

// Create new Workbook and get the active Worksheet
Workbook workbook = excelApp.Workbooks.Add();
Worksheet worksheet = (Worksheet)workbook.ActiveSheet;

try
{
    // Write column headers to the first row
    for (int i = 0; i < dt.Columns.Count; i++)
    {
        worksheet.Cells[1, i + 1] = dt.Columns[i].ColumnName;
    }
    // Write data rows starting from row 2
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        for (int j = 0; j < dt.Columns.Count; j++)
        {
            worksheet.Cells[i + 2, j + 1] = dt.Rows[i][j].ToString();
        }
    }
    // Define file path and save the Excel file
    string filePath = @"C:\Reports\EmployeeReport_Interop.xlsx";
    workbook.SaveAs(filePath);
    Console.WriteLine("Excel file created successfully using Interop.");
}
catch (Exception ex)
{
    Console.WriteLine("Error exporting data to Excel: " + ex.Message);
}
finally
{
    // Close workbook and quit Excel application
    workbook.Close();
    excelApp.Quit();
    // Critical: Release COM objects to prevent memory leaks
    Marshal.ReleaseComObject(worksheet);
    Marshal.ReleaseComObject(workbook);
    Marshal.ReleaseComObject(excelApp);
}
$vbLabelText   $csharpLabel

這段程式碼示範了使用 Microsoft Interop 將DataTable匯出到 Excel 檔案的完整工作流程。這個流程首先建立一個名為dt的新DataTable其中包含員工資訊——四列分別代表 ID、姓名、部門和薪資,這些都是商業應用程式中常見的資料類型。

Application物件代表 Excel 進程本身。 將Visible = false可防止 Excel 應用程式在處理過程中出現在螢幕上,這對於背景操作至關重要。 DisplayAlerts = false設定會抑制使用者執行匯出時可能會中斷自動化工作流程的對話方塊。

WorkbookWorksheet物件與 Excel 的文件結構直接對應。 工作簿指的是 Excel 檔案本身(.XLSX 或 .XLS 格式),而工作表則是該檔案中的各個工作表標籤。程式碼使用workbook.ActiveSheet來取得每個新工作簿所建立的預設工作表的參考。

如何使用 IronXL 將資料表匯出到 Excel?

IronXL提供了一種無需安裝 Office 即可使用的現代化替代方案。 該庫可以直接讀取和寫入 Excel 文件,因此適用於伺服器環境、雲端部署和跨平台應用程式。

先決條件

透過 NuGet 套件管理器控制台安裝 IronXL:

Install-Package IronXL.Excel
Install-Package IronXL.Excel
SHELL

或使用 .NET CLI:

dotnet add package IronXL.Excel
dotnet add package IronXL.Excel
SHELL

無需安裝其他軟體、Office 或進行系統設定。 該庫在 Windows、Linux 和 macOS 上安裝後即可立即使用。 對於 Azure 部署,IronXL 無需特殊配置即可在應用程式服務、函數和容器執行個體中執行。 該程式庫支援 .NET Framework 4.6.2+ 和所有現代 .NET 版本,包括 .NET 6、7、8、9 和 10。

IronXL 程式碼範例

以下程式碼展示如何使用 IronXL 程式庫將DataTable轉換為 Excel:

using IronXL;
using System.Data;

// Create a sample DataTable
DataTable dt = new DataTable("Employees");
dt.Columns.Add("EmployeeID", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Department", typeof(string));
dt.Columns.Add("Salary", typeof(decimal));

// Fill DataTable with rows of data
dt.Rows.Add(1, "John Smith", "Engineering", 75000);
dt.Rows.Add(2, "Sarah Johnson", "Marketing", 65000);
dt.Rows.Add(3, "Michael Chen", "Finance", 70000);
dt.Rows.Add(4, "Emily Davis", "Engineering", 80000);

// Create a new Excel workbook and worksheet
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workbook.CreateWorkSheet("Employees");

// Write column names to the first row as headers
for (int i = 0; i < dt.Columns.Count; i++)
{
    sheet.SetCellValue(0, i, dt.Columns[i].ColumnName);
}

// Export DataTable rows to Excel cells
for (int i = 0; i < dt.Rows.Count; i++)
{
    for (int j = 0; j < dt.Columns.Count; j++)
    {
        sheet.SetCellValue(i + 1, j, dt.Rows[i][j]);
    }
}

// Save to file path as xlsx format
string filePath = @"C:\Reports\EmployeeReport_IronXL.xlsx";
workbook.SaveAs(filePath);
Console.WriteLine("Excel file created successfully using IronXL.");
using IronXL;
using System.Data;

// Create a sample DataTable
DataTable dt = new DataTable("Employees");
dt.Columns.Add("EmployeeID", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Department", typeof(string));
dt.Columns.Add("Salary", typeof(decimal));

// Fill DataTable with rows of data
dt.Rows.Add(1, "John Smith", "Engineering", 75000);
dt.Rows.Add(2, "Sarah Johnson", "Marketing", 65000);
dt.Rows.Add(3, "Michael Chen", "Finance", 70000);
dt.Rows.Add(4, "Emily Davis", "Engineering", 80000);

// Create a new Excel workbook and worksheet
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workbook.CreateWorkSheet("Employees");

// Write column names to the first row as headers
for (int i = 0; i < dt.Columns.Count; i++)
{
    sheet.SetCellValue(0, i, dt.Columns[i].ColumnName);
}

// Export DataTable rows to Excel cells
for (int i = 0; i < dt.Rows.Count; i++)
{
    for (int j = 0; j < dt.Columns.Count; j++)
    {
        sheet.SetCellValue(i + 1, j, dt.Rows[i][j]);
    }
}

// Save to file path as xlsx format
string filePath = @"C:\Reports\EmployeeReport_IronXL.xlsx";
workbook.SaveAs(filePath);
Console.WriteLine("Excel file created successfully using IronXL.");
$vbLabelText   $csharpLabel

IronXL 的方法遵循類似的邏輯結構,但語法更簡潔,沒有 COM 的複雜性。 這個 Excel 函式庫使開發人員能夠建立、讀取和寫入電子表格文件,而無需依賴任何 Microsoft Office。 WorkBook.Create方法以指定的格式初始化一個新的工作簿ExcelFileFormat.XLSX產生與 Excel 2007 及更高版本相容的現代 Office Open XML 文件,同時該程式庫也支援舊版系統的 XLS 格式。

輸出

如何使用 Interop 或 IronXL 將資料表匯出至 Excel(C#):圖 1 - Excel 輸出

如何使用 Interop 或 IronXL 將資料表匯出至 Excel(C#):圖 2 - 控制台輸出

CreateWorkSheet方法會在工作簿中新增一個具有指定表名的新工作表。 與 Interop 先處理應用程式物件不同,IronXL 直接處理檔案結構。 當使用者開啟 Excel 檔案時,工作表名稱會顯示在 Excel 底部的標籤上。

單元格填入使用SetCellValue ,該函數接受行索引、列索引和要寫入的值。與 Excel Interop 的基於 1 的索引不同,IronXL 使用基於 0 的索引,符合標準的 .NET Framework 約定——第 0 行是第一行,第 0 列是第一列。 與其他 .NET 集合和DataTable列的一致性降低了認知負荷,並消除了在索引系統之間轉換時經常發生的差一錯誤。

該方法能夠自動智慧地處理類型轉換。 整數、字串、十進制數和日期時間值均以適當的 Excel 儲存格格式寫入。 十進位值顯示為可以參與公式的數字,而日期值可以格式化為 dd/mm/yyyy 或其他區域格式。 該庫能夠正確處理空值和缺失數據,而不會拋出異常。

請注意,程式碼中完全沒有清理程式碼。 IronXL 對像是標準的 .NET 託管對象,垃圾回收器會自動處理它們。 不存在孤立進程的風險,無需管理 COM 引用計數,也不會因不當的資源釋放模式而導致記憶體洩漏。 僅此一項簡化就消除了困擾 Excel Interop 解決方案的一整類錯誤。

有關 IronXL 的 Excel 創建功能的更多詳細信息,請參閱建立電子表格文件

如何建立可重複使用的匯出方法?

生產環境中的應用程式通常需要一個可重複使用的方法,將任何DataTable匯出到 Excel 檔案。以下程式碼範例示範了一個輔助類,該類別封裝了匯出邏輯,並可透過事件處理程序(例如按鈕點擊事件)調用,同時object sender參數。

可重複使用的 IronXL 匯出助手

using IronXL;
using System.Data;
using System.IO;
using System;
public class ExcelExporter
{
    /// <summary>
    /// Export a DataTable to Excel file at the specified path
    /// </summary>
    public static bool ExportToExcel(DataTable dt, string filePath)
    {
        if (dt == null || dt.Rows.Count == 0)
            return false;
        try
        {
            // Create new workbook and worksheet
            WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
            WorkSheet sheet = workbook.CreateWorkSheet(dt.TableName ?? "Sheet1");
            // Write column names as headers in the first row
            for (int i = 0; i < dt.Columns.Count; i++)
            {
                var cell = sheet.GetCellAt(0, i);
                cell.Value = dt.Columns[i].ColumnName;
                cell.Style.Font.Bold = true;
            }
            // Fill cells with data values from each row
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    var value = dt.Rows[i][j];
                    // Handle missing or null values
                    if (value == DBNull.Value || value == null)
                        sheet.SetCellValue(i + 1, j, "");
                    else
                        sheet.SetCellValue(i + 1, j, value);
                }
            }
            // Validate file path and save
            FileInfo fileInfo = new FileInfo(filePath);
            if (!fileInfo.Directory.Exists)
                fileInfo.Directory.Create();
            workbook.SaveAs(filePath);
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Export failed: " + ex.Message);
            return false;
        }
    }
    /// <summary>
    /// Query a DataTable and export filtered results
    /// </summary>
    public static DataTable FilterAndExport(DataTable dt, string filterExpression, string filePath)
    {
        if (dt == null)
            return dt;
        // Create filtered view and export
        DataRow[] filteredRows = dt.Select(filterExpression);
        DataTable filteredTable = dt.Clone();
        foreach (DataRow row in filteredRows)
        {
            filteredTable.ImportRow(row);
        }
        ExportToExcel(filteredTable, filePath);
        return filteredTable;
    }
    /// <summary>
    /// Export DataTable to CSV file as an alternative format
    /// </summary>
    public static string ExportToCsv(DataTable dt)
    {
        StringBuilder sb = new StringBuilder();
        // Write column headers
        string[] columnNames = dt.Columns.Cast<DataColumn>().Select(column => column.ColumnName).ToArray();
        sb.AppendLine(string.Join(",", columnNames));
        // Write data rows
        foreach (DataRow row in dt.Rows)
        {
            string[] values = row.ItemArray.Select(field => field?.ToString() ?? "").ToArray();
            sb.AppendLine(string.Join(",", values));
        }
        return sb.ToString();
    }
}
// Usage example in Windows Forms or WPF event handler
public void ExportButton_Click(object sender, EventArgs e)
{
    DataTable dt = GetEmployeeData(); // Your data source
    string filePath = @"C:\Reports\Export.xlsx";
    bool success = ExcelExporter.ExportToExcel(dt, filePath);
    if (success)
        Console.WriteLine("Export completed successfully");
}
using IronXL;
using System.Data;
using System.IO;
using System;
public class ExcelExporter
{
    /// <summary>
    /// Export a DataTable to Excel file at the specified path
    /// </summary>
    public static bool ExportToExcel(DataTable dt, string filePath)
    {
        if (dt == null || dt.Rows.Count == 0)
            return false;
        try
        {
            // Create new workbook and worksheet
            WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
            WorkSheet sheet = workbook.CreateWorkSheet(dt.TableName ?? "Sheet1");
            // Write column names as headers in the first row
            for (int i = 0; i < dt.Columns.Count; i++)
            {
                var cell = sheet.GetCellAt(0, i);
                cell.Value = dt.Columns[i].ColumnName;
                cell.Style.Font.Bold = true;
            }
            // Fill cells with data values from each row
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    var value = dt.Rows[i][j];
                    // Handle missing or null values
                    if (value == DBNull.Value || value == null)
                        sheet.SetCellValue(i + 1, j, "");
                    else
                        sheet.SetCellValue(i + 1, j, value);
                }
            }
            // Validate file path and save
            FileInfo fileInfo = new FileInfo(filePath);
            if (!fileInfo.Directory.Exists)
                fileInfo.Directory.Create();
            workbook.SaveAs(filePath);
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Export failed: " + ex.Message);
            return false;
        }
    }
    /// <summary>
    /// Query a DataTable and export filtered results
    /// </summary>
    public static DataTable FilterAndExport(DataTable dt, string filterExpression, string filePath)
    {
        if (dt == null)
            return dt;
        // Create filtered view and export
        DataRow[] filteredRows = dt.Select(filterExpression);
        DataTable filteredTable = dt.Clone();
        foreach (DataRow row in filteredRows)
        {
            filteredTable.ImportRow(row);
        }
        ExportToExcel(filteredTable, filePath);
        return filteredTable;
    }
    /// <summary>
    /// Export DataTable to CSV file as an alternative format
    /// </summary>
    public static string ExportToCsv(DataTable dt)
    {
        StringBuilder sb = new StringBuilder();
        // Write column headers
        string[] columnNames = dt.Columns.Cast<DataColumn>().Select(column => column.ColumnName).ToArray();
        sb.AppendLine(string.Join(",", columnNames));
        // Write data rows
        foreach (DataRow row in dt.Rows)
        {
            string[] values = row.ItemArray.Select(field => field?.ToString() ?? "").ToArray();
            sb.AppendLine(string.Join(",", values));
        }
        return sb.ToString();
    }
}
// Usage example in Windows Forms or WPF event handler
public void ExportButton_Click(object sender, EventArgs e)
{
    DataTable dt = GetEmployeeData(); // Your data source
    string filePath = @"C:\Reports\Export.xlsx";
    bool success = ExcelExporter.ExportToExcel(dt, filePath);
    if (success)
        Console.WriteLine("Export completed successfully");
}
$vbLabelText   $csharpLabel

這個輔助類別示範了幾個可用於生產環境的模式。 ExportToExcel方法接受任何DataTable和檔案路徑字串,如果匯出失敗或表格為空,則傳回 false。 此方法透過在寫入單元格之前檢查DBNull.Value來優雅地處理缺失值。

FilterAndExport方法展示如何在匯出之前使用篩選表達式查詢DataTable當使用者只需要匯出特定記錄時非常有用。 此方法傳回已過濾的DataTable ,以便呼叫程式碼可以對其進行進一步處理。

ExportToCsv方法使用StringBuilder有效率地建構 CSV 輸出,作為 Excel 格式的替代方案。 雖然 IronXL 本身支援 CSV 匯出,但本範例為了教學目的展示了手動導出方法。

事件處理程序範例展示了這些方法如何與 Windows Forms 或 WPF 應用程式集成,其中object senderEventArgs是標準參數。 一些熟悉 ClosedXML 的開發人員可能會使用new XLWorkbook()識別出類似的模式,但 IronXL 的 API 提供了等效的功能以及額外的格式支援。

這兩種方法如何處理單元格格式?

專業的 Excel 匯出檔案通常需要進行格式設定:粗體標題、彩色儲存格、邊框和數字格式。 這兩個庫都支援樣式,但實作方式截然不同。

使用 Interop 進行格式化

using Microsoft.Office.Interop.Excel;
using System.Data;
using System.Runtime.InteropServices;
DataTable dt = new DataTable("Sales");
dt.Columns.Add("Product", typeof(string));
dt.Columns.Add("Revenue", typeof(decimal));
dt.Rows.Add("Widget A", 15000.50m);
dt.Rows.Add("Widget B", 22500.75m);
Application excelApp = new Application();
Workbook workbook = excelApp.Workbooks.Add();
Worksheet worksheet = (Worksheet)workbook.ActiveSheet;
// Write column headers with formatting to first row
for (int i = 0; i < dt.Columns.Count; i++)
{
    Range headerCell = worksheet.Cells[1, i + 1];
    headerCell.Value = dt.Columns[i].ColumnName;
    headerCell.Font.Bold = true;
    headerCell.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue);
    headerCell.Borders.LineStyle = XlLineStyle.xlContinuous;
}
// Write data values to cells
for (int i = 0; i < dt.Rows.Count; i++)
{
    for (int j = 0; j < dt.Columns.Count; j++)
    {
        worksheet.Cells[i + 2, j + 1] = dt.Rows[i][j];
    }
}
string filePath = @"C:\Reports\FormattedReport_Interop.xlsx";
workbook.SaveAs(filePath);
workbook.Close();
excelApp.Quit();
Marshal.ReleaseComObject(worksheet);
Marshal.ReleaseComObject(workbook);
Marshal.ReleaseComObject(excelApp);
using Microsoft.Office.Interop.Excel;
using System.Data;
using System.Runtime.InteropServices;
DataTable dt = new DataTable("Sales");
dt.Columns.Add("Product", typeof(string));
dt.Columns.Add("Revenue", typeof(decimal));
dt.Rows.Add("Widget A", 15000.50m);
dt.Rows.Add("Widget B", 22500.75m);
Application excelApp = new Application();
Workbook workbook = excelApp.Workbooks.Add();
Worksheet worksheet = (Worksheet)workbook.ActiveSheet;
// Write column headers with formatting to first row
for (int i = 0; i < dt.Columns.Count; i++)
{
    Range headerCell = worksheet.Cells[1, i + 1];
    headerCell.Value = dt.Columns[i].ColumnName;
    headerCell.Font.Bold = true;
    headerCell.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue);
    headerCell.Borders.LineStyle = XlLineStyle.xlContinuous;
}
// Write data values to cells
for (int i = 0; i < dt.Rows.Count; i++)
{
    for (int j = 0; j < dt.Columns.Count; j++)
    {
        worksheet.Cells[i + 2, j + 1] = dt.Rows[i][j];
    }
}
string filePath = @"C:\Reports\FormattedReport_Interop.xlsx";
workbook.SaveAs(filePath);
workbook.Close();
excelApp.Quit();
Marshal.ReleaseComObject(worksheet);
Marshal.ReleaseComObject(workbook);
Marshal.ReleaseComObject(excelApp);
$vbLabelText   $csharpLabel

Interop 格式化程式碼存取各個Range物件並設定Font.BoldInterior.ColorBorders.LineStyle等屬性。 每次屬性存取都是一次 COM 進程間調用,這會增加開銷,並且如果 Excel 無回應,則會增加出現異常的幾率。

使用 IronXL 進行格式化

using IronXL;
using IronXL.Styles;
using System.Data;
DataTable dt = new DataTable("Sales");
dt.Columns.Add("Product", typeof(string));
dt.Columns.Add("Revenue", typeof(decimal));
dt.Rows.Add("Widget A", 15000.50m);
dt.Rows.Add("Widget B", 22500.75m);
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workbook.CreateWorkSheet("Sales");
// Write column headers with formatting to first row
for (int i = 0; i < dt.Columns.Count; i++)
{
    sheet.SetCellValue(0, i, dt.Columns[i].ColumnName);
    var cell = sheet.GetCellAt(0, i);
    cell.Value = dt.Columns[i].ColumnName;
    cell.Style.Font.Bold = true;
    cell.Style.SetBackgroundColor("#ADD8E6");
    cell.Style.BottomBorder.SetColor("#000000");
    cell.Style.BottomBorder.Type = BorderType.Thin;
}
// Write data rows with values from DataTable
for (int i = 0; i < dt.Rows.Count; i++)
{
    for (int j = 0; j < dt.Columns.Count; j++)
    {
        sheet.SetCellValue(i + 1, j, dt.Rows[i][j]);
    }
}
string filePath = @"C:\Reports\FormattedReport_IronXL.xlsx";
workbook.SaveAs(filePath);
using IronXL;
using IronXL.Styles;
using System.Data;
DataTable dt = new DataTable("Sales");
dt.Columns.Add("Product", typeof(string));
dt.Columns.Add("Revenue", typeof(decimal));
dt.Rows.Add("Widget A", 15000.50m);
dt.Rows.Add("Widget B", 22500.75m);
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workbook.CreateWorkSheet("Sales");
// Write column headers with formatting to first row
for (int i = 0; i < dt.Columns.Count; i++)
{
    sheet.SetCellValue(0, i, dt.Columns[i].ColumnName);
    var cell = sheet.GetCellAt(0, i);
    cell.Value = dt.Columns[i].ColumnName;
    cell.Style.Font.Bold = true;
    cell.Style.SetBackgroundColor("#ADD8E6");
    cell.Style.BottomBorder.SetColor("#000000");
    cell.Style.BottomBorder.Type = BorderType.Thin;
}
// Write data rows with values from DataTable
for (int i = 0; i < dt.Rows.Count; i++)
{
    for (int j = 0; j < dt.Columns.Count; j++)
    {
        sheet.SetCellValue(i + 1, j, dt.Rows[i][j]);
    }
}
string filePath = @"C:\Reports\FormattedReport_IronXL.xlsx";
workbook.SaveAs(filePath);
$vbLabelText   $csharpLabel

IronXL 的樣式 API 使用流暢、直覺的語法,.NET 開發人員會發現這種語法非常熟悉。 Style屬性透過簡潔的物件模型提供對字體設定、背景顏色和邊框的存取。 顏色值接受標準十六進位代碼,例如#ADD8E6 (淺藍色),無需在顏色系統之間轉換即可輕鬆匹配企業品牌或設計規範。

輸出

如何使用 Interop 或 IronXL 將資料表匯出至 Excel C#:圖 3 - 使用 IronXL 輸出格式

單元格存取器語法sheet[row, col]可以直接存取單一單元格,而無需建立其他物件或範圍參考。 這種方法可以減少程式碼冗餘,並省去基於 COM 的 API 所需的繁瑣步驟。在同一儲存格上設定多個樣式屬性非常簡單-每個屬性賦值都會直接修改儲存格的外觀。

邊框配置體現了 IronXL 的實用設計。 開發者無需處理需要查閱文件的枚舉值,而是使用BorderType.Thin表示標準邊框,或使用BorderType.Thick表示強調的邊界。 SetColor方法接受十六進位顏色代碼作為邊框顏色,以保持與背景顏色規範的一致性。

若要了解包含數位格式、條件格式和進階樣式技巧的全面格式設定選項,請參考儲存格樣式文件邊框對齊指南

出口最佳實踐

為確保資料順利可靠地匯出到 Excel,在整個開發過程中遵循最佳實踐至關重要。 始終對匯出的 Excel 檔案使用一致的檔案路徑和命名規則,使檔案管理變得簡單明了且可預測。 透過捕獲異常(例如使用catch (Exception ex)來實現強大的錯誤處理,如果在導出過程中發生錯誤,則傳回 false 或提供有意義的回饋。 對於大型資料集,可以考慮使用 OpenXML SDK,它提供了一種高效能、記憶體效率高的方式將資料寫入 Excel 文件,而無需自動化 Microsoft Excel 的額外開銷。 像 ClosedXML 這樣的函式庫進一步簡化了導出流程,提供了直覺的 API,有助於確保您的程式碼高效運作且易於維護。 透過遵循這些最佳實踐,開發人員可以建立既可靠又可擴展的匯出例程,無論資料集的大小或複雜性如何,都能將準確的資料匯出到 Excel 檔案。

何時該選擇哪一種方法?

當您需要將 DataTable 資料匯出到 Excel 檔案時,正確的選擇取決於專案的特定要求、部署環境以及長期維護方面的考慮。

在下列情況下選擇 Microsoft Office Excel Interop:

  • 處理已安裝 Office 並依賴 Interop 的舊系統
  • 需要使用進階 Excel 功能,例如巨集、資料透視表或圖表自動化,這些功能需要完整的 Excel 應用程式物件模型。
  • 建立桌面應用程序,使用者需要安裝 Microsoft Excel,並且該應用程式可以互動式運行。 部署環境完全受控,僅限 Windows 系統,Office 授權已準備就緒。
  • 自動化包含複雜嵌入式公式或 VBA 程式碼的現有 Excel 模板

選擇 IronXL 的情況:

  • 建立用於產生 Excel 檔案匯出的 Web 應用程式、REST API 或後台服務
  • 部署到雲端環境,例如 Azure 應用程式服務、AWS Lambda 或 Docker 容器
  • 需要對 Windows、Linux 或 macOS 部署提供跨平台支持
  • 適用於 .NET Framework 4.6.2+ 或更高版本,但互通支援有限。 需要可靠、可預測的資源管理,且無需擔心 COM 清理問題。
  • 避免生產伺服器上的 Office 授權依賴 建立多租戶應用程序,其中獨立生成 Excel 文件至關重要
  • 高效處理大型資料集,無需 COM 進程間通訊的開銷 需要匯出為多種格式,包括 XLSX、XLS、CSV 檔案、JSON 和 XML。

IronXL 教學提供了更多範例,涵蓋常見場景,包括讀取現有 Excel 檔案、使用公式管理多個工作表。 當需要將多個相關表匯出到不同的工作表時,該程式庫也支援使用 DataSet 物件。

結論

將 DataTable 匯出到 Excel 檔案是處理業務資料的 .NET 應用程式的基本要求。 無論您是需要從資料庫查詢匯出資料、從資料集建立報告,還是將資料表列轉換為格式化的 Excel 表格,選擇合適的庫都至關重要。

雖然 Microsoft Office Excel Interop 多年來一直為開發人員提供服務,但它對 Office 安裝的依賴性、COM 的複雜性、不受支援的伺服器場景以及資源管理方面的挑戰,使其對於現代應用程式開發而言越來越不切實際。 諸如catch (Exception ex)區塊中填充 COM 清理程式碼以及缺失引用的變通方法等問題是常見的痛點。

IronXL 提供了更清潔、更可靠的替代方案,直接解決了這些限制。 透過 NuGet 進行簡單的Install-Package ,支援 Windows、Linux 和 macOS 等跨平台,以及遵循 .NET Framework 約定的簡單 API,它消除了困擾 Excel Interop 解決方案的部署難題和資源管理陷阱。 本文中的程式碼範例表明,完成相同的 DataTable 到 Excel 匯出任務需要類似的開發工作量,但 IronXL 可以在不增加營運開銷和維護負擔的情況下提供結果。

準備好簡化 .NET 專案中的 Excel 檔案產生流程了嗎? 立即開始 IronXL 的免費試用,體驗它為您的開發工作流程帶來的改變。 對於生產部署和團隊許可,請探索符合您組織需求的許可選項

常見問題解答

在 C# 中,使用 IronXL 匯出資料表相比 Excel Interop 的主要優勢是什麼?

IronXL 提供了一種更簡單、更有效率的方式,可以使用 C# 將 DataTables 匯出到 Excel,而無需在伺服器上安裝 Excel。

IronXL在匯出到Excel時能否處理大型資料表?

是的,IronXL 針對效能進行了最佳化,可以處理大型資料表,確保快速可靠地匯出到 Excel 檔案。

我是否需要安裝 Microsoft Excel 才能使用 IronXL 匯出資料?

不,IronXL 不需要安裝 Microsoft Excel,因此非常適合伺服器端應用程式。

與 Interop 相比,IronXL 如何簡化匯出資料表的過程?

IronXL 簡化了流程,消除了與 Interop 相關的複雜設定和依賴關係,並提供了用於匯出資料表的簡單 API。

IronXL 是否相容於 .NET Core,能夠將資料表匯出到 Excel?

是的,IronXL 與 .NET Core 完全相容,可讓您在跨平台應用程式中將資料表匯出到 Excel。

IronXL可以將資料表匯出為哪些文件格式?

IronXL 可以將資料表匯出為各種 Excel 檔案格式,包括 XLSX、XLS 和 CSV。

IronXL 是否支援 Excel 表格的樣式和格式設定?

是的,IronXL 支援進階樣式和格式選項,可讓您從資料表建立精美的 Excel 表格。

我可以使用 IronXL 來自動化 C# 中與 Excel 相關的任務嗎?

是的,IronXL 可以用來自動化各種與 Excel 相關的任務,從匯出資料表到複雜的資料分析操作。

對於初次接觸 IronXL 的開發者來說,學習曲線是否陡峭?

IronXL 的設計直觀易學,並提供豐富的文件和範例,幫助開發人員快速入門。

在商業專案中使用 IronXL 有哪些授權選項?

IronXL 提供多種授權選項,以滿足不同的專案需求,包括用於商業用途的永久授權和訂閱授權。

喬迪·巴迪亞
軟體工程師
喬迪精通Python、C#和C++,除了在Iron Software運用這些技能外,他還從事遊戲程式設計。他參與產品測試、產品開發和研究等工作,為產品的持續改進做出了巨大貢獻。豐富的經驗讓他始終保持挑戰性和工作熱情,他表示這是他最喜歡在Iron Software工作的原因之一。喬迪在佛羅裡達州邁阿密長大,畢業於佛羅裡達大學,主修電腦科學和統計學。