首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 透過 COM Interop 操作 Excel 匯出與另存完整範例

     編輯:關於C語言

在 WinForms 專案中,若需將資料匯出為格式豐富的 Excel 檔案(含樣式、公式、分頁設定),Microsoft.Office.Interop.Excel 仍是最直觀、功能最完整的選擇。本文提供一個完整的「另存為」實作範例,涵蓋資料寫入、儲存格格式化、邊框樣式、頁面設定與儲存對話框等實務技巧。

核心程式碼架構

private void btnSaveAsData_Click(object sender, EventArgs e)
{
    // 1. 建立 Excel 應用程式與活頁簿
    Excel.Application xlsApp = new Excel.Application();
    Excel._Workbook xlsBook = xlsApp.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
    Excel._Worksheet xlsSheet = (Excel._Worksheet)xlsBook.Worksheets[1];
    xlsSheet.Activate();

    // 2. 設定標題與資料來源
    xlsApp.Caption = lblDMMC.Text + "斷面實測成果表 - 另存為";
    DataTable myDT1 = GetDataTable(...); // 取得主資料
    DataTable myDT2 = GetDataTable(...); // 取得輔助資料

    // 3. 寫入表頭、資料列、特殊標記(▲/▼)
    // ... 迴圈寫入 xlsSheet.Cells[row, col] ...

    // 4. 進階格式化:欄寬、行高、字型、對齊、邊框、數值格式
    xlsSheet.Columns.ColumnWidth = 9;
    xlsSheet.Rows.RowHeight = 18;
    xlsSheet.Cells.Font.Name = "新細明體"; // 建議使用系統通用字型
    xlsSheet.Cells.Font.Size = 10;
    // 設定標題列粗體、特定儲存格底線、數值格式(##### / #####.0)等

    // 5. 列印設定(若需列印)
    xlsSheet.PageSetup.Orientation = Excel.XlPageOrientation.xlLandscape;
    xlsSheet.PageSetup.PaperSize = Excel.XlPaperSize.xlPaperA4;
    xlsSheet.PageSetup.CenterHorizontally = true;
    // 設定邊距、標題列重複列印等

    // 6. 彈出「另存新檔」對話框並儲存
    string fileName = xlsApp.GetSaveAsFilename(
        "斷面實測成果表.xls",
        "Excel檔案 (*.xls), *.xls",
        1,
        "斷面實測成果表"
    ).ToString().Trim();

    if (!string.IsNullOrEmpty(fileName) && fileName != "False")
    {
        xlsSheet.SaveAs(fileName, Excel.XlFileFormat.xlExcel9795, 
            Type.Missing, Type.Missing, false, false, 
            Excel.XlSaveAsAccessMode.xlNoChange, 
            Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
    }

    // 7. **關鍵:正確釋放 COM 物件,避免 Excel 殭屍進程**
    xlsBook.Saved = true;
    xlsBook.Close();
    xlsApp.Quit();
    ReleaseComObject(xlsSheet);
    ReleaseComObject(xlsBook);
    ReleaseComObject(xlsApp);
    GC.Collect();
    GC.WaitForPendingFinalizers();
}

實務關鍵點總結

1. COM 物件釋放(最重要)

每一個 Excel.Range、Worksheet、Workbook、Application 都屬於 COM 物件,**必須顯式呼叫 Marshal.ReleaseComObject()**,否則 Excel 進程將殘留在背景。建議封裝輔助方法:

private void ReleaseComObject(object obj)
{
    if (obj != null) 
    {
        try { Marshal.ReleaseComObject(obj); } 
        catch { } 
        finally { obj = null; }
    }
}

2. 避免「雙重點號」存取

錯誤: xlsApp.Workbooks.Add().Worksheets[1](中間產生的 Workbooks 未釋放)
正確: 分層宣告變數並逐一釋放,如範例所示。

3. 效能優化:批次寫入

逐格寫入 Cells[i, j] = value 極慢。大量資料請改用陣列一次寫入:

object[,] data = new object[rowCount, colCount];
// 填入陣列...
xlsSheet.get_Range("A1").Resize[rowCount, colCount].Value2 = data;

4. 相容性提醒

  • 需安裝 Microsoft Office Excel(或至少安裝 PIAs/Office Runtime)。
  • xlExcel9795 產生 .xls (BIFF8) 格式,若需 .xlsx 請改用 xlOpenXMLWorkbook (51)。
  • 伺服器端/非互動環境(如 IIS、Windows Service)**嚴禁使用 Interop**,請改用 ClosedXML、EPPlus 或 NPOI 等純 .NET 函式庫。

結語

Interop 雖功能強大,但部署門檻高、效能較差、記憶體管理繁瑣。現代專案建議優先評估 ClosedXML(支援 .xlsx、語法優雅、無 Office 相依),僅在必須使用 Excel 獨有功能(如巨集、複雜圖表、列印預覽)時才採用 Interop。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved