关于.net调用com组件将word或exce转为pdf或html进行预览的问题整理
1.先贴代码(dll地址自己百度下载,名字叫做Microsoft.Office.Interop.Word.dll)
/ ///// 将word文档转换成PDF格式 /// /// /// ///public bool ConvertWord2Pdf(string sourcePath, string targetPath) { bool result; LogWriter.WriteErrorLog("0"); Microsoft.Office.Interop.Word.WdExportFormat exportFormat = Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF; LogWriter.WriteErrorLog("1"); object paramMissing = Type.Missing; LogWriter.WriteErrorLog("2"); Microsoft.Office.Interop.Word.Application wordApplication = new Microsoft.Office.Interop.Word.Application(); LogWriter.WriteErrorLog("3"); Microsoft.Office.Interop.Word.Document wordDocument = null; LogWriter.WriteErrorLog("4"); try { object paramSourceDocPath = sourcePath; string paramExportFilePath = targetPath; LogWriter.WriteErrorLog("5"); Microsoft.Office.Interop.Word.WdExportFormat paramExportFormat = exportFormat; LogWriter.WriteErrorLog("6"); Microsoft.Office.Interop.Word.WdExportOptimizeFor paramExportOptimizeFor = Microsoft.Office.Interop.Word.WdExportOptimizeFor.wdExportOptimizeForPrint; LogWriter.WriteErrorLog("7"); Microsoft.Office.Interop.Word.WdExportRange paramExportRange = Microsoft.Office.Interop.Word.WdExportRange.wdExportAllDocument; LogWriter.WriteErrorLog("8"); int paramStartPage = 0; int paramEndPage = 0; LogWriter.WriteErrorLog("9"); Microsoft.Office.Interop.Word.WdExportItem paramExportItem = Microsoft.Office.Interop.Word.WdExportItem.wdExportDocumentContent; LogWriter.WriteErrorLog("10"); Microsoft.Office.Interop.Word.WdExportCreateBookmarks paramCreateBookmarks = Microsoft.Office.Interop.Word.WdExportCreateBookmarks.wdExportCreateWordBookmarks; LogWriter.WriteErrorLog("11"); wordDocument = wordApplication.Documents.Open( ref paramSourceDocPath, ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing); LogWriter.WriteErrorLog("12"); if (wordDocument != null) { LogWriter.WriteErrorLog("13"); wordDocument.ExportAsFixedFormat(paramExportFilePath, paramExportFormat, false, paramExportOptimizeFor, paramExportRange, paramStartPage, paramEndPage, paramExportItem, true, true, paramCreateBookmarks, true, true, false, ref paramMissing); LogWriter.WriteErrorLog("14"); } result = true; LogWriter.WriteErrorLog("15"); } catch (Exception ex) { LogWriter.WriteErrorLog(ex); result = false; } finally { if (wordDocument != null) { wordDocument.Close(ref paramMissing, ref paramMissing, ref paramMissing); wordDocument = null; } if (wordApplication != null) { wordApplication.Quit(ref paramMissing, ref paramMissing, ref paramMissing); wordApplication = null; } GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); } return result; } /// /// word转成html /// /// public string WordToHtml(object wordFileName) { try { LogWriter.WriteErrorLog("0"); //在此处放置用户代码以初始化页面 Microsoft.Office.Interop.Word.Application word = new Microsoft.Office.Interop.Word.Application(); LogWriter.WriteErrorLog("1"); Type wordType = word.GetType(); LogWriter.WriteErrorLog("2"); Microsoft.Office.Interop.Word.Documents docs = word.Documents; LogWriter.WriteErrorLog("3"); //打开文件 Type docsType = docs.GetType(); LogWriter.WriteErrorLog("4"); Microsoft.Office.Interop.Word.Document doc = (Microsoft.Office.Interop.Word.Document)docsType.InvokeMember("Open", System.Reflection.BindingFlags.InvokeMethod, null, docs, new Object[] { wordFileName, true, true }); LogWriter.WriteErrorLog("5"); LogWriter.WriteErrorLog(doc.ToString()); //转换格式,另存为 Type docType = doc.GetType(); LogWriter.WriteErrorLog("6"); string wordSaveFileName = wordFileName.ToString(); LogWriter.WriteErrorLog("7"); string strSaveFileName = wordSaveFileName.Substring(0, wordSaveFileName.LastIndexOf(".")) + ".html"; //wordSaveFileName.Substring(0, wordSaveFileName.Length - 3) + "html"; LogWriter.WriteErrorLog("8"); object saveFileName = (object)strSaveFileName; LogWriter.WriteErrorLog("9"); docType.InvokeMember("SaveAs", System.Reflection.BindingFlags.InvokeMethod, null, doc, new object[] { saveFileName, Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatFilteredHTML }); LogWriter.WriteErrorLog("10"); docType.InvokeMember("Close", System.Reflection.BindingFlags.InvokeMethod, null, doc, null); LogWriter.WriteErrorLog("11"); //退出 Word wordType.InvokeMember("Quit", System.Reflection.BindingFlags.InvokeMethod, null, word, null); LogWriter.WriteErrorLog("12"); return saveFileName.ToString(); } catch (Exception ex) { LogWriter.WriteErrorLog(ex.ToString()); return ""; } }
2.上面的代码主要的功能分别是将word转换为pdf和将word转换为html,以上代码在本地执行完全没问题,可以正常生成html或者word,但是在服务器上就会出现问题,问题如下
3.问题1,通过以上的log日志我们可以发现,以上代码都执行到了0,后面的代码没有执行,同时报了以下的错误,也就是说在都是在调用com组件上出现了问题
错误日志
System.UnauthorizedAccessException: Retrieving the COM class factory for component with CLSID {000209FF-0000-0000-C000-000000000046} failed due to the following error: 80070005 拒绝访问。 (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)).
4.以上的错误可以通过以下几步来解决
1).运行dcomcnfg -》组件服务-》计算机-》我的电脑-》DCom配置-》找到Microsoft Word文档
如果是win7服务器或者window server服务器 需要运行comexp.msc -32 否则在DCom配置找不到Microsoft Word文档
office下载地址:http://www.xitongtiandi.net/soft_yy/2076.html
2).单击属性打开此应用程序的属性对话框。
3).单击标识选项卡,然后选择交互式用户。
4).单击"安全"选项卡,分别在"启动和激活权限"和"访问权限"组中选中"自定义",然后自定义->编辑->账户
关于步骤 4) 网上说需要添加自定义->编辑->添加ASP.NET账户和IUSER_计算机名,然而我并没有找到这两个账户,所以我就添加了个everyone权限,这个权限可能不安全,因为我是自己的测试服务器,所 以这样设置没有问题,如果觉得不安全,可以自己试试添加别的账户试试
5).打开IIS->应用程序池->高级设置->将标识由原来的ApplicationPoolIdentity改为LocalSystem(有人说改为LocalServer也可以,我我自己试了下是不行的,不知道别人可不可以),这一步非常重要,网上好 多解决方案都没有这一步
5.设置好后再次运行,会发现,日志显示word转pdf并没有执行13和14,word转html只执行到了5,没有执行6往后面的代码,同时爆出一个错误为将对象引用到实例。通过这个错误可以判断 出 Microsoft.Office.Interop.Word.Document是null,这又该怎么解决呢,网上查了一大堆,一个有用的没有,直到偶然间发现一篇博客,以下就是解决方案
6.找到目录C:\Windows\SysWOW64\config\systemprofile\ 然后在里面新建一个文件夹Desktop ,注意大小写,就是这么简单,惊不惊喜,意不意外,同理excel转pdf或者html就需要重新百度下别的代码了,并且DCom配置改成excel的就行了,这里不做说明