SharePoint 2013中Office Interop Word导出PDF报0x80004005错误求助
问题概述
开发的SharePoint Web部件使用ExportAsFixedFormat方法将生成的Word文档导出为PDF,开发环境运行正常,但部署到生产服务器后抛出COMException (0x80004005)错误,提示“Word has encountered a problem”。备注:文件保存路径为wwwroot,使用Office 2013。
错误堆栈
[COMException (0x80004005): Word has encountered a problem.] Microsoft.Office.Interop.Word.DocumentClass.ExportAsFixedFormat(String OutputFileName, WdExportFormat ExportFormat, Boolean OpenAfterExport, WdExportOptimizeFor OptimizeFor, WdExportRange Range, Int32 From, Int32 To, WdExportItem Item, Boolean IncludeDocProps, Boolean KeepIRM, WdExportCreateBookmarks CreateBookmarks, Boolean DocStructureTags, Boolean BitmapMissingFonts, Boolean UseISO19005_1, Object& FixedFormatExtClassPtr) +0 Microsoft.SharePoint.<>c__DisplayClass5.<RunWithElevatedPrivileges>b__3() +349 Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode) +197 Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(WaitCallback secureCode, Object param) +423 Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(CodeToRunElevated secureCode) +95 test.PdfExporter.WebParts.PrintPDF.PrintPDFUserControl.generateWodDoc(ServiceConfermationList serviceConfermationList) +158 test.PdfExporter.WebParts.PrintPDF.PrintPDFUserControl.<btnPrint_Click>b__3_0() +2075 Microsoft.SharePoint.<>c__DisplayClass5.<RunWithElevatedPrivileges>b__3() +349 Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode) +197 Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(WaitCallback secureCode, Object param) +423 Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(CodeToRunElevated secureCode) +95 test.PdfExporter.WebParts.PrintPDF.PrintPDFUserControl.btnPrint_Click(Object sender, EventArgs e) +94 System.Web.UI.WebControls.Button.OnClick(EventArgs e) +99 System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +140 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2749
代码示例
using Microsoft.Office.Interop.Word; // Create a new Word application Application wordApp = new Application(); // Create a new document Document doc = wordApp.Documents.Add(); // Insert content into the document Paragraph para = doc.Content.Paragraphs.Add(); para.Range.Text = "Hello, World!"; // Export the document as PDF string pdfFileName = "example.pdf"; doc.ExportAsFixedFormat(pdfFileName, WdExportFormat.wdExportFormatPDF); // Clean up doc.Close(); wordApp.Quit();
解决方案
1. 权限配置调整
生产环境中,SharePoint应用池账户需具备以下权限:
- 对
wwwroot目录的读写权限,确保能正常写入生成的PDF文件。 - Office COM组件访问权限:
- 打开
组件服务->计算机->我的电脑->DCOM配置。 - 找到
Microsoft Word 97 - 2003 Document(对应Office 2013),右键选择属性。 - 在
安全选项卡中,给SharePoint应用池账户分配启动和激活权限、访问权限下的本地启动、本地激活、本地访问权限。 - 在
身份选项卡,选择交互式用户;若应用池为域账户,也可选择此用户并输入对应账户信息。
- 打开
2. Office组件环境检查
- 确保生产服务器安装完整版Office 2013(不能是Office 365点击运行版,这类版本不支持COM交互),并安装最新Office更新补丁。
- 移除代码中嵌套的
RunWithElevatedPrivileges调用(错误堆栈显示两次权限提升),嵌套操作会导致COM组件上下文混乱,改为单次权限提升执行完整Word操作流程。
3. 代码优化:避免COM对象泄漏
原代码未正确释放COM对象,易导致生产环境Word进程残留引发异常,修改代码如下:
using Microsoft.Office.Interop.Word; using System.Runtime.InteropServices; using Microsoft.SharePoint; // 单次权限提升执行完整流程 SPSecurity.RunWithElevatedPrivileges(() => { Application wordApp = null; Document doc = null; Paragraph para = null; try { wordApp = new Application(); // 设置Word后台运行,禁用警告 wordApp.Visible = false; wordApp.DisplayAlerts = WdAlertLevel.wdAlertsNone; doc = wordApp.Documents.Add(); para = doc.Content.Paragraphs.Add(); para.Range.Text = "Hello, World!"; // 使用完整物理路径,避免相对路径权限问题 string pdfPath = System.Web.Hosting.HostingEnvironment.MapPath("~/example.pdf"); doc.ExportAsFixedFormat(pdfPath, WdExportFormat.wdExportFormatPDF, OpenAfterExport: false, OptimizeFor: WdExportOptimizeFor.wdExportOptimizeForPrint); doc.Close(SaveChanges: false); } finally { // 逐一释放COM对象,防止内存泄漏 if (para != null) Marshal.ReleaseComObject(para); if (doc != null) Marshal.ReleaseComObject(doc); if (wordApp != null) { wordApp.Quit(); Marshal.ReleaseComObject(wordApp); } } });
4. 字体缺失处理
生产服务器若缺少文档使用的字体,会导致导出失败。可采取两种方案:
- 在生产服务器安装文档中用到的所有字体。
- 在
ExportAsFixedFormat调用中设置BitmapMissingFonts: true,强制将缺失字体转为位图:doc.ExportAsFixedFormat(pdfPath, WdExportFormat.wdExportFormatPDF, BitmapMissingFonts: true);
内容的提问来源于stack exchange,提问作者SaMuTa
相关产品推荐
相关产品推荐

