2023.12.5 更新
项目运行中发现,引入了org.apache.poi太多的包,导致内部有依赖冲突且很不好排查,修改后直接使用aspose-words的包就能实现word转换pdf
更新后的pom依赖

<dependency>
    <groupId>com.luhuiguo</groupId>
    <artifactId>aspose-words</artifactId>
    <version>23.1</version>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.5</version>
</dependency>

核心代码:

import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

public class WordToPdf {
    public static File docToPdf(String docPath, String pdfPath) {
        System.out.println("WORD转化PDF开始>>>>");  //转化用时
        File pdfFile = new File(pdfPath);
        try {
            long old = System.currentTimeMillis();
            String s = "<License><Data><Products><Product>Aspose.Total for Java</Product><Product>Aspose.Words for Java</Product></Products><EditionType>Enterprise</EditionType><SubscriptionExpiry>20991231</SubscriptionExpiry><LicenseExpiry>20991231</LicenseExpiry><SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber></Data><Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature></License>";
            ByteArrayInputStream is = new ByteArrayInputStream(s.getBytes());
            License license = new License();
            license.setLicense(is);
            Document document = new Document(docPath);
            FileOutputStream outputStream = new FileOutputStream(pdfFile);
            document.save(outputStream, SaveFormat.PDF);
            long now = System.currentTimeMillis();
            outputStream.close();
            is.close();
            System.out.println("WORD转化PDF共耗时:" + ((now - old) / 1000.0) + "秒");  //转化用时
        } catch (Exception e) {
            System.out.println("转化失败");
            e.printStackTrace();
        }
        return pdfFile;
    }

    public static File docToPdf(InputStream docPathInputStream, String pdfPath) {
        File pdfFile = new File(pdfPath);
        try {
            long old = System.currentTimeMillis();
            String s = "<License><Data><Products><Product>Aspose.Total for Java</Product><Product>Aspose.Words for Java</Product></Products><EditionType>Enterprise</EditionType><SubscriptionExpiry>20991231</SubscriptionExpiry><LicenseExpiry>20991231</LicenseExpiry><SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber></Data><Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature></License>";
            ByteArrayInputStream is = new ByteArrayInputStream(s.getBytes());
            License license = new License();
            license.setLicense(is);
            Document document = new Document(docPathInputStream);
            FileOutputStream outputStream = new FileOutputStream(pdfFile);
            document.save(outputStream, SaveFormat.PDF);
            long now = System.currentTimeMillis();
            outputStream.close();
            is.close();
            System.out.println("WORD转化PDF共耗时:" + ((now - old) / 1000.0) + "秒");  //转化用时
        } catch (Exception e) {
            System.out.println("转化失败");
            e.printStackTrace();
        }

        return pdfFile;
    }

    public static void main(String[] args) {
        String docPath = "F:\\Users\\test\\Desktop\\test.docx";
        String pdfPath = "F:\\Users\\test\\Desktop\\test-convert.pdf";
        docToPdf(docPath,pdfPath);

    }
}

之前的版本

最近做的一个项目中需要对接上上签实现自动签章和骑缝章的功能,但是用户这边的合同有docx也有pdf,而上上签只能对接pdf的格式,于是找了很多方法,不是表格转换有问题,就是图片转换有问题,要么就是格式上有点失真,最后找到一个比较完美的方案,记录一下,后台是springboot,文件涉及到公司机密就没有效果展示了。

<dependency>
    <groupId>com.luhuiguo</groupId>
    <artifactId>aspose-words</artifactId>
    <version>23.1</version>
</dependency>
<!--  poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.0</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.0</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>5.2.0</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-excelant</artifactId>
    <version>5.2.0</version>
</dependency>
<!-- itextpdf -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13.2</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.5</version>
</dependency>

核心代码

import cn.hutool.core.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * @author fhey
 * @date 2023-04-20 11:15:58
 * @description: 文件工具类
 */
public class FileUtil {
    private static final Logger logger = LoggerFactory.getLogger(FileUtil.class);

    //获取新文件的全路径
    public static String getNewFileFullPath(String sourceFilePath, String destFilePath, String ext) {
        File destFile = new File(destFilePath);
        if (destFile.isFile()) {
            return destFilePath;
        }
        File sourceFile = new File(sourceFilePath);
        String sourceFileName = sourceFile.getName();
        if (sourceFile.isFile()) {
            return destFilePath + File.separator + sourceFileName.substring(0, sourceFileName.lastIndexOf(StrUtil.DOT)) + StrUtil.DOT + ext;
        }
        return destFilePath + File.separator + sourceFileName + StrUtil.DOT + ext;
    }

    //判断文件是否是图片
    public static boolean isImage(File file) throws IOException {
        FileInputStream is = new FileInputStream(file);
        byte[] bytes = new byte[8];
        is.read(bytes);
        is.close();
        String type = bytesToHexString(bytes).toUpperCase();
        if (type.contains("FFD8FF") //JPEG(jpg)
                || type.contains("89504E47") //PNG
                || type.contains("47494638") //GIF
                || type.contains("49492A00") //TIFF(tif)
                || type.contains("424D") //Bitmap(bmp)
        ) {
            return true;
        }
        return false;
    }

    //将文件头转换成16进制字符串
    public static String bytesToHexString(byte[] src) {
        StringBuilder builder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                builder.append(0);
            }
            builder.append(hv);
        }
        return builder.toString();
    }

}

使用示例

public static void wordToPdf(String wordPath, String pdfPath) throws Exception {
        pdfPath = FileUtil.getNewFileFullPath(wordPath, pdfPath, "pdf");
        File file = new File(pdfPath);
        FileOutputStream os = new FileOutputStream(file);
        Document doc = new Document(wordPath);
        doc.save(os, com.aspose.words.SaveFormat.PDF);
    }

    public static void main(String[] args) throws Exception {
        String filepath = "test.docx";
        String outpath = "/tmp";
        wordToPdf(filepath, outpath);
    }