使用场景

多个word进行合并;word转pdf; 1,此方法只支持.net framework框架; 2,但恰恰我的项目是netcore的,所以需要在项目中添加引入一个net framework的项目,在源项目中引用framework项目,最终在framework项目中进行对com组件进行调用处理;

一、使用步骤

1.引入库

第一步:创建netFramework项目 在项目中 右键----添加----新建项目----创建一个netFramework的web项目 (也可以下载我写的,直接添加现有项目即可,资源下载地址) 第二步:添加引用 右键引用----添加引用----点击COM----找到 Microsoft Word 14.0 Object Library选中确认添加即可(找不到的话,从nuget上面下载安装也可,已实测) 第三步:创建类文件(此处我只用到了合并word以及word转pdf,其他代码不放了,网上可以搜到) 代码如下(示例):

using System.Collections.Generic;
using System.IO;
using Microsoft.Office.Interop.Word;
using System;
using System.Linq;
using System.Reflection;
using System.Web;

namespace NetFrameworkProject
{
    public class WordClass
    {
        Application objApp = null;
        Document objDocLast = null;
        Document objDocBeforeLast = null;
        public WordClass()
        {
            objApp = new Application();
        }
        #region 打开文件
        public void Open(string tempDoc)
        {
            object objTempDoc = tempDoc;
            object objMissing = System.Reflection.Missing.Value;
            objApp = new Application();
            objDocLast = objApp.Documents.Open(
               ref objTempDoc, //FileName 
               ref objMissing, //ConfirmVersions 
               ref objMissing, //ReadOnly 
               ref objMissing, //AddToRecentFiles 
               ref objMissing, //PasswordDocument 
               ref objMissing, //PasswordTemplate 
               ref objMissing, //Revert 
               ref objMissing, //WritePasswordDocument 
               ref objMissing, //WritePasswordTemplate 
               ref objMissing, //Format 
               ref objMissing, //Enconding 
               ref objMissing, //Visible 
               ref objMissing, //OpenAndRepair 
               ref objMissing, //DocumentDirection 
               ref objMissing, //NoEncodingDialog 
               ref objMissing //XMLTransform 
               );
            objDocLast.Activate();
        }
        #endregion
         
        public void SaveAs(string outDoc)
        {
            object objMissing = System.Reflection.Missing.Value;
            object objOutDoc = outDoc;
            objDocLast.SaveAs(
            ref objOutDoc, //FileName 
            ref objMissing, //FileFormat 
            ref objMissing, //LockComments 
            ref objMissing, //PassWord 
            ref objMissing, //AddToRecentFiles 
            ref objMissing, //WritePassword 
            ref objMissing, //ReadOnlyRecommended 
            ref objMissing, //EmbedTrueTypeFonts 
            ref objMissing, //SaveNativePictureFormat 
            ref objMissing, //SaveFormsData 
            ref objMissing, //SaveAsAOCELetter, 
            ref objMissing, //Encoding 
            ref objMissing, //InsertLineBreaks 
            ref objMissing, //AllowSubstitutions 
            ref objMissing, //LineEnding 
            ref objMissing //AddBiDiMarks 
            );
        }
         
        /// <summary> 
        /// 循环合并多个文件(插入合并文件) 
        /// </summary> 
        /// <param name="tempDoc">模板文件</param> 
        /// <param name="arrCopies">需要合并的文件</param> 
        /// <param name="outDoc">合并后的输出文件</param> 
        public void InsertMerge(string tempDoc, List<string> arrCopies, string outDoc)
        {
            object objMissing = Missing.Value;
            object objFalse = false;
            object confirmConversion = false;
            object link = false;
            object attachment = false;
            try
            {
                //打开模板文件 
                Open(tempDoc);
                foreach (string strCopy in arrCopies)
                {
                    objApp.Selection.InsertFile(
                    strCopy,
                    ref objMissing,
                    ref confirmConversion,
                    ref link,
                    ref attachment
                    );
                }
                //保存到输出文件 
                SaveAs(outDoc);
                foreach (Microsoft.Office.Interop.Word.Document objDocument in objApp.Documents)
                {
                    objDocument.Close(
                    ref objFalse, //SaveChanges 
                    ref objMissing, //OriginalFormat 
                    ref objMissing //RouteDocument 
                    );
                }
            }
            finally
            {
                objApp.Quit(
                ref objMissing, //SaveChanges 
                ref objMissing, //OriginalFormat 
                ref objMissing //RoutDocument 
                );
                objApp = null;
            }
        }
         
        /// <summary>
        /// 将word转换成pdf
        /// </summary>
        /// <param name="sourcePath"></param>
        /// <param name="targetPath"></param>
        /// <returns></returns>
        public bool WordToPDF(string sourcePath, string targetPath)
        {
            bool result = false;
            Microsoft.Office.Interop.Word.Application application = new Microsoft.Office.Interop.Word.Application();
            Microsoft.Office.Interop.Word.Document document = null;
            try
            {
                application.Visible = false;
                document = application.Documents.Open(sourcePath);
                document.ExportAsFixedFormat(targetPath, WdExportFormat.wdExportFormatPDF);
                result = true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                result = false;
            }
            finally
            {
                document.Close();
            }
            return result;
        }
         
    }
}

第四步:添加项目引用(net framework框架可忽略此步) 在实际用的地方,将新建的项目引用进去;

到这里就准备就绪了,进入调用环节;

2.调用

代码如下(示例):

public void netFrameWorkDemo()
        {
            //指定目录
            string path = @"E:\codeSource\WEBCORE\wwwroot\UploadFile\1\2021-03-01\";
            //输出文档时会自动创建
            string outDoc = path+"all.docx";
            //模版word只需要指定一个空word即可,必须要用,不然后面open方法会报错,可根据需要自动生成
            string tempDoc = path+"tempDoc.docx";

            string ttt = path + "问题汇总.docx";
            string ttt2 = path + "问题汇总2.docx";
            //合并word
            List<string> arrCopies = new List<string>();
            arrCopies.Add(ttt);
            arrCopies.Add(ttt2);
            WordClass wc = new WordClass();
            wc.InsertMerge(tempDoc, arrCopies, outDoc);
            //word转成pdf
            string tttpdf = path + "ttt.pdf";//指定输出的文件名
            string ttt2pdf = path + "ttt2.pdf";//指定输出的文件名
            wc.WordToPDF(ttt, tttpdf); 
            wc.WordToPDF(ttt2, ttt2pdf);
        }

二、我使用时出现的bug

错误信息一

无法将类型为“Microsoft.Office.Interop.Excel.ApplicationClass”的 COM 对象强制转换为接口类型“Microsoft.Office.Interop.Excel._Application”。此操作失败的原因是对 IID 为“{000208D5-0000-0000-C000-000000000046}”的接口的 COM 组件调用 QueryInterface 因以下错误而失败: 加载类型库/DLL 时出错。 (异常来自 HRESULT:0x80029C4A (TYPE_E_CANTLOADLIBRARY))。

原因及解决方案

网上搜了很多方法,有很多说法,又是注册表又是重装office的,每人情况都不一定一样,我的是因为之前装了wps又卸载了,重新把wps装上就好了,网上说必须用wps自带的卸载才行(没试过,有试过的可以留言共享下)。

错误信息二

Retrieving the COM class factory for component with CLSID {000209FF-0000-0000-C000-000000000046} failed due to the following error: 80070005 拒绝访问。 (0x80070005 (E_ACCESSDENIED)).

原因及解决方案

第一:这个主要是64位系统的问题,word是32位的组件,所以在正常的系统组件服务里是看不到的(找不到CLSID为000209FF-0000-0000-C000-000000000046),可以通过在运行里面输入 comexp.msc -32 来打开32位的组件服务,在里就能看到excel组件了 第二:只要修改IIS的应用程序池,选择你的项目,点击高级设置,标识改为:LocalSystem 或NetworkServer;

错误信息三

word转pdf时报错 Object reference not set to an instance of an object( 对象引用未设置为对象的实例 )

原因及解决方案

原因是文件夹没有IIS_USERS的权限。给项目文件夹附上权限即可。

<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">

三、总结

这种方法是免费的,缺点还是挺明显的,就是速度很慢,我测试了一个190页的word转成pdf大约月要35秒; 收费的可以使用下 Aspose.word与Aspose.pdf;