在 ASP.NET 伺服器端使用 Microsoft.Office.Interop.Excel 產出**真正的 .xls/.xlsx 二進位檔案** (而非偽裝的 HTML),雖然功能強大,但部署維護極其繁瑣。本文彙整實戰中遇到的三大核心問題與解決方案。
現象: 專案引用 Microsoft.Office.Interop.Owc11,部署至伺服器報 COMException (0x80040154): Class not registered。
解決:
現象: 開發機 Office 2003 (PIA 11.0),伺服器 Office 2010/2016 (PIA 14.0/15.0) → FileNotFoundException 或 TypeLoadException。
根因: Interop 組件強綁定特定版本 PIA (Primary Interop Assembly),且需目標機安裝對應版本 Office (含 .NET Programmability Support)。
標準部署步驟 (以 Office 2003 PIA 11.0 為例):
Microsoft.Office.Interop.Excel (Version=11.0.0.0)。現代化替代方案 (強烈建議): 棄用 Interop,改用 ClosedXML、EPPlus、NPOI、DocumentFormat.OpenXml 等純 managed 程式庫,無需安裝 Office、支援 Linux 容器、記憶體可控、效能優異。
現象: 網站呼叫 new ApplicationClass() 或 Workbooks.Open() 拋出 System.UnauthorizedAccessException: Retrieving the COM class factory for component with CLSID {00024500-0000-0000-C000-000000000046} failed due to the following error: 80070005 Access is denied.
根因: IIS 工作者處理序身分 (通常為 `IIS_IUSRS` 或 `ApplicationPoolIdentity`) 無權啟動/存取 Excel COM 伺服器 (Out-of-process COM Server)。
dcomcnfg.exe (或 `控制台` → `系統管理工具` → `元件服務`)。元件服務 → 電腦 → 我的電腦 → DCOM 設定。app.DisplayAlerts = false; app.Visible = false; 避免彈窗卡住進程。Marshal.ReleaseComObject() 逐層釋放 `Range`、`Worksheet`、`Workbook`、`Application`,並呼叫 `GC.Collect(); GC.WaitForPendingFinalizers();` 防止 Excel 殭屍進程殘留佔用授權/記憶體。| 維度 | Microsoft.Office.Interop.Excel | ClosedXML / EPPlus / NPOI |
|---|---|---|
| 伺服器需安裝 Office | 是 (授權成本高、安全風險) | 否 |
| 支援 Linux / Docker | 否 | 是 |
| 並發效能 | 極差 (STA、鎖死、記憶體洩漏) | 優異 (純 managed、多執行緒安全) |
| 檔案格式支援 | .xls, .xlsx | .xlsx (OpenXML),NPOI 另支援 .xls |
| 複雜圖表/巨集/列印 | 完整支援 | 有限/不支援 |
結論: 除非必須操作巨集、列印、複雜圖表或舊版 .xls 相容,**新專案請直接選用 ClosedXML (語法最親和) 或 NPOI (支援 .xls)**,徹底規避 COM 部署地獄。