在 .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() 統一釋放
}
}
Visual Studio **不預置** Microsoft.Office.Interop.Excel.dll,需手動生成:
C:\Program Files\Microsoft Office\OfficeXX\EXCEL9.OLB(XX 為版本號)到 VS SDK 目錄:C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\TlbImp Excel9.olb /out:Excel.dllExcel.dll 位於 Bin 目錄,專案中「添加引用」→「瀏覽」選中即可現代替代方案:NuGet 安裝 Microsoft.Office.Interop.Excel 套件,自動處理 PIA 組件引用。
Application (Excel.ApplicationClass)
└── Workbooks 集合
└── Workbook (WorkbookClass)
└── Worksheets 集合
└── Worksheet
└── Cells[row, col] / Range["A1"]
Cells[row, col]:行列索引**從 1 開始**(非 0)Range["A1:C3"]:支援 A1 式引用,批量操作更高效| 步驟 | 代碼 | 作用 |
|---|---|---|
| 1. 關閉應用 | app.Quit() | 通知 Excel 進程退出 |
| 2. 釋放 RCW | Marshal.ReleaseComObject(app) | 釋放 Runtime Callable Wrapper,遞減 COM 參考計數 |
| 3. 強制 GC | GC.Collect(); GC.WaitForPendingFinalizers(); | 確保最終化器執行,徹底清理非托管資源 |
血淚教訓:缺少任一步驟,任務管理器中將殘留 EXCEL.EXE 進程,導致後續自動化失敗、授權佔用、內存洩漏。
Range["A1:D4"].Value = object[,] dataArray 一次性寫入二維數組,比逐 Cell 寫入快 100 倍+app.ScreenUpdating = false; 操作期間禁用重繪app.Calculation = XlCalculation.xlCalculationManual; 公式密集表格加速| 問題 | 原因 | 解決 |
|---|---|---|
| 「Retrieving the COM class factory failed (0x80040154)」 | 未安裝 Office 或位數不匹配(x86/x64) | 安裝 Office;專案屬性→Build→勾選 "Prefer 32-bit" 或匹配 Office 位數 |
| 伺服器端無法啟動 Excel | DCOM 權限、互動式登入限制 | DCOMCNFG → Microsoft Excel Application → 權限 → 添加 IIS_IUSRS/NETWORK SERVICE 啟動權限 |
| 大數據導出超時/記憶體爆炸 | COM 邊界開銷、GC 壓力 | 改用 OpenXML SDK / EPPlus / NPOI 純 .NET 方案,無需安裝 Office |
若環境**不允許安裝 Office**(如 Linux 容器、雲函數、CI/CD),強烈建議改用純 .NET 庫:
Install-Package EPPlus,支援 .xlsx,API 友好,性能優異Install-Package NPOI,同時支援 .xls/.xlsx,Apache POI 移植版Install-Package ClosedXML,OpenXML 封裝,語法極簡COM 互操作是操作 Excel 的「核選項」——功能最全(支援宏、圖表、樣式、打印區域等高級特性),但**部署重、資源難管、性能差、不支援無 Office 環境**。
現代專案優先選擇 EPPlus / NPOI;僅在**必須利用 Excel 引擎計算公式、渲染圖表、執行 VBA** 時,才啟用 COM 方案,並嚴格遵循 Quit → ReleaseComObject → GC.Collect 三步釋放法。