常見崩潰原因分析
| 庫/方案 | 典型崩潰原因 | 解決方向 |
| Microsoft.Office.Interop.Word | 未安裝 Office / 版本不匹配 / COM 組件註冊損壞 / 服務端無交互桌面權限 | ❌ 禁用於服務端/自動化場景 |
| FreeSpire.Doc | 授權驗證失敗 / 版本不兼容 / 複雜表格/圖片渲染異常 | 檢查 License、升級版本、簡化文檔結構 |
| NPOI (XWPF) | POI 版本與 .docx 格式不匹配 / 大文件 OOM / 样式衝突 | 升級 NPOI 2.6+、流式寫入 SXWPFDocument |
| OpenXML SDK | XML 結構錯誤 / 命名空間缺失 / 關係部件未正確創建 | 使用 Productivity Tool 驗證、嚴格遵循 ECMA-376 |
推薦方案:OpenXML SDK (微軟官方、無依賴、高性能)
1. NuGet 安裝
Install-Package DocumentFormat.OpenXml
2. 創建基礎 Word 文檔 (最小可行代碼)
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
public static void CreateBasicDocx(string filePath)
{
using (WordprocessingDocument doc = WordprocessingDocument.Create(filePath, WordprocessingDocumentType.Document))
{
// 1. 添加主文檔部件
MainDocumentPart mainPart = doc.AddMainDocumentPart();
mainPart.Document = new Document();
Body body = mainPart.Document.AppendChild(new Body());
// 2. 添加段落與文本
Paragraph para = body.AppendChild(new Paragraph());
Run run = para.AppendChild(new Run());
run.AppendChild(new Text("Hello, OpenXML SDK!"));
// 3. 保存 (using 塊自動調用 Save)
}
}
3. 進階:樣式、表格、圖片完整示例
public static void CreateRichDocx(string filePath)
{
using (var doc = WordprocessingDocument.Create(filePath, WordprocessingDocumentType.Document))
{
var mainPart = doc.AddMainDocumentPart();
mainPart.Document = new Document(new Body());
var body = mainPart.Document.Body;
// 樣式定義部件
var stylePart = mainPart.AddNewPart();
stylePart.Styles = new Styles();
GenerateStyles(stylePart.Styles);
// 標題
body.Append(CreateParagraph("項目報告", "Heading1"));
// 正文段落
body.Append(CreateParagraph("這是使用 OpenXML SDK 生成的 Word 文檔。", "Normal"));
body.Append(CreateParagraph("支持豐富格式:", "Normal"));
// 帶格式的 Run
var para = new Paragraph();
para.Append(CreateRun("粗體", true, false, "28"));
para.Append(CreateRun(" 、", false, false, "28"));
para.Append(CreateRun("紅色", false, false, "28", "FF0000"));
body.Append(para);
// 表格
body.Append(CreateTable(new[] { "列1", "列2", "列3" },
new[] { new[] { "A1", "B1", "C1" }, new[] { "A2", "B2", "C2" } }));
// 圖片 (需添加 ImagePart)
// body.Append(CreateImageParagraph(mainPart, "logo.png", "Logo"));
}
}
// 輔助方法略...
// 關鍵點:所有 OpenXML 元素必須在正確的命名空間、正確的父子層級創建
// 使用 OpenXML Productivity Tool (SDK 安裝目錄) 打開現有 .docx 反編譯生成 C# 代碼
調試崩潰的黃金法則
- 捕獲異常堆棧:`try-catch` 記錄完整 `ex.ToString()`,特別關注 `OpenXmlPackageException`、`FileFormatException`
- 驗證文檔:`OpenXmlValidator validator = new(); var errors = validator.Validate(doc);` 列出所有標準違規
- 對比正確文檔:用 Productivity Tool 打開手工創建的正確 .docx,點擊「Reflect Code」生成標準代碼對比
- 最小化復現:逐行註釋代碼定位崩潰行,構建最小復現項目提 Issue
方案選型決策樹
需要在服務器/容器運行?
├─ 是 → 禁用 Interop
│ ├─ 簡單文檔、高性能、無 Office 依賴 → OpenXML SDK ⭐⭐⭐⭐⭐
│ ├─ 複雜報表、郵件合併、模板引擎 → FreeSpire.Doc / NPOI / DocX
│ └─ 需要 PDF 轉換 → LibreOffice Headless / 商業庫
└─ 否 (桌面端、用戶機已裝 Office)
└─ 需要 Word 打印/打印預覽/宏/ActiveX → Interop 可接受
參考資源