【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);
        }
    }
}
相关推荐
哦虎!26 分钟前
【JavaEE】网络初识
java
for_ever_love__43 分钟前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
程序猿追2 小时前
kotlin-retry 接入鸿蒙后,怎样确认它真的会停止重试
开发语言·kotlin·harmonyos
我是人✓2 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
智能直播2 小时前
网络RTMP拉流不卡顿、声音不同步,一文讲透缓冲区、时间戳
开发语言·ffmpeg·php·音视频·视频编解码
欣栀♡2 小时前
JVM 频繁 Full GC 先看日志括号里的 cause,jstat 的 FGC 在 JDK 8 上会骗人
java·jvm
IT研究室2 小时前
最新计算机毕业设计选题推荐-基于spring boot的葡萄酒文化宣传网站-网站-文档指导-Java-springboot
java·spring boot·课程设计
慧都小项2 小时前
MyEclipse 中创建和测试 JAX-RS REST 接口:从项目配置到 REST Explorer
java·restful·myeclipse·jax-rs
Wang's Blog2 小时前
Java 项目实战: 交友项目 - 入门案例:编写 Dubbo 服务提供者
java·dubbo·交友
墨云安全2 小时前
内网资产无法暴露到公网,怎么做安全检测?2026 年内网渗透测试的落地路径
开发语言·安全·网络安全·渗透测试·php