【Java】多pdf文件合并为一个.docx文件

当将多个 PDF 文件合并成单个 DOCX 文档时,利用 Java 中的 Apache PDFBox 和 Apache POI 库可以实现这一目标。这个过程可以分为几个步骤:

1. 导入所需的库

使用 Apache PDFBox 和 Apache POI 库来处理 PDF 和 DOCX 文件。你需要导入相关库,并确保在项目中使用了正确的依赖。

go 复制代码
<dependency>
     <groupId>org.apache.pdfbox</groupId>
     <artifactId>pdfbox</artifactId>
     <version>2.0.29</version>
</dependency>

2. 获取PDF文件列表

通过指定文件夹路径,遍历文件夹中的所有 PDF 文件,并将其存储在一个列表中。

3. 创建DOCX文档对象

使用 Apache POI 的 XWPFDocument 类创建一个新的空白 DOCX 文档对象。

4. 逐个处理PDF文件

对于每个 PDF 文件:

  • 使用 PDFBox 的 PDDocument 加载 PDF 文件。
  • 遍历 PDF 文件的每一页,将每一页渲染为图像(PNG 格式)。
  • 将图像插入到 DOCX 文档中对应的段落中,并保留文件名作为文字内容。
  • 创建一个空的XWPFDocument对象,即将用于存储合并后的文档内容。

5. 将结果保存为DOCX文件

最后,将生成的 DOCX 文档保存到指定的输出路径。

java 复制代码
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;

public class MergePDFsToDOCX {

    public static void main(String[] args) {
        String pdfFolderPath = "\\mergePdfsTODocument"; // 替换为包含PDF文件的文件夹路径
        String outputDOCXPath = "\\mergePdfsTODocument\\document.docx"; // 输出的DOCX文件路径

        try {
            List<File> pdfFiles = getPdfFilesInFolder(pdfFolderPath);
            mergePDFsToDocx(pdfFiles, outputDOCXPath);
            System.out.println("PDFs merged to DOCX successfully: " + outputDOCXPath);
        } catch (IOException e) {
            System.err.println("Failed to merge PDFs to DOCX.");
            e.printStackTrace();
        }
    }

    public static List<File> getPdfFilesInFolder(String folderPath) {
        File folder = new File(folderPath);
        List<File> pdfFiles = new ArrayList<>();

        if (folder.exists() && folder.isDirectory()) {
            File[] files = folder.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isFile() && file.getName().toLowerCase().endsWith(".pdf")) {
                        pdfFiles.add(file);
                    }
                }
            }
        } else {
            System.err.println("Folder not found: " + folderPath);
        }
        return pdfFiles;
    }

    public static void mergePDFsToDocx(List<File> pdfFiles, String outputDOCXPath) throws IOException {
        XWPFDocument doc = new XWPFDocument();

        for (File pdfFile : pdfFiles) {
            try (PDDocument pdf = PDDocument.load(pdfFile)) {
                PDFRenderer pdfRenderer = new PDFRenderer(pdf);
                int numPages = pdf.getNumberOfPages();

                for (int pageIndex = 0; pageIndex < numPages; pageIndex++) {
                    BufferedImage bim = pdfRenderer.renderImageWithDPI(pageIndex, 300); // 渲染PDF页面为图像
                    String imgFileName = pdfFile.getName() + "_page_" + (pageIndex + 1) + ".png"; // 图像文件名
                    File imageFile = new File(imgFileName);

                    ImageIO.write(bim, "png", imageFile); // 将图像写入文件

                    FileInputStream imageStream = new FileInputStream(imageFile);
                    XWPFParagraph paragraph = doc.createParagraph();
                    XWPFRun run = paragraph.createRun();
                    run.setText(pdfFile.getName());
                    run.addBreak();

                    doc.createParagraph().createRun().addPicture(
                            imageStream, Document.PICTURE_TYPE_PNG, imgFileName, Units.toEMU(400), Units.toEMU(400));

                    imageStream.close();
                    imageFile.delete(); // 删除临时图像文件
                }
            } catch (IOException e) {
                System.err.println("Failed to process file: " + pdfFile.getName());
                e.printStackTrace();
            } catch (InvalidFormatException e) {
                throw new RuntimeException(e);
            }
        }

        try (FileOutputStream fos = new FileOutputStream(outputDOCXPath)) {
            doc.write(fos);
        }
    }
}
相关推荐
AI你一生一世9 分钟前
不止于时序存储:DolphinDB 如何成为 AI 时代的工业智能底座
java·人工智能·struts·时序数据库·工业智能·dolphindb·ai基础设施
布莱克60514 分钟前
C/C++ 中变量的声明与定义:区别、联系与常见误区
c语言·开发语言·c++·声明·定义
云-缩影20 分钟前
拆解 AI 图像生成应用的后端架构:ECS、OSS 和大模型 API 怎么配合
java·spring boot·后端
LabVIEW开发23 分钟前
LabVIEW 局部变量为何引发竞争条件?四种同步机制
开发语言·labview
瑞克-桑切斯42 分钟前
7、MySQL 慢查询排查与优化实战指南
java·服务器·数据库
benchmark_cc1 小时前
A 股、港股、美股如何建立统一的标的主数据格式?
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
Zenova EdgeOS2 小时前
Go 工业边缘错误处理实战:用 errors 构建可追溯错误链
开发语言·数据库·golang
取名真是2 小时前
Python 算法知识点从基础到进阶
开发语言·python·算法
FRing033 小时前
vue2干货总结3(computed计算属性、watch监听器)
开发语言·前端·vue.js·vue2
Fatbobman(东坡肘子)4 小时前
快速消失的硬盘容量 -- 肘子的 Swift 周报 #160
开发语言·人工智能·redis·ios·swiftui·iphone·swift