方案一、采用OpenXml(服务器不依赖Office组件)
在word生成的最后加上代码:
using (WordprocessingDocument docx = WordprocessingDocument.Open(sourceRealReportPath, true))
{
//操作word代码
…
//更新域
docx.MainDocumentPart.DocumentSettingsPart.Settings.Append(new DocumentFormat.OpenXml.Wordprocessing.UpdateFieldsOnOpen() { Val = true });
docx.Close();
}
采用这种方式生成word之后,需要打开word时才触发更新更新域操作,且打开word时会有提示框,若要去除提示框,需在客户机上进行以下两步操作:
1、修改注册表:(找到对应office版本)
HKEY_CURRENT_USERSoftwareMicrosoftOffice10.0WordOptions
新增或修改DWORD Value:FieldCalcSecurityLevel;值设置为0
FieldCalcSecurityLevel |
DisplayAlerts=wdAlertsNone |
0 |
Message does not appear and Link Group fields update automatically. |
1 |
Message is suppressed and Link Group Fields update. |
2 |
Message is suppressed and Link Group Fields do not update. |
注意:
1、这里存在问题,如果不打开word的话,目录无法更新,必须有使用office打开word的操作
2、不打开word,直接通过office web 365转Pdf或者在线阅读word,目录也不会更新
2、修改office->选项->信任中心->信任中心设置->受保护视图:
移除掉:”为来自Internet的文件启用受保护视图”前面的勾选
方案二、采用Office组件(服务器必须安装Office)
采用Office组件调用实现更新目录的话,有一些弊端:
①服务器必须安装office
②调用com组件实际上相当于在服务器上打开word进行操作,当并发量比较大时,word的处理速度会比较慢,并发量越大处理越慢,可以想象,当电脑打开50个word时,操作肯定会卡,这是一个道理;暂时还未发现有效的解决方法。
(实例化一个com实例,处理多个文件倒是可以加快速度,但是要看实际的应用场景是否可以多个文件一起处理;我现在遇到的场景是必须同步一个个文件进行处理,纠结中,,,,)
服务器安装office并需要配置环境:
(参考:https://www.cnblogs.com/5426z/articles/4865312.html)
①首先服务器需要安装:office软件,我安装的是office2010版本,安装后在服务器端不用激活也可以使用。
②组件权限设置:
在运行栏中输入命令:dcomcnfg,打开组件服务管理窗口,但是却发现找不到Microsoft Word程序,这主要是64位系统的问题,word是32位的组件,所以在正常的系统组件服务里是看不到的,可以通过在运行里面输入comexp.msc -32 来打开32位的组件服务,在里就能看到Microsoft Word组件了。
③IIS权限设置:将IIS中应用程序池运行用户改为LocalSystem
必须要先配置组件权限,仅仅将IIS中应用程序池运行用户改为LocalSystem是不行的:不会报80070005组件错误,但是读取的word对象会为null
DCOM 的配置过程。
1、运行“dcomcnfg”,打开 DCOM 配置程序。(或者 开始→设置→控制面版→管理工具→组件服务→计算机→我的电脑→DCOM配置)
对 Word进行编程,实际上就是通过 .Net
Framework 去调用 Excel 的 COM 组件,所有要在 Web 环境下调用 COM 组件的时候,都需要对其进行相应的配置。
很多朋友都反映在 Windows 环境下调试正常的程序,一拿到 Web 环境中就出错,实际上就是因为缺少了这一步。
①将 “身份标识” 选项卡中的用户设为 “交互式用户” 。
②设置选中 “安全性” 选项卡中的 “使用自定义配置权限”,点击 “编辑”。
③用户添加 EveryOne、 IIS User、NetWork Service,并将所有操作权限都勾选(建议)
.net开发环境搭建:
Vs开发com组件引用
(我这里本机安装的是office2010,根据各自电脑安装的情况选择即可)
这样就可以使用了:(参考代码)
//实例化COM Microsoft.Office.Interop.Word.ApplicationClass wordApp = new Microsoft.Office.Interop.Word.ApplicationClass(); object fileobj = filePath; object nullobj = System.Reflection.Missing.Value; //打开指定文件(不同版本的COM参数个数有差异,一般而言除第一个外都用nullobj就行了) Microsoft.Office.Interop.Word.Document doc = wordApp.Documents.Open(ref fileobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj, ref nullobj ); //更新目录 doc.TablesOfContents[1].Update(); //LogHelper.Info(string.Format("操作3.1")); doc.Save();//保存 //获取Word页码 Microsoft.Office.Interop.Word.WdStatistic PagesCountStat = Microsoft.Office.Interop.Word.WdStatistic.wdStatisticPages; pageCount = doc.ComputeStatistics(PagesCountStat, ref nullobj); //关闭文件 doc.Close(ref nullobj, ref nullobj, ref nullobj); //关闭COM wordApp.Quit(ref nullobj, ref nullobj, ref nullobj);
引用完成之后,如果直接用vs进行跑是没有问题的,但是放在iis上面会提示:
检索 COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件时失败,原因是出现以下错误: 80070005
再回到上面检查权限配置是否正确。(一开始我也是报这种错误)
方案三、收费方案(SautinSoft等)
暂时未考虑,收费方案基本都是按开发人员,按部署的项目数来进行收费,代价会比较大。