java实现word转pdf

1、使用技术

复制代码
linux:libreoffice
windows:dom4j

2、java代码

java 复制代码
import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.UUID;

@Slf4j
public class WordToPdfUtils {
    private static String OS_NAME = "os.name";

    private static String WINDOWS = "windows";

    private static String DOCX = ".docx";

    private static String PDF = ".pdf";

    private static String TEMP_PATH = "/tmp";


    public static File wordToPdf(MultipartFile inputWord) {
        boolean IS_WINDOWS = System.getProperty(OS_NAME).toLowerCase().contains(WINDOWS);

        File tempWordFile = transferToFile(inputWord);
        File pdfFile;
        try {
            if (IS_WINDOWS) {
                pdfFile = new File(UUID.randomUUID() + PDF);
                winWordToPdf(pdfFile, tempWordFile);
            } else {
                pdfFile = linuxWordToPdf(TEMP_PATH, tempWordFile);
            }
            return pdfFile;
        } finally {
            if (tempWordFile.exists()) {
                tempWordFile.delete();
            }
        }
    }


    public static File wordToPdf(ByteArrayOutputStream outputStream) {
        boolean IS_WINDOWS = System.getProperty(OS_NAME).toLowerCase().contains(WINDOWS);

        File tempWordFile = outputStreamToFile(outputStream, UUID.randomUUID() + PDF);
        File pdfFile;
        try {
            if (IS_WINDOWS) {
                pdfFile = new File(UUID.randomUUID() + PDF);
                winWordToPdf(pdfFile, tempWordFile);
            } else {
                pdfFile = linuxWordToPdf(TEMP_PATH, tempWordFile);
            }
            return pdfFile;
        } finally {
            if (tempWordFile.exists()) {
                tempWordFile.delete();
            }
        }
    }

    public static File outputStreamToFile(OutputStream outputStream, String fileName) {
        File file = new File(fileName);
        try (OutputStream fileOutput = new FileOutputStream(file)) {
            // 将数据从ByteArrayOutputStream转移到文件输出流
            ((ByteArrayOutputStream) outputStream).writeTo(fileOutput);
            return file;
        } catch (IOException e) {
            log.error("outputStreamToFile error", e);
            return null;
        }
    }

    public static MultipartFile convert(File file) throws IOException {
        FileInputStream fi = new FileInputStream(file);
        return new MockMultipartFile("file",file.getName(), null, fi);
    }

    /**
     * windows系统word转pdf
     *
     * @param pdfFile  转换后的pdf文件
     * @param wordFile word源文件
     */
    public static void winWordToPdf(File pdfFile, File wordFile) {
        IConverter converter = LocalConverter.builder().build();
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            fileInputStream = new FileInputStream(wordFile);
            fileOutputStream = new FileOutputStream(pdfFile);
            converter.convert(fileInputStream)
                    .as(DocumentType.DOCX)
                    .to(fileOutputStream)
                    .as(DocumentType.PDF).execute();
        } catch (FileNotFoundException fileNotFoundException) {
            throw new ResultException(GlobalCodeEnum.WORD2PDF_ERROR, "文件不存在");
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 创建具有唯一性的临时文件
     *
     * @param originalFilename 原始文件名
     * @return 创建好的临时文件对象
     * @throws IOException 如果创建临时文件过程中出现IO异常
     */
    private static File createUniqueTempFile(String originalFilename) throws IOException {
        String uniqueIdentifier = UUID.randomUUID().toString() + System.nanoTime();
        return File.createTempFile("temp-" + uniqueIdentifier + "-", "-" + originalFilename);
    }

    /**
     * 根据原始Word文件名生成对应的PDF文件名
     *
     * @param wordFileName Word文件名
     * @return PDF文件名
     */
    private static String getPdfFileName(String wordFileName) {
        return wordFileName.replaceFirst("[.][^.]+$", ".pdf");
    }

    /**
     * 设置PDF文件的HTTP响应头信息
     *
     * @param response         HTTP响应对象
     * @param originalFilename 原始文件名
     */
    private static void setPdfResponseHeaders(HttpServletResponse response, String originalFilename) {
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(getPdfFileName(originalFilename)) + "\"");
    }

    /**
     * linux系统word转pdf
     * 使用LibreOffice转换。系统需安装LibreOffice
     * 转换命令 libreoffice --invisible --convert-to pdf --outdir output_dir source_path
     * 转换后的pdf文件名使用的是源文件的名称,所以如果要指定输出文件名称,就需把源文件名称改成想要输出的名称
     *
     * @param wordFile word源文件
     */
    public static File linuxWordToPdf(String outPutPath, File wordFile) {
        try {
            // 构建LibreOffice的下一行工具命令
            String command = "libreoffice --headless --invisible --convert-to pdf:writer_pdf_Export " + wordFile.getAbsolutePath() + "  --outdir " + outPutPath;
            log.info(command);

            // 执行转换命令
            if (executeLinuxCmd(command)) {
                return new File(outPutPath + File.separator + wordFile.getName().split("\\.")[0] + "." + wordFile.getName().split("\\.")[1]);
            }
            return null;
        } catch (Exception e) {
            log.error("linuxWordToPdf linux环境word转换为pdf时出现异常!", e);
            return null;
        }
    }

    /**
     * 执行命令行
     *
     * @param command 命令行
     * @return
     */
    private static boolean executeLinuxCmd(String command) throws IOException, InterruptedException {
        // 使用Java的ProcessBuilder来执行Linux命令
        ProcessBuilder processBuilder = new ProcessBuilder("/bin/bash", "-c", command);
        Process process = processBuilder.start();

        // 等待命令执行完成,并获取输出和错误流信息
        int exitCode = process.waitFor();
        if (exitCode != 0) {
            log.error("执行命令 {} 失败,退出码:{}", command, exitCode);
            return false;
        }
        return true;
    }

    private static File transferToFile(MultipartFile multipartFile) {
        String path = UUID.randomUUID() + DOCX;
        File file = new File(path);
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            FileCopyUtils.copy(multipartFile.getBytes(), file);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return file;
    }


}

3、libreoffice

下载 LibreOffice | LibreOffice 简体中文官方网站 - 自由免费的办公套件

linux安装

java 复制代码
#libreoffice的安装步骤

#1.先将libreoffice的rpm文件上传至服务器
#2.将rpm压缩包解压到/opt目录下
tar -zxvf /tmp/LibreOffice_24.8.1_Linux_x86-64_rpm.tar.gz -C /opt/libreoffice
#3.进入解压目录
cd /opt/libreoffice/LibreOffice_24.8.1.2_Linux_x86-64_rpm/RPMS
#4.安装rpm包
yum localinstall *.rpm
#5.检查是否安装完成
libreoffice24.8 --version

dockerfile示例

java 复制代码
FROM xxx/library/xxx-jdk17:1.0
USER 0
RUN mkdir -p /testdata/logs \
&& mkdir /usr/finance-lease \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

RUN cd /testdata && curl -O https://arthas.aliyun.com/arthas-boot.jar

# 切换 Rocky Linux 的 dnf 源为阿里云镜像源
RUN sed -i 's|^mirrorlist=|#mirrorlist=|g' /etc/yum.repos.d/rocky.repo && \
    sed -i 's|^#baseurl=http://dl.rockylinux.org|baseurl=http://mirrors.cloud.aliyuncs.com|g' /etc/yum.repos.d/rocky.repo && \
    dnf clean all && dnf makecache


# 判断是否为 Linux 系统,如果是则安装 LibreOffice
RUN if [ -f /etc/os-release ]; then \
        if [ -x /usr/bin/apt-get ]; then \
            apt-get update && apt-get install -y libreoffice; \
        elif [ -x /usr/bin/yum ]; then \
            yum update -y && yum install -y libreoffice; \
        elif [ -x /usr/bin/dnf ]; then \
            dnf update -y && dnf install -y libreoffice; \
        elif [ -x /usr/bin/zypper ]; then \
            zypper refresh && zypper install -y libreoffice; \
        elif [ -x /usr/bin/pacman ]; then \
            pacman -Syu --noconfirm libreoffice; \
        elif [ -x /usr/bin/apk ]; then \
            apk add --no-cache libreoffice; \
        else \
            echo "Unrecognized package manager, skipping LibreOffice installation"; \
        fi; \
    else \
        echo "Not a Linux-based system, skipping LibreOffice installation"; \
    fi

COPY ../entrypoint.sh /usr/finance-lease/entrypoint.sh
COPY ./finance-lease-business/target/financelease.jar /usr/finance-lease/financelease.jar
EXPOSE 8097
EXPOSE 10091
ENTRYPOINT ["/bin/bash", "/usr/finance-lease/entrypoint.sh"]

4、使用示例

             //获取文件输入流信息
            URL url = new URL(fileInfo.getOssFullPath());
            inputStream = url.openConnection().getInputStream();
            //注意不能直接使用XWPFDocument,会出现类型转换异常,直接使用子类
            MyXWPFDocument xwpfDocument = new MyXWPFDocument(inputStream);
            //填充合同模板变量值,生成合同文件
            WordExportUtil.exportWord07(xwpfDocument, templateParams);
            xwpfDocument.write(outputStream);
            //转为pdf
            File file = WordToPdfUtils.wordToPdf(outputStream);
相关推荐
d3soft1 小时前
厦大团队:DeepSeek大模型概念、技术与应用实践 140页PDF完整版下载
ai·pdf·教程·deepseek
提拉米苏不吃肉3 小时前
跨平台公式兼容性大模型提示词模板(飞书 + CSDN + Microsoft Word)
microsoft·word·飞书
不学能干嘛8 小时前
写大论文的word版本格式整理,实现自动生成目录、参考文献序号、公式序号、图表序号
word
菜鸟单飞19 小时前
介绍一款非常实用的PDF阅读软件!
windows·pdf·电脑
一川风絮千片雪21 小时前
【排版教程】如何在Word/WPS中优雅的插入参考文献
word·wps
杜大哥21 小时前
如何在WPS打开的word、excel文件中,使用AI?
人工智能·word·excel·wps
青涩小鱼1 天前
在WPS中设置word的页码不从第一页开始,从指定页开始插入页码
word·wps
IDRSolutions_CN1 天前
如何在 PDF 文件中嵌入自定义数据
java·经验分享·pdf·软件工程·团队开发
企鹅侠客2 天前
开源免费文档翻译工具 可支持pdf、word、excel、ppt
人工智能·pdf·word·excel·自动翻译