jacob+wps文档转pdf 异常文件转换卡死处理

邵兴庆
2023-12-01
package com.xhkjedu.utils;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import com.xhkjedu.config.ConfigKey;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 *功能描述  wps转PDF
 * @author WN
 * @date 2020/9/7
 * @param  * @param null
 * @return
 */
@Slf4j
public class PdfUtil {
    // 文档格式转换组件
    public static final String WORDSERVER_STRING = "KWPS.Application";
    // 幻灯片格式转换组件
    public static final String PPTSERVER_STRING = "KWPP.Application";
    // 表格格式转换组件
    public static final String EXECLSERVER_STRING = "KET.Application";
    private static final int wdFormatPDF = 17;
    private static final int xlTypePDF = 0;
    private static final int ppSaveAsPDF = 32;

    private static String  uploadfolder = ConfigKey.uploadfolder; //文件保存的目录

    public PdfUtil() {
    }

    /**
     * 文档转pdf
     * @Param [srcFilePath, pdfFilePath, fileType]
     * @Author ywx
     * @Date 2020/10/10 16:07
     * @return boolean
     **/
    public static boolean fileToPdf(String srcFilePath, String pdfFilePath, String fileType) throws Exception {
        final boolean[] rtn = {false};
        final String[] processName = {null};
        final ExecutorService exec = Executors.newFixedThreadPool(1);
        Callable<String> call = new Callable<String>() {
            @Override
            public String call() throws Exception {
                //开始执行耗时操作
                if(fileType.equals("doc") || fileType.equals("docx") || fileType.equals("txt")){
                    processName[0] = "wps.exe";
                    rtn[0] = wpsTopdf(srcFilePath,pdfFilePath);
                }else if(fileType.equals("ppt") || fileType.equals("pptx")){
                    processName[0] = "wpp.exe";
                    rtn[0] = pptTopdf(srcFilePath,pdfFilePath);
                }else if(fileType.equals("xls") || fileType.equals("xlsx")){
                    processName[0] = "et.exe";
                    rtn[0] = xlsTopdf(srcFilePath,pdfFilePath);
                }else{
                    rtn[0] = true;
                }
                return "执行完成!";
            }
        };
        try {
            Future<String> future = exec.submit(call);
            future.get(ConfigKey.timeout, TimeUnit.SECONDS); //任务处理超时时间
        } catch (TimeoutException ex) {
            log.error("转换处理超时",ex.getMessage());
            killProc(processName[0]);
            throw new Exception("转换处理超时");
        }
        // 关闭线程池
        exec.shutdown();
        return rtn[0];
    }


    /**
     * @param srcFilePath            文档路径
     * @param pdfFilePath            pdf路径
     * @return void
     * @throws Exception
     * @throws
     * @Description: 文档格式转换 支持 wps、wpt、doc、docx、dot、txt等所有文档格式文件
     * @author JornTang
     * @email 957707261@qq.com
     * @date 2017年9月14日
     */
    public static boolean wpsTopdf(String srcFilePath, String pdfFilePath)
            throws Exception {
// wps com
        ActiveXComponent pptActiveXComponent = null;
        ActiveXComponent workbook = null;
// open thred
        ComThread.InitSTA();
        try {
            pptActiveXComponent = new ActiveXComponent(WORDSERVER_STRING);
            Variant openParams[] = {new Variant(uploadfolder + srcFilePath),
                    new Variant(true), new Variant(true)};
            workbook = pptActiveXComponent.invokeGetComponent("Documents")
                    .invokeGetComponent("Open", openParams);
            workbook.invoke("SaveAs", new Variant[]{new Variant(uploadfolder + pdfFilePath),
                    new Variant(wdFormatPDF)});
        } catch (Exception e) {
            log.error("文档转换pdf失败",e.getMessage());
            throw e;
        } finally {
            if (workbook != null) {
                workbook.invoke("Close");
                workbook.safeRelease();
            }
            if (pptActiveXComponent != null) {
                pptActiveXComponent.invoke("Quit");
                pptActiveXComponent.safeRelease();
            }
// close thred
            ComThread.Release();
        }
        return true;
    }


    /**
     * @param srcFilePath            幻灯片路径
     * @param pdfFilePath            pdf路径
     * @return boolean
     * @throws
     * @Description: 幻灯片格式转换 支持ppt、pps、pptx、ppsx、dps、dpt、pot、uof
     * @author JornTang
     * @date 2017年9月14日
     */
    public static boolean pptTopdf(String srcFilePath, String pdfFilePath) {
        ActiveXComponent pptActiveXComponent = null;
        ActiveXComponent workbook = null;
        boolean readonly = true;
        ComThread.InitSTA();
        try {
            pptActiveXComponent = new ActiveXComponent(PPTSERVER_STRING);
            workbook = pptActiveXComponent.invokeGetComponent("Presentations")
                    .invokeGetComponent(
                            "Open",
                            new Variant[]{new Variant(uploadfolder + srcFilePath),
                                    new Variant(readonly)});
            workbook.invoke("SaveAs", new Variant[]{new Variant(uploadfolder + pdfFilePath),
                    new Variant(ppSaveAsPDF)});
            return true;
        } catch (Exception e) {
            log.error("ppt转pdf失败:"+e.getMessage());
            throw e;
        } finally {
            if (workbook != null) {
                workbook.invoke("Close");
                workbook.safeRelease();
            }
            if (pptActiveXComponent != null) {
                pptActiveXComponent.invoke("Quit");
                pptActiveXComponent.safeRelease();
            }
            ComThread.Release();
        }
    }

    /**
     * @param srcFilePath            幻灯片路径
     * @param pdfFilePath            pdf路径
     * @return boolean
     * @throws
     * @Description: 表格格式转换 支持et、ett、xls、xlsx、xlt、uof、prn、csv
     * @author JornTang
     * @date 2017年9月14日
     */
    public static boolean xlsTopdf(String srcFilePath, String pdfFilePath) {
        ActiveXComponent et = null;
        Dispatch workbook = null;
        ComThread.InitSTA();
        try {
            et = new ActiveXComponent(EXECLSERVER_STRING);
            et.setProperty("Visible", new Variant(false));
            Dispatch workbooks = et.getProperty("Workbooks").toDispatch();
            workbook = Dispatch.invoke(
                    workbooks,
                    "Open",
                    1,
                    new Object[]{(uploadfolder + srcFilePath), Integer.valueOf(xlTypePDF),
                            Boolean.valueOf(true)}, new int[1]).toDispatch();
            Dispatch.call(workbook, "ExportAsFixedFormat", new Object[]{
                    Integer.valueOf(xlTypePDF), (uploadfolder + pdfFilePath)});
           Dispatch.invoke(workbook, "ExportAsFixedFormat", Dispatch.Method, new Object[] { new Variant(0), // PDF格式=0
                    (uploadfolder + pdfFilePath), new Variant(xlTypePDF) // 0=标准 (生成的PDF图片不会变模糊) 1=最小文件
                    // (生成的PDF图片糊的一塌糊涂)
            }, new int[1]);
            return true;
        } catch (Exception e) {
            log.error("excel转换pdf失败",e.getMessage());
            throw e;
        } finally {
            if (workbook != null) {
                Dispatch.call(workbook, "Close");
                workbook.safeRelease();
            }
            if (et != null) {
                et.invoke("Quit");
                et.safeRelease();
            }
            ComThread.Release();
        }

    }

    //杀死进程
    public static void killProc(String processName) {
        log.info("关闭应用程序:" + processName);
        if (StringUtils.isNotBlank(processName)) {
            try {
                executeCmd("taskkill /F /IM " + processName);
                ComThread.Release();
            } catch (IOException e) {
                log.error("杀死进程失败",e.getMessage());
            }
        }
    }

    //执行cmd命令
    public static String executeCmd(String command) throws IOException {
        log.info("Execute command : " + command);
        Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec("cmd /c " + command);
        BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));
        String line = null;
        StringBuilder build = new StringBuilder();
        while ((line = br.readLine()) != null) {
            log.info(line);
            build.append(line);
        }
        return build.toString();
    }
}

 类似资料: