java实现图片、word、pdf等多文件融合到一个pdf(word转pdf)

本文主要介绍了srpingboot如何将 jpg、jpeg、png、pdf、docx、doc六种格式文件合并输出成一个pdf文件以及word文档如何转换为pdf,关键是开源免费
在日常工作学习中免不了会涉及到将多种格式的文件合并为一个pdf或者是将word文档、ppt、excel等转换为pdf。废话不多说,直接上代码

一、使用 PDFBox 合并多种格式文件成 PDF 文件

1.添加依赖

在 pom.xml 文件中添加 PDFBox 的依赖:

<dependency>
  <groupId>org.apache.pdfbox</groupId>
  <artifactId>pdfbox</artifactId>
  <version>2.0.24</version>
</dependency>
 <dependency>
    <groupId>org.apache.directory.studio</groupId>
    <artifactId>org.apache.commons.io</artifactId>
    <version>2.4</version>
</dependency>
<dependency>
   <groupId>commons-io</groupId>
   <artifactId>commons-io</artifactId>
   <version>2.7</version>
</dependency>
<dependency>
   <groupId>cn.hutool</groupId>
   <artifactId>hutool-all</artifactId>
   <version>5.7.12</version>
</dependency>

2.实现代码

在 Spring Boot 项目中,新建一个类 MergeFilesToPDFUtil,并添加如下代码:

import org.apache.commons.io.FileUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.jodconverter.DocumentConverter;
import org.jodconverter.document.DefaultDocumentFormatRegistry;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;


/**
 * @ClassName MergeFilesToPDFUtil
 * @Description
 * @Author hzy
 * @Date 2023/4/6 10:56
 **/
public class MergeFilesToPDFUtil {
    
    

    @Resource
    public DocumentConverter documentConverter;


    /**
     *
     * @param fileNames 需要转换的文件列表(需带文件路径)
     * @param outputFile 输出文件路径 如:/test/output.pdf
     */
    public String generatePdf(List<String> fileNames, String outputFile) {
    
    
        List<InputStream> inputStreams = new ArrayList<>();
        List<PDDocument> pdDocuments = new ArrayList<>();
        List<PDDocument> pdfdocuments = new ArrayList<>();
        //生成临时文件的路径
        String url = "/home/tempFile/";

        try {
    
    
            File file = new File(outputFile);
            if (!file.exists()) {
    
    
                if (!file.getParentFile().exists()) {
    
    
                    file.getParentFile().mkdirs();
                }
                file.createNewFile();
            }
            // 创建一个空的pdf文档
            PDDocument document = new PDDocument();
            // 依次读取要合并的各个文件,并将其内容添加到pdf文档中
            for (String fileName : fileNames) {
    
    
                String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1);
                //读取jpg、jpeg、png格式的文件
                if (fileExt.equalsIgnoreCase("jpg") || fileExt.equalsIgnoreCase("jpeg")
                        || fileExt.equalsIgnoreCase("png")) {
    
    
                    PDImageXObject image = PDImageXObject.createFromFile(fileName, document);
                    PDPage page = new PDPage(new PDRectangle(image.getWidth(), image.getHeight()));
                    document.addPage(page);
                    try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
    
    
                        contentStream.drawImage(image, 0, 0);
                    }
                } else if (fileExt.equalsIgnoreCase("pdf")) {
    
    
                    PDDocument pdf = PDDocument.load(new File(fileName));
                    for (PDPage page : pdf.getPages()) {
    
    
                        document.addPage(page);
                    }
                    pdfdocuments.add(pdf);
                } else if (fileExt.equalsIgnoreCase("docx") || fileExt.equalsIgnoreCase("doc")) {
    
    
                    String pdfFile = System.currentTimeMillis() + ".pdf";
                    String tempPdfUrl = url + "/" + pdfFile;
                    // 转换word文件为pdf
                    if (fileExt.equalsIgnoreCase("docx")) {
    
    
                        documentConverter.convert(new File(fileName)).as(DefaultDocumentFormatRegistry.DOCX).
                                to(new File(tempPdfUrl)).as(DefaultDocumentFormatRegistry.PDF).execute();
                    } else {
    
    
                        documentConverter.convert(new File(fileName)).as(DefaultDocumentFormatRegistry.DOC)
                                .to(new File(tempPdfUrl)).as(DefaultDocumentFormatRegistry.PDF).execute();
                    }
                    //这里是将转完的pdf添加到新的pdf页面之后
                    PDDocument load = PDDocument.load(new File(tempPdfUrl));
                    for (PDPage page : load.getPages()) {
    
    
                        document.addPage(page);
                    }
                    //将生成的pdf临时文件删除掉
                    FileUtils.forceDelete(new File(tempPdfUrl));
                    pdDocuments.add(load);
                }
            }
            // 将pdf文档保存到本地
            document.save(outputFile);
            document.close();
            return outputFile;
        } catch (FileNotFoundException e) {
    
    
            throw new RuntimeException(e);
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        } catch (Exception e) {
    
    
            throw new RuntimeException(e);
        } finally {
    
    
            closeIo(inputStreams, pdDocuments, pdfdocuments);
        }
    }
    /**
     * 关闭所有的io流
     * @param inputStreams
     * @param pdDocuments
     * @param pdfdocuments
     */
    public static void closeIo(List<InputStream> inputStreams ,List<PDDocument> pdDocuments,List<PDDocument> pdfdocuments){
    
    
        try {
    
    
            Thread.sleep(5000);
            for (InputStream inputStream : inputStreams) {
    
    
                inputStream.close();
            }
            for (PDDocument pdDocument : pdDocuments) {
    
    
                pdDocument.close();
            }
            for (PDDocument pdfdocument : pdfdocuments) {
    
    
                pdfdocument.close();
            }
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}

二、使用 LibreOffice 将word文档转为pdf

注意,本文在添加 Word 文件时,我们使用了 LibreOffice的方法将其转换为 PDF 文件。然后又通过pdfbox进行的合并,如果有更好的方式将word转为pdf那么只需要修改相关代码即可,不用引入libreoffice相关依赖。以下是使用LibreOffice的方式,仅供参考:

1.安装 LibreOffice

首先需要在服务器上安装 LibreOffice。在 Linux 上,可以使用命令行工具安装:

sudo apt-get install libreoffice

在 Windows/mac上,可以从 LibreOffice 官网下载安装程序进行安装。

2.添加依赖

在 pom.xml 文件中添加以下依赖:

<!--jodconverter 核心-->
        <dependency>
            <groupId>org.jodconverter</groupId>
            <artifactId>jodconverter-spring-boot-starter</artifactId>
            <version>4.4.6</version>
        </dependency>
        <!--jodconverter 引用LibreOffice-->
        <dependency>
            <groupId>org.jodconverter</groupId>
            <artifactId>jodconverter-local-lo</artifactId>
            <version>4.4.6</version>
        </dependency>

3.修改配置文件

在application.yml 文件中添加以下配置:

#配置lireoffice
jodconverter:
  local:
    enabled: true
    #libreoffice安装路径
    office-home: /Applications/LibreOffice.app/Contents
    task-execution-timeout: 86400000
    task-queue-timeout: 86400000
    process-timeout: 86400000

三、进行测试

请注意:为方便观看,这里采用使用main方法的形式进行演示,在实际开发过程中 main方法无法调用非静态方法generatePdf,需要使用service进行调用,否则DocumentConverter无法注入

public static void main(String[] args) throws Exception {
    
    
        // 要合并的文件列表
        List<String> fileNames = new ArrayList<>();
        fileNames.add("/test/file1.jpg");
        fileNames.add("/test/file2.jpeg");
        fileNames.add("/test/file3.png");
        fileNames.add("/test/file4.pdf");
        fileNames.add("/test/file5.docx");
        fileNames.add("/test/file6.doc");
        // 输出的pdf文件名
        String outputFile = "/test/output.pdf";
        generatePdf(fileNames,outputFile);
    }

猜你喜欢

转载自blog.csdn.net/weixin_50531218/article/details/129982315