Java合并PDF文档的三种常用方式总结

God_M 2024-12-09 11:00:15编程技术
402

前言

在现代企业中,文档管理是一项重要的任务,尤其是在需要将多个PDF文件合并成一个文件时。本文将详细介绍如何使用Java代码高效地合并多个PDF文件,包括处理书签、记录日志信息和优化资源使用。通过本文提供的示例代码,读者可以轻松实现这一功能,提高工作效率。

合并PDF

1.pdfbox合并pdf

apache的pdfbox

pom.xml

 <dependency>
     <groupId>org.apache.pdfbox</groupId>
     <artifactId>pdfbox</artifactId>
     <version>2.0.26</version>
 </dependency>

代码示例

// 添加待合并文件
for (ZipUtil.RelativeFile sourcePdf : fileRefers) {
   long time1 = System.currentTimeMillis();
   log.info("开始添加{}, 大小:{}MB, 路径:{}", (++index),
   FileUtils.newFile(sourcePdf.getFilePath()).length() / 1024 / 1024, sourcePdf.getFilePath());
   try (PDDocument document = PDDocument.load(FileUtils.newFile(sourcePdf.getFilePath()), MemoryUsageSetting.setupTempFileOnly());
        ) {
            // 页面大纲(1级)
            String newName = FileUtils.newFile(sourcePdf.getRelativePath()).getName();
            newName = StringUtils.trimToEmpty(newName).replace("." + FilenameUtils.getExtension(newName), "");
            PdfBoxBookmark boxData = new PdfBoxBookmark(newName, totalPage);

            PDDocumentOutline outline = document.getDocumentCatalog().getDocumentOutline();
            if (outline != null) {
                buildBookMark(outline, boxData, totalPage);
            }
            /
            allBookList.add(boxData);

            mergePdf.addSource(sourcePdf.getFilePath());

            // 更新总页码
            totalPage += document.getNumberOfPages();
        } catch (IOException e) {
            e.printStackTrace();
            log.error("合并pdf失败:{}",e);
            throw new BaseException("文件不存在:" + sourcePdf.getFilePath());
        }
        log.info("结束添加,添加后,总{}页:{},耗费:{}秒",totalPage,
                sourcePdf.getFilePath(), (System.currentTimeMillis() - time1) / 1000);
    }

    // 设置合并后的pdf文件路径
    mergePdf.setDestinationFileName(destFilePath);

    // 合并pdf
    try {
        mergePdf.setDocumentMergeMode(PDFMergerUtility.DocumentMergeMode.OPTIMIZE_RESOURCES_MODE);
        mergePdf.mergeDocuments(MemoryUsageSetting.setupTempFileOnly());
    } catch (IOException e) {
        e.printStackTrace();
        throw new BaseException("合并发生异常");
    }

2.spire.pdf

e-iceblue的spire.pdf

pom.xml

<dependency>
    <groupId>e-iceblue</groupId>
    <artifactId>spire.pdf</artifactId>
    <version>9.5.6</version>
</dependency>

代码示例:

String[] files = new String[] {
                "C:\\Users\\test\\Desktop\\tmp\\001\\20241014-001\\error-file.pdf",
                "C:\\Users\\test\\Desktop\\tmp\\001\\20241014-001\\111.pdf"};

//Merge documents and return an object of PdfDocumentBase
PdfDocumentBase pdf = PdfDocument.mergeFiles(files);

//Save the result to a PDF file
pdf.save("C:\\Users\\test\\Desktop\\tmp\\001\\20241014-001\\MergedPDF222.pdf", FileFormat.PDF);

3.itextpdf

itextpdf

pom.xml

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13.4</version>
</dependency>

代码示例:

String[] pdfs = new String[] {
                "C:\\Users\\test\\Desktop\\tmp\\001\\20241014-001\\0001.pdf",
                "C:\\Users\\test\\Desktop\\tmp\\001\\20241014-001\\0002.pdf"};

String outputPdf = "C:\\Users\\test\\Desktop\\tmp\\001\\20241014-001\\MergedPDF333-.pdf"; // 合并后的PDF文件

try {
    Document document = new Document();
    PdfCopy copy = new PdfCopy(document, new FileOutputStream(outputPdf));
    document.open();

    for (String pdf : pdfs) {
        PdfReader reader = new PdfReader(pdf);
        for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            document.newPage();
            copy.addPage(copy.getImportedPage(reader, i));
        }
        reader.close();
    }

    document.close();
    System.out.println("PDFs merged successfully.");
} catch (Exception e) {
    e.printStackTrace();
}

总结

1.apache的pdfbox和itextpdf是免费的,e-iceblue的spire.pdf是收费的而且价格不菲,无授权会有水印,虽然e-iceblue有免费的spire.pdf.free但有页数限制。

2.apache的pdfbox和e-iceblue的spire.pdf对pdf文档的容错不高,如果pdf文档是通过三方软件生成或编辑过的(可能会存在一定问题,但是浏览器打开或wps打开会容错显示),在合并时会抛文档的异常。但是itextpdf会进行容错修复并合并成功。

所以个人推荐使用itextpdf。

Java 合并pdf
THE END
蜜芽
故事不长,也不难讲,四字概括,毫无意义。

相关推荐

Java日志管理框架:Log4j、SLF4J、Logback对比与使用方法详解
java主流日志框架中,Log4j 1.x作为早期标准,Log4j 2.x通过重构实现性能飞跃,Logback作为Log4j的继承者以原生SLF4J支持成为主流选择,而SLF4J作为日志门面,通过抽象层实现...
2025-09-15 编程技术
533

Java 与 MySQL 性能优化:MySQL全文检索查询优化实践
本文聚焦Java与MySQL协同环境下的全文检索优化实践,从索引策略、查询调优、参数配置到Java层优化,深入解析如何释放全文检索的潜力,为高并发、大数据量场景提供稳定高效的搜...
2025-09-13 编程技术
512

JavaScript 中 instanceof 的作用及使用方法详解
在 JavaScript 的类型检查体系中,instanceof 是一个重要的操作符,用于判断一个对象是否属于某个构造函数的实例或其原型链上的类型。本文ZHANID工具网将系统讲解 instanceof...
2025-09-11 编程技术
503

Java与MySQL数据库连接实战:JDBC使用教程
JDBC(Java Database Connectivity)作为Java标准API,为开发者提供了统一的数据访问接口,使得Java程序能够无缝连接各类关系型数据库。本文ZHANID工具网将以MySQL数据库为例...
2025-09-11 编程技术
498

JavaScript出现“undefined is not a function”错误的解决方法
在JavaScript开发中,TypeError: undefined is not a function 是最常见的运行时错误之一,通常表示代码尝试调用一个未定义(undefined)的值作为函数。本文ZHANID工具网将从...
2025-09-10 编程技术
518

Java集合框架:List、Set、Map的使用与区别详解
Java集合框架是JDK中提供的核心数据结构库,为开发者提供了高效、安全、可扩展的集合操作能力。本文ZHANID工具网将系统解析List、Set、Map三大核心接口的实现类及其使用场景,...
2025-09-09 编程技术
481