在文档密集型应用场景中,无论是整合财务报告,还是搭建自动化归档系统,通过 Java 实现 PDF 合并都是一项核心需求。不过,开发人员在处理多来源 PDF 时,常会面临两大难题:一是如何保证不同来源 PDF 的格式完整性,二是如何提升资源利用效率。而 Spire.PDF for Java 提供了一套稳健且简洁的解决方案,能有效简化 PDF 合并流程。
本文将详细介绍 Java 中 PDF 合并的实现方法,并附上实用示例,涵盖多文件完整合并、指定页面精准合并、基于流的动态合并三种核心场景。
快速集成 Spire.PDF for Java
Spire.PDF for Java 的核心优势:
- 无外部依赖:纯 Java 原生实现,无需额外引入其他工具或组件。
- 功能丰富:支持 PDF 合并、拆分、加密和批注等。
- 跨平台兼容:可在 Windows、Linux 和 macOS 上运行。
安装方式
在使用 Spire.PDF for Java 之前,需将其添加到项目中,有以下两种方式:
方式 1:通过 Maven 安装
在项目的 pom.xml 文件中,添加如下仓库配置与依赖信息:
<repositories>
<repository>
<id>com.e-iceblue</id>
<name>e-iceblue</name>
<url>https://repo.e-iceblue.cn/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.pdf</artifactId>
<version>11.8.3</version>
</dependency>
</dependencies>
方式 2:手动添加 JAR 包
从 E-iceblue 官网下载 JAR 包,然后将其添加到项目中。
Java 合并多个 PDF 文件
此示例适用于需要将两个或多个 PDF 文档完整合并的场景,操作简单直接,非常适合批量处理。
核心步骤:
- 定义文件路径:创建字符串数组,存储所有待合并 PDF 的完整路径。
- 合并文件:调用 mergeFiles() 方法,传入文件路径数组,该方法会自动合并所有 PDF,并返回代表合并结果的 PdfDocumentBase 对象。
- 保存结果:通过 save() 方法,将合并后的 PDF 保存为新文件。
示例代码:
import com.spire.pdf.FileFormat;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfDocumentBase;
public class MergePdfs {
public static void main(String[] args) {
// 获取待合并的PDF文档路径
String[] files = new String[] {"Sample1.pdf", "Sample2.pdf", "Sample3.pdf"};
// 合并这些PDF文档
PdfDocumentBase pdf = PdfDocument.mergeFiles(files);
// 保存合并后的PDF文件
pdf.save("合并PDF文档.pdf", FileFormat.PDF);
}
}
适用场景
- 需合并本地存储的完整 PDF 文件时。
- 无需筛选页面,仅需批量合并文档的场景。
合并结果: 将 3 个 PDF 文件(共 9 页)合并为 1 个 PDF 文件。
Java 合并多个 PDF 的指定页面
实际开发中,有时无需合并完整文档,仅需提取不同 PDF 的指定页面(例如:从文件 A 提取 1-3 页、从文件 B 提取 2-5 页)。该示例可帮助开发人员精准控制每个源 PDF 中需合并的页面。
核心步骤:
- 加载 PDF 文件:将每个源 PDF 文件加载到 PdfDocument 对象中,并存储在一个数组中。
- 创建新 PDF 文件:初始化一个空的 PDF 文档,作为合并后页面的存储载体。
- 插入指定页面:
- insertPage():将单个指定页面插入到新 PDF 中。
- insertPageRange():将指定页面范围插入到新 PDF 中。
- 保存结果:使用 saveToFile() 方法保存合并后的 PDF 文件。
示例代码:
import com.spire.pdf.PdfDocument;
public class MergeSelectedPages {
public static void main(String[] args) {
// 获取待合并的PDF文档路径
String[] files = new String[] {"Sample1.pdf", "Sample2.pdf", "Sample3.pdf"};
// 创建PdfDocument类型的数组
PdfDocument[] pdfs = new PdfDocument[files.length];
// 遍历文档数组
for (int i = 0; i < files.length; i++)
{
// 加载指定的PDF文档
pdfs[i] = new PdfDocument(files[i]);
}
// 创建一个新的PDF文档
PdfDocument pdf = new PdfDocument();
// 将不同PDF中的指定页面插入到新PDF中
pdf.insertPage(pdfs[0], 0);
pdf.insertPageRange(pdfs[1], 1, 3);
pdf.insertPage(pdfs[2], 0);
// 保存合并后的PDF文件
pdf.saveToFile("合并指定页面.pdf");
}
}
适用场景
- 自定义 PDF 组合(如报告摘要、章节提取)
- 排除源文件中无关页面(如删除空白页、冗余封面)
合并结果: 将 3 个不同 PDF 文件中的指定页面合并为一个新的 PDF 文件。
Java 合并 PDF 文件流
部分应用场景中,PDF 并非以本地文件形式存储(例如:从网络流获取的 PDF、内存中动态生成的 PDF、临时缓存的 PDF)。针对这类情况,Spire.PDF 支持直接通过流完成合并。
核心步骤:
- 创建输入流:通过 FileInputStream 对象读取每个 PDF 文件的原始字节数据。
- 合并流:调用 mergeFiles () 方法,传入输入流数组,该方法会合并所有流数据,并返回PdfDocumentBase对象。
- 保存与资源清理:保存合并后的 PDF 文件,同时关闭所有流和文档对象(这对防止资源泄漏至关重要)。
示例代码:
import com.spire.pdf.*;
import java.io.*;
public class mergePdfsByStream {
public static void main(String[] args) throws IOException {
// 为每个PDF文档创建对应的FileInputStream对象
FileInputStream stream1 = new FileInputStream(new File("Template_1.pdf"));
FileInputStream stream2 = new FileInputStream(new File("Template_2.pdf"));
FileInputStream stream3 = new FileInputStream(new File("Template_3.pdf"));
// 初始化InputStream数组,统一管理所有文件输入流
InputStream[] streams = new FileInputStream[]{stream1, stream2, stream3};
// 将输入流合并为单个PdfDocumentBase对象
PdfDocumentBase pdf = PdfDocument.mergeFiles(streams);
// 保存合并后的PDF文件
pdf.save("MergePdfsByStream.pdf", FileFormat.PDF);
// 释放合并后文档占用的系统资源
pdf.close();
pdf.dispose();
// 关闭所有输入流,避免资源泄漏
stream1.close();
stream2.close();
stream3.close();
}
}
适用场景
- 合并非文件来源的 PDF(例如,网络下载的 PDF、内存中生成的 PDF)
- 无法直接访问文件路径的环境
结论
Spire.PDF for Java 通过直观、易用的 API 简化了复杂的 PDF 合并任务。无论您需要合并完整文档、创建自定义页面序列,还是合并来自流数据源的 PDF,本文中的示例都能帮助您在 Java 中高效实现 PDF 合并,以满足各种文档处理需求。
如需探索更多进阶功能(如加密合并后的 PDF、添加书签等),请参考官方文档。
常见问题(FAQ)
Q1:为何合并后的 PDF 会有红色水印?
答:这是商业版本的默认特性(会自动添加水印),可通过以下方式解决:
- 申请 30 天试用许可证,获取无限制测试权限。
- 使用免费版本,该版本适用于页数≤10 页的 PDF 文档。
Q2:如何控制合并后的 PDF 页面顺序?
答:合并后 PDF 的页面顺序由两大因素决定:输入文件(或流)的顺序、您选择的页面范围。具体示例如下:
- 完整文档合并时:输入数组中文件的顺序,即为合并后页面的顺序。
- 选择性页面合并时:按预期的页面顺序调用 insertPage() 或 insertPageRange() 方法即可。
Q3:能否合并受密码保护的 PDF?
答:可以。Spire.PDF for Java 支持合并加密的 PDF,但加载文件时必须传入正确密码。可使用带密码参数的 loadFromFile() 重载方法:
PdfDocument pdf = new PdfDocument();
pdf.loadFromFile("sample.pdf", "userPassword"); // 输入密码解密
Q4:如何合并扫描件(或基于图像)的 PDF?
A:Spire.PDF 处理图像类 PDF 的逻辑与普通 PDF 一致,但需注意:合并后文件的体积可能会显著增大(因图像数据占用空间较多)。