Java Word转PDF 通过jacob DLL(SaveAs)

个人理解和经验,有误的地方,还请指正

1.下载Jacob包。

2.将Jacob包中的Dll放在系统Jdk安装路径的jre->bin。

【如果是Tomcat需要将dll放在Tomcat的bin目录下】

3.正常来说到这一步是可以的(非Tomcat服务启动),

测试代码块:

    /**
     * docx文档转换为PDF
     *
     * @param temDir   PDF文件路径
     * @param wordPath Word路径
     * @param fileName PDF文件名
     * @throws Exception 可能为Docx4JException, FileNotFoundException, IOException等
     */
    public static String convertDocxToPDF(String temDir, String wordPath) throws Exception {
        //temDir PDF文件地址; wordPath Word文件地址 ;fileName PDF文件名
        ActiveXComponent app = null;
        String pdfFile = "";
        InputStream in = null;
        OutputStream out = null;
        // 开始时间
        long start = System.currentTimeMillis();
        try {
            log.info("1");
            ComThread.InitSTA();
            log.info("2");
            // 打开word
            app = new ActiveXComponent("Word.Application");//office
 //           app = new ActiveXComponent("kwps.Application");//wps(未测试过)
            log.info("3");
            // 设置word不可见默认就是不可见的
            //app.setProperty("Visible", false);
            // 获得word中所有打开的文档
            Dispatch documents = app.getProperty("Documents").toDispatch();
            System.out.println("打开文件: " + wordPath);
            // 打开文档
            Dispatch document = Dispatch.call(documents, "Open", wordPath, false, true).toDispatch();
            // 如果文件存在的话,不会覆盖,会直接报错,所以我们需要判断文件是否存在
            pdfFile = temDir;
            File target = new File(pdfFile);
            if (target.exists()) {
                target.delete();
            }
            log.info("4");
            // 另存为,将文档报错为pdf,其中word保存为pdf的格式宏的值是17
            Dispatch.call(document, "SaveAs", pdfFile, 17);
            // 关闭文档
            Dispatch.call(document, "Close", false);
            // 结束时间
            long end = System.currentTimeMillis();
            System.out.println("转换成功,用时:" + (end - start) + "ms");

            log.info("5");
            return pdfFile;
        } catch (Exception e) {
            e.getLocalizedMessage();
            e.printStackTrace();
            e.getMessage();
            e.getCause();
            e.getStackTrace();
            e.getSuppressed();
            System.out.println("转换失败" + e.getMessage());
            System.out.println("转换失败" + e.getLocalizedMessage());
            System.out.println("转换失败" + e.getSuppressed());
            System.out.println("转换失败" + e.getStackTrace());
        } finally {
            // 关闭office
            app.invoke("Quit", 0);
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            ComThread.Release();
//            delTempFile(pdfFile);//
//            delTempFile(wordPath);//
        }
        return pdfFile;
    }

4.如果是Server 2008(我用的是Server 2016)之后的版本并且用Tomcat 通过服务启动程序,则需要以下操作:

(1)因为Server 2008之后好像是取消了COM对象默认的交互方式为“非交互”型,如果是通过 console启动程序不会有问题,但是如果是通过服务的形式启动就会有获取不到dll的问题。报错表现为 “Can't get object clsid from progid”

操作:下载Office(我是用的是2015,但是好像2003之后的到365都可以)或WPS(好像不能是简洁版)软件,操作目的是在系统注册表中生成对应软件的注册表(Office:Microsoft Word 97 - 2003 文档;WPS:WPS文字 文档),将注册表的属性->标识 改为交互式用户

红字部分后续测试发现不是必须的。

【此处的软件和代码中 ActiveXComponent 要保持一致

(2) 同样因为上述原因除了设置交互式用户外,在打开文件时因为文件操作需要一个Desktop文件夹所以需要在指定目录新建文件夹。报错表现为 “VariantChangeType failed”

操作:在 C:\Windows\System32\config\systemprofile 和C:\Windows\SysWOW64\config\systemprofile 目录下分别建 Desktop文件夹。

更新:如果上述步骤还是不行,可以进行以下操作

(1)进入 comexp.msc 编辑 Microsoft Word 97-2003 Document(WPS的是 Microsoft Word 06 - 07 Document ) 属性将安全中的访问权限设置为允许,将标识中的账户设置为启动用户;

注:Tomcat 服务中的账户类型要和该类型一致,即启动用户->本地系统账户;下列用户->此账户;

 

到这一步我碰到的问题就已经解决了,如果后续有新的问题会更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值