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

C# 操作 Excel 完整方案:COM 互操作生成 .xls 文件與組件註冊指南

     編輯:更多程式設計知識

在 .NET 中生成 Excel 文件最經典的方案是使用 Microsoft Office COM 互操作組件。本文提供完整的控制台程序示例,涵蓋 Excel.Application 初始化、工作簿創建、單元格寫入、文件保存、COM 物件釋放全流程,並詳細說明 Excel.dll 互操作組件的生成與引用步驟。

完整控制台程序示例

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;

class AppTest
{
    private Excel.ApplicationClass _excelApp;

    public static void Main()
    {
        AppTest app = new AppTest();
        app._excelApp = new Excel.ApplicationClass();
        app._excelApp.UserControl = false; // 後台運行,不顯示 UI

        for (int i = 0; i < 4; i++)
        {
            string filePath = @"D:\test\" + i + ".xls";
            app.SaveToXls(filePath);
        }

        // 正確關閉與釋放 COM 資源
        app._excelApp.Quit();
        Marshal.ReleaseComObject(app._excelApp);
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }

    private void SaveToXls(string filename)
    {
        // 創建新工作簿
        Excel.WorkbookClass wb = (Excel.WorkbookClass)_excelApp.Workbooks.Add(Missing.Value);

        // 寫入數據(注意:COM 索引從 1 開始)
        for (int row = 1; row <= 4; row++)
        {
            _excelApp.Cells[row, 1] = row.ToString();
            _excelApp.Cells[row, 2] = "'bbb2";
            _excelApp.Cells[row, 3] = "'ccc3";
            _excelApp.Cells[row, 4] = "'aaa4";
        }

        wb.Saved = true; // 標記為已保存,避免彈出提示
        _excelApp.ActiveWorkbook.SaveCopyAs(filename); // 另存為副本
        // wb.Close() 會釋放 workbook,這裡由 Quit() 統一釋放
    }
}

關鍵技術點深度解析

1. COM 互操作組件獲取

Visual Studio **不預置** Microsoft.Office.Interop.Excel.dll,需手動生成:

  1. 確保機器已安裝 Microsoft Office(含 Excel)
  2. 複製 C:\Program Files\Microsoft Office\OfficeXX\EXCEL9.OLB(XX 為版本號)到 VS SDK 目錄:
    C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\
  3. 打開「Visual Studio .NET 2003 命令提示」,運行:
    TlbImp Excel9.olb /out:Excel.dll
  4. 生成的 Excel.dll 位於 Bin 目錄,專案中「添加引用」→「瀏覽」選中即可

現代替代方案:NuGet 安裝 Microsoft.Office.Interop.Excel 套件,自動處理 PIA 組件引用。

2. Excel 物件模型層級

Application (Excel.ApplicationClass)
  └── Workbooks 集合
        └── Workbook (WorkbookClass)
              └── Worksheets 集合
                    └── Worksheet
                          └── Cells[row, col] / Range["A1"]
  • Cells[row, col]:行列索引**從 1 開始**(非 0)
  • Range["A1:C3"]:支援 A1 式引用,批量操作更高效

3. 生命週期與資源管理(核心難點)

步驟代碼作用
1. 關閉應用app.Quit()通知 Excel 進程退出
2. 釋放 RCWMarshal.ReleaseComObject(app)釋放 Runtime Callable Wrapper,遞減 COM 參考計數
3. 強制 GCGC.Collect(); GC.WaitForPendingFinalizers();確保最終化器執行,徹底清理非托管資源

血淚教訓:缺少任一步驟,任務管理器中將殘留 EXCEL.EXE 進程,導致後續自動化失敗、授權佔用、內存洩漏。

4. 性能優化建議

  • 批量寫入:用 Range["A1:D4"].Value = object[,] dataArray 一次性寫入二維數組,比逐 Cell 寫入快 100 倍+
  • 關閉螢幕更新:app.ScreenUpdating = false; 操作期間禁用重繪
  • 關閉自動計算:app.Calculation = XlCalculation.xlCalculationManual; 公式密集表格加速
  • 避免循環訪問 COM 屬性:每次跨邊界調用有巨大開銷,讀取整塊數據到陣列再處理

5. 常見坑點與規避

問題原因解決
「Retrieving the COM class factory failed (0x80040154)」未安裝 Office 或位數不匹配(x86/x64)安裝 Office;專案屬性→Build→勾選 "Prefer 32-bit" 或匹配 Office 位數
伺服器端無法啟動 ExcelDCOM 權限、互動式登入限制DCOMCNFG → Microsoft Excel Application → 權限 → 添加 IIS_IUSRS/NETWORK SERVICE 啟動權限
大數據導出超時/記憶體爆炸COM 邊界開銷、GC 壓力改用 OpenXML SDK / EPPlus / NPOI 純 .NET 方案,無需安裝 Office

現代替代方案推薦

若環境**不允許安裝 Office**(如 Linux 容器、雲函數、CI/CD),強烈建議改用純 .NET 庫:

  • EPPlus:Install-Package EPPlus,支援 .xlsx,API 友好,性能優異
  • NPOI:Install-Package NPOI,同時支援 .xls/.xlsx,Apache POI 移植版
  • ClosedXML:Install-Package ClosedXML,OpenXML 封裝,語法極簡
  • DocumentFormat.OpenXml:Microsoft 官方底層 SDK,功能最全但 API 較繁瑣

總結

COM 互操作是操作 Excel 的「核選項」——功能最全(支援宏、圖表、樣式、打印區域等高級特性),但**部署重、資源難管、性能差、不支援無 Office 環境**。

現代專案優先選擇 EPPlus / NPOI;僅在**必須利用 Excel 引擎計算公式、渲染圖表、執行 VBA** 時,才啟用 COM 方案,並嚴格遵循 Quit → ReleaseComObject → GC.Collect 三步釋放法。

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