c# 通过代码调用WPS将Word转为PDF

发布时间 2023-10-31 16:11:38作者: 向前_走

最近在使用Spire.Doc的过程中,发现在将word文件转为PDF时,一旦页数过多(具体超过多少页会报错暂未求证),会直接报错(Object reference not set to an instance of an object.),堆栈信息如下:

当然,我这是免费版的,功能被阉割很正常,所以这两天一直在寻找替代品。

中间了解到可以使用微软官方的组件Microsoft.Office.Interop.Word去操作,奈何需要先安装office,奈何本地只有WPS,就想着能不能用WPS实现下。

经搜索后果然可以实现,但是实践下来遇到了很多坑,故在此记录下,希望大伙遇到同样的问题时,就不用耽搁太久了。

说下操作步骤:

1、本地要安装WPS。

2、在项目中添加引用,点击“COM”,勾选下图中的两个组件,即wpsapi.dll、ksoapi.dll,其中wpsapi.dll是操作word的组件,ksoapi.dll是wpsapi.dll依赖的组件:

 3、完成以上操作后,写好测试代码,开始运行即可,下面贴出我的测试代码:

 1         /// <summary>
 2         /// word转pdf
 3         /// </summary>
 4         /// <param name="sourceWordPath">源文件路径<see cref="string"/>.</param>
 5         /// <param name="newPdfPath">新文件路径<see cref="string"/>.</param>
 6         /// <returns>The <see cref="bool"/>.</returns>
 7         public static void WordToPdf(string sourceWordPath, string newPdfPath)
 8         {
 9             if (sourceWordPath == null) throw new ArgumentNullException(nameof(sourceWordPath));
10             if (newPdfPath == null) throw new ArgumentNullException(nameof(newPdfPath));
11 
12             var type = Type.GetTypeFromProgID("KWps.Application");
13             dynamic wps = Activator.CreateInstance(type);
14 
15             //ApplicationClass wps = new ApplicationClass();
16             //用上行注释的方式初始化的话,会报错误:
17             //检索 COM 类工厂中 CLSID 为 {000209FF-0000-4B30-A977-D214852036FE} 的组件失败,
18             //原因是出现以下错误: 80040154 没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))
19 
20             try
21             {
22                 //用wps打开word不显示界面
23                 dynamic doc = wps.Documents.Open(sourceWordPath, Visible: false);
24 
25                 //转pdf
26                 doc.ExportAsFixedFormat(newPdfPath, WdExportFormat.wdExportFormatPDF);
27 
28                 doc.Close();
29             }
30             catch (Exception e)
31             {
32                 Console.WriteLine(e.Message);
33             }
34             finally
35             {
36                 wps.Quit();
37                 GC.Collect();
38                 GC.WaitForPendingFinalizers();
39             }
40 
41         }

到这里就算大功告成了。

最开始我是用.Net Core 3.1进行测试的,发现始终加载不了COM组件,最终使用.Net Framework 4.6.1测试没有问题