首页IT科技怎么把pdf组合文件拆分(使用Apache PDFBox实现拆分、合并PDF)

怎么把pdf组合文件拆分(使用Apache PDFBox实现拆分、合并PDF)

时间2025-06-20 07:54:16分类IT科技浏览4622
导读:使用Apache PDFBox实现拆分、合并PDF 问题背景 如何...

使用Apache PDFBox实现拆分            、合并PDF

问题背景

如何拆分PDF? 如何合并PDF? 如何拆分合并PDF实现去除PDF的某些页?

Apache PDFBox介绍

Apache PDFBox 1.8.10官方文档

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> finalPdfs = new ArrayList<>(); int j = 1; String splitPdf = splitPath + "\\" + splitFileName + "_"; for (SplitterDTO splitterDTO : splitterDTOS) { // Loading an existing PDF document File file = new File(sourcePdf); PDDocument document = PDDocument.load(file); // Instantiating Splitter class Splitter splitter = new Splitter(); splitter.setStartPage(splitterDTO.getStartPage()); splitter.setSplitAtPage(splitterDTO.getSplitAtPage()); splitter.setEndPage(splitterDTO.getEndPage()); // 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 while(iterator.hasNext()) { PDDocument pd = iterator.next(); String pdfName = splitPdf+ j++ +".pdf"; pd.save(pdfName); finalPdfs.add(pdfName); } // System.out.println("Multiple PDF’s created"); document.close(); } return finalPdfs; } 拆分测试 public static void main(String[] args) throws Exception { // 拆分规则:如拆分成1-4                 ,5,以及8三个pdf String splitRule = "1-4,5,8"; String sourcePdf = "D:\\BaiduNetdiskDownload\\test\\测试用pdf.pdf"; // 拆分后pdf所放的文件夹 String splitPath = "D:\\BaiduNetdiskDownload\\test"; // 拆分后的文件名 String splitFileName = UUID.randomUUID().toString().replace("-", ""); /** * 1       、拆分 */ PdfUtils pdfUtils = new PdfUtils(); List<SplitterDTO> splitterDTOS = pdfUtils.matchByRegex(splitRule); List<String> pdfList = pdfUtils.spitPdf(sourcePdf, splitPath, splitFileName, splitterDTOS); System.out.println("pdf文件拆分成功------------"); pdfList.forEach(System.out::println); }

控制台输出结果:

pdf文件拆分成功------------ D:\BaiduNetdiskDownload\test\a5f1b001f2d64a75ac63e75bdb4809e6_1.pdf D:\BaiduNetdiskDownload\test\a5f1b001f2d64a75ac63e75bdb4809e6_2.pdf D:\BaiduNetdiskDownload\test\a5f1b001f2d64a75ac63e75bdb4809e6_3.pdf

对应文件夹生成三个pdf文件:

合并PDF

代码 /** * 合并PDF * @param inputStreams 需合并的pdf文件流 * @param bothPath 合并后的pdf文件路径 * @param destinationFileName 合并后的pdf文件名 */ public static void MergePdf(List<InputStream> inputStreams, String bothPath, String destinationFileName) throws Exception { // org.apache.pdfbox.util.PDFMergerUtility:pdf合并工具类 PDFMergerUtility mergePdf = new PDFMergerUtility(); File file = new File(bothPath); if (!file.exists()) { file.mkdirs(); } mergePdf.addSources(inputStreams); // 设置合并生成pdf文件名称 mergePdf.setDestinationFileName(bothPath + File.separator + destinationFileName); // 合并PDF mergePdf.mergeDocuments(); for (InputStream in : inputStreams) { if (in != null) { in.close(); } } } 合并测试 public static void main(String[] args) throws Exception { /** * 合并 */ // 合并pdf生成的文件名 String destinationFileName = DateUtils.format(new Date()); // 需要合并的PDF文件 List<InputStream> inputStreams = new ArrayList<>(); inputStreams.add(new FileInputStream(new File("D:\\ToPDF\\pdf\\水印冲鸭.pdf"))); inputStreams.add(new FileInputStream(new File("D:\\ToPDF\\pdf\\testtest.pdf"))); // 合并后pdf存放路径 String bothPath = "D:\\ToPDF\\pdf"; MergePdf(inputStreams, bothPath, destinationFileName+"测试合并.pdf"); System.out.println("pdf文件合并成功"); }

控制台输出结果:

pdf文件合并成功

对应文件夹生成合并的pdf文件:

拆分 + 合并

测试代码 public static void main(String[] args) throws Exception { // 拆分规则:如拆分成1-4               ,5                    ,以及8三个pdf String splitRule = "1-4,5,8"; String sourcePdf = "D:\\BaiduNetdiskDownload\\test\\测试用pdf.pdf"; // 拆分后pdf所放的文件夹 String splitPath = "D:\\BaiduNetdiskDownload\\test"; // 拆分后的文件名 String splitFileName = UUID.randomUUID().toString().replace("-", ""); /** * 1         、拆分 */ PdfUtils pdfUtils = new PdfUtils(); List<SplitterDTO> splitterDTOS = pdfUtils.matchByRegex(splitRule); List<String> pdfList = pdfUtils.spitPdf(sourcePdf, splitPath, splitFileName, splitterDTOS); System.out.println("pdf文件拆分成功------------"); pdfList.forEach(System.out::println); /** * 2                   、合并 */ // 合并pdf生成的文件名 String destinationFileName = splitFileName; // 需要合并的PDF文件 List<InputStream> inputStreams = new ArrayList<>(); for (String pdf : pdfList) { inputStreams.add(new FileInputStream(new File(pdf))); } // 合并后pdf存放路径 String bothPath = "D:\\BaiduNetdiskDownload\\test"; MergePdf(inputStreams, bothPath, destinationFileName + "测试合并.pdf"); System.out.println("pdf文件合并成功-----------"

); } 测试结果

控制台输出结果: pdf文件拆分成功------------ D:\BaiduNetdiskDownload\test\a5f1b001f2d64a75ac63e75bdb4809e6_1.pdf D:\BaiduNetdiskDownload\test\a5f1b001f2d64a75ac63e75bdb4809e6_2.pdf D:\BaiduNetdiskDownload\test\a5f1b001f2d64a75ac63e75bdb4809e6_3.pdf pdf文件合并成功-----------

对应文件夹生成拆分后以及合并的pdf文件:

完整代码

package com.example.demo.utils; import lombok.Data; import org.apache.pdfbox.exceptions.COSVisitorException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.util.PDFMergerUtility; import org.apache.pdfbox.util.Splitter; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.*; /** * @Author 似有风中泣 * @Description 操作PDF类 * @Data 2022/6/27 16:18 * @Version 1.0 */ public class PdfUtils { // 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*$"; public static void main(String[] args) throws Exception { // 拆分规则:如拆分成1-4                    ,5       ,以及8三个pdf String splitRule = "1-4,5,8"; String sourcePdf = "D:\\BaiduNetdiskDownload\\test\\测试用pdf.pdf"; // 拆分后pdf所放的文件夹 String splitPath = "D:\\BaiduNetdiskDownload\\test"; // 拆分后的文件名 String splitFileName = UUID.randomUUID().toString().replace("-", ""); /** * 1           、拆分 */ PdfUtils pdfUtils = new PdfUtils(); List<SplitterDTO> splitterDTOS = pdfUtils.matchByRegex(splitRule); List<String> pdfList = pdfUtils.spitPdf(sourcePdf, splitPath, splitFileName, splitterDTOS); System.out.println("pdf文件拆分成功------------"); pdfList.forEach(System.out::println); /** * 2      、合并 */ // 合并pdf生成的文件名 String destinationFileName = splitFileName; // 需要合并的PDF文件 List<InputStream> inputStreams = new ArrayList<>(); for (String pdf : pdfList) { inputStreams.add(new FileInputStream(new File(pdf))); } // 合并后pdf存放路径 String bothPath = "D:\\BaiduNetdiskDownload\\test"; MergePdf(inputStreams, bothPath, destinationFileName + "测试合并.pdf"); System.out.println("pdf文件合并成功-----------"); } /** * 正则校验匹配 拆分规则 * @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 * @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> finalPdfs = new ArrayList<>(); int j = 1; String splitPdf = splitPath + "\\" + splitFileName + "_"; for (SplitterDTO splitterDTO : splitterDTOS) { // Loading an existing PDF document File file = new File(sourcePdf); PDDocument document = PDDocument.load(file); // Instantiating Splitter class Splitter splitter = new Splitter(); splitter.setStartPage(splitterDTO.getStartPage()); splitter.setSplitAtPage(splitterDTO.getSplitAtPage()); splitter.setEndPage(splitterDTO.getEndPage()); // 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 while(iterator.hasNext()) { PDDocument pd = iterator.next(); String pdfName = splitPdf+ j++ +".pdf"; pd.save(pdfName); finalPdfs.add(pdfName); } // System.out.println("Multiple PDF’s created"); document.close(); } return finalPdfs; } /** * 合并PDF * @param inputStreams 需合并的pdf文件流 * @param bothPath 合并后的pdf文件路径 * @param destinationFileName 合并后的pdf文件名 */ public static void MergePdf(List<InputStream> inputStreams, String bothPath, String destinationFileName) throws Exception { // pdf合并工具类 PDFMergerUtility mergePdf = new PDFMergerUtility(); File file = new File(bothPath); if (!file.exists()) { file.mkdirs(); } mergePdf.addSources(inputStreams); // 设置合并生成pdf文件名称 mergePdf.setDestinationFileName(bothPath + File.separator + destinationFileName); // 合并PDF mergePdf.mergeDocuments(); for (InputStream in : inputStreams) { if (in != null) { in.close(); } } } } /** * Splitter类的配置 */ @Data class SplitterDTO { private int splitAtPage; private int startPage; private int endPage; }

参考:

https://iowiki.com/pdfbox/pdfbox_splitting_a_pdf_document.html

https://github.com/apache/pdfbox

https://javadoc.io/doc/org.apache.pdfbox/pdfbox/1.8.10/index.html
声明:本站所有文章         ,如无特殊说明或标注                   ,均为本站原创发布   。任何个人或组织           ,在未征得本站同意时      ,禁止复制                  、盗用              、采集   、发布本站内容到任何网站                  、书籍等各类媒体平台                  。如若本站内容侵犯了原著者的合法权益                  ,可联系我们进行处理                 。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
云计算spi(【产品新体验】CSDN. 云IDE体验与功能使用教程(保姆级教程)) 网站推广120种方法(网站推广怎么做比较好)