使用Apache PDFBox实现拆分、合并PDF
问题背景
- 如何拆分PDF?
- 如何合并PDF?
- 如何拆分并合并PDF实现去除PDF的某些页?
Apache PDFBox介绍
Apache PDFBox 库是一个开源的 Java 工具,用于处理 PDF 文件。该项目允许创建新的PDF文档,操作 现有文档以及从文档中提取内容的能力。 PDFBox还包括几个命令行实用程序。PDFBox 发布 在 Apache 许可证下,版本 2.0。
也就是说,我们可以使用PDFBox实现拆分、合并PDF。
在maven项目中添加依赖:
<!--PDF操作-->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-app</artifactId>
<version>1.8.10</version>
</dependency>
拆分PDF
我们需实现WPS这种按照范围拆分的拆分规则:
- 参考样例
以下是wiki教程中找到的样例,可以实现按照每页拆分成pdf。
public static void main(String[] args) throws IOException {
//Loading an existing PDF document
File file = new File("C:/PdfBox_Examples/sample.pdf");
PDDocument document = PDDocument.load(file);
//Instantiating Splitter class
Splitter splitter = new Splitter();
//splitting the pages of a PDF document
List<PDDocument> Pages = splitter.split(document);
//Creating an iterator
Iterator<PDDocument> iterator = Pages.listIterator();
//Saving each page as an individual document
int i = 1;
while(iterator.hasNext()) {
PDDocument pd = iterator.next();
pd.save("C:/PdfBox_Examples/sample"+ i++ +".pdf");
}
System.out.println("Multiple PDF’s created");
document.close();
}
org.apache.pdfbox.util.Splitter
类
Splitter
类有三个拆分相关的参数
private int splitAtPage = 1;
private int startPage = -2147483648;
private int endPage = 2147483647;
分别代表拆分的页数范围,开始拆分的页数,结束拆分的页数。
也就是说,我们可以通过实现设置splitter的相关参数(如splitter.setStartPage(12)
等)来实现按照范围拆分的功能。
- 匹配拆分规则
建立SplitterDTO
/**
* Splitter类的配置
*/
@Data
class SplitterDTO {
private int splitAtPage;
private int startPage;
private int endPage;
}
使用正则表达式校验按照范围拆分的拆分规则,将其参数保存在List<SplitterDTO>
中:
// m-n 例如 3-5,拆分第三到第五页的pdf
private static final String ruleOne = "^[1-9]\\d*-[1-9]\\d*$";
// m 例如 7,拆分第七页的pdf
private static final String ruleTwo = "^[1-9]\\d*$";
/**
* 正则校验匹配 拆分规则
* @param splitRule 拆分规则
* @return
*/
private List<SplitterDTO> matchByRegex(String splitRule) {
List<SplitterDTO> result = new ArrayList<>();
String[] splits = splitRule.split(",");
for (String split : splits) {
SplitterDTO dto = new SplitterDTO();
if (split.matches(ruleOne)) {
String[] nums = split.split("-");
dto.setStartPage(Integer.parseInt(nums[0]));
dto.setEndPage(Integer.parseInt(nums[1]));
// 拆分的长度
dto.setSplitAtPage(dto.getEndPage() - dto.getStartPage() + 1);
result.add(dto);
} else if (split.matches(ruleTwo)) {
dto.setStartPage(Integer.parseInt(split));
dto.setEndPage(Integer.parseInt(split));
dto.setSplitAtPage(1);
result.add(dto);
} else {
System.out.println("错误的规则:" + split);
}
}
return result;
}
- 根据拆分规则拆分PDF
根据拆分规则开始拆分PDF并保存为pdf。
/**
* 拆分pdf
* @param sourcePdf 源pdf(路径+文件名+文件后缀)
* @param splitPath 拆分后的文件路径
* @param splitFileName 拆分后的文件名(不含后缀)
* @param splitterDTOS 拆分规则
* @return finalPdfs 最终拆分成的pdf
*/
private List<String> spitPdf(String sourcePdf, String splitPath, String splitFileName, List<SplitterDTO> splitterDTOS) throws IOException, COSVisitorException {
List<String> f