不推荐在生产环境用 microsoft.office.interop.word,尤其不能用于服务器端——它依赖桌面版 office 安装、线程模型敏感、极易卡死或崩溃;推荐 docx 或 openxml sdk 等无依赖、纯托管方案。

直接说结论:别用 Microsoft.Office.Interop.Word 做服务端或批量生成,它会启动 Word 进程、吃内存、卡死、报错“RPC 服务器不可用”,而且服务器上没装 Office 就直接失败。
为什么 DocX(Xceed.Words.NET)适合快速生成报告
它不依赖 Office 安装,纯 .NET 实现,所有操作都在内存里完成。生成一份含表格、图片、样式的 15 页报告,实测平均耗时 180–220ms,吞吐量稳定在每秒 4–5 份。
- 模板填充必须用 Word 原生的域字段:
Insert → Quick Parts → Field → MergeField,手打«Name»是无效文本,DocX 找不到也替换不了 - 域只在主文档区域生效,页眉页脚里的
MERGEFIELD默认被忽略,需手动调用doc.Header.Primary.Fields或doc.Footer.Primary.Fields单独处理 - 社区版(免费)不支持图表插入和目录更新,商用必须买授权;3.0+ 版本才支持 .NET 6/7/8,老项目升级前先确认目标框架
- 表格循环推荐用
doc.ReplaceText("{{loop:Items}}", "")配合自定义标记解析,原生不支持嵌套循环,得自己写foreach+InsertTable()
OpenXML 是唯一能上生产环境的方案
如果你要支撑每天万级导出、跑在 Linux Docker 里、或者老板说“不能有任何第三方授权风险”,DocumentFormat.OpenXml 是事实标准。它本质是操作 ZIP 包里的 XML,无进程、无依赖、可审计。
- 新建文档必须走完整链路:
WordprocessingDocument.Create()→AddMainDocumentPart()→MainDocumentPart.Document.Body,漏掉AddMainDocumentPart()会导致文件损坏、“无法打开” - 每个段落不是
new Paragraph("text"),而是new Paragraph(new ParagraphProperties(), new Run(new Text("text"))),缺一层嵌套,Word 就报The element has invalid child element - 表格必须嵌在段落里:
Body → Paragraph → Table → TableRow → TableCell → Paragraph → Run → Text,TableCell里不放Paragraph,内容就完全不显示 - 图片插入必须用绝对路径 + 正确
ImagePartType(比如ImagePartType.Jpeg),相对路径或类型错一个字节,图片就变红叉
别踩这些运行时坑
很多问题不是代码逻辑错,而是资源没释放或路径没对齐。
-
WordprocessingDocument必须用using块包裹,否则文件句柄一直占着,第二次写同名文件直接抛IOException: The process cannot access the file - DocX 的
Save()如果传入已存在的路径,不会覆盖——它会静默失败,建议先File.Delete()再保存 - OpenXML 插入中文没问题,但
、<code>>、&会被自动转义成、<code>>、&,不需要手动HtmlEncode,否则会变成双转义 - 模板中用书签(Bookmark)定位比用文本查找可靠得多,但 OpenXML 读取书签要手动遍历
Body.Descendants<bookmarkstart>()</bookmarkstart>,DocX 则提供doc.Bookmarks["xxx"]直接取
真正难的不是写第一份报告,而是让第 10001 份报告和第一份长得一模一样、字体不漂移、表格不碎、页眉不丢——这取决于你从第一天就选对了底层模型,而不是等上线后靠补丁堆出来。










