利用 Microsoft.Office.Interop.PowerPoint 將 `.ppt/.pptx` 轉為 PDF,是早期 ASP.NET 常見需求。但 **Microsoft 官方明確不建議在伺服器端自動化 Office**(非互動式、無使用者配置、權限、穩定性、授權問題)。本文提供可運行的參考實作,**僅供維護舊專案或內部低頻工具使用**;新專案請改用 LibreOffice headless、Aspose.Slides、FreeSpire.Presentation、或雲端轉換 API。
Microsoft.Office.Core、Microsoft.Office.Interop.PowerPoint
using Microsoft.Office.Core;
using Microsoft.Office.Interop.PowerPoint;
using System;
public static class OfficeToPdf
{
/// PPT 轉 PDF,成功回傳 true
public static bool PPTConvertToPDF(string sourcePath, string targetPath)
{
const PpSaveAsFileType SaveAsPdf = PpSaveAsFileType.ppSaveAsPDF;
object missing = Type.Missing;
Application app = null;
Presentation pres = null;
try
{
app = new Application(); // 啟動 PowerPoint 進程
// 開啟檔案:ReadOnly、Untitled、WithWindow=false
pres = app.Presentations.Open(sourcePath, MsoTriState.msoTrue, MsoTriState.msoFalse, MsoTriState.msoFalse);
if (pres != null)
{
pres.SaveAs(targetPath, SaveAsPdf, MsoTriState.msoTrue);
}
return true;
}
catch (Exception ex)
{
// 記錄日誌 ex.Message
return false;
}
finally
{
// 嚴格釋放 COM 物件,避免殭屍進程
if (pres != null)
{
pres.Close();
System.Runtime.InteropServices.Marshal.ReleaseComObject(pres);
pres = null;
}
if (app != null)
{
app.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
app = null;
}
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
}
bool ok = OfficeToPdf.PPTConvertToPDF(@"D:\12345.pptx", @"D:\12345.pdf");
Console.WriteLine(ok ? "轉換成功" : "轉換失敗");
| 問題 | 原因 | 對策 |
|---|---|---|
| 轉換卡住、無回應 | PowerPoint 彈出對話框(修復、字體缺失、宏啟用) | Open 參數 MsoTriState.msoFalse 禁止 UI、預先安裝所需字體、關閉宏安全提示 |
| 併發失敗 | Office 單進程、單執行緒模型 (STA) | 序列化佇列處理、或每請求啟動獨立進程 (效能極差) |
| 權限錯誤 (80070005) | ASP.NET 身分無權存取 DCOM/桌面 | DCOMCNFG 設定「啟動與啟動權限」、或改用無 Office 依賴方案 |
| 記憶體洩漏 | COM 物件未正確 Release | finally 區塊 Marshal.ReleaseComObject + GC.Collect |
| 授權風險 | 伺服器安裝 Office 需 Volume License | 確認授權模式、或改用開源/商業無 Office 方案 |
| 方案 | 授權 | 跨平台 | 轉換保真度 | 備註 |
|---|---|---|---|---|
| LibreOffice headless (soffice --convert-to pdf) | MPL/LGPL | ✅ Win/Linux/macOS | 高 | 需安裝 LibreOffice、字體;適合容器化部署 |
| Aspose.Slides for .NET | 商業 | ✅ | 極高 | 功能最全、支援複雜動畫/母版、無 Office 依賴 |
| FreeSpire.Presentation | 免費(有頁數限制) | ✅ | 中高 | 適合簡單轉換、免費額度足夠多數內部專案 |
| 云端 API (CloudConvert, ConvertAPI, Adobe PDF Services) | 按量付費 | ✅ | 極高 | 無基建維護、資料離開內網需評估合規 |
Interop 方案「能跑但不穩、難維運、有授權疑慮」。**舊專案維護期內可用本文代碼並加上佇列/重試/監控**;**新專案請直接選擇 LibreOffice headless 或商業庫**,徹底擺脫 Office 伺服器端自動化的坑。