编辑
2024-05-21
学习记录
00
请注意,本文编写于 317 天前,最后修改于 316 天前,其中某些信息可能已经过时。

目录

说明
依赖
工具类
可能出现的问题
优化

说明

根据业务要求需要将多个pdf合并成一个大的pdf,并且合并后的pdf还需要根据每个小pdf的标题生成目录。 本来使用的是iTextpdf5版本,这个版本不支持书签,所以引入新的依赖,使用pdfbox依赖写一个工具类合并pdf。

依赖

xml
<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.30</version> </dependency>

工具类

java
package com.lhw.management.utils; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageXYZDestination; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.List; public class PdfBoxUtils { /** * * @Description: 合并pdf生成目录 * @Param: @param null * @author lihaowei * @since: 2024/5/21 13:46 * @return */ public static byte[] MergeByteArrayAddBookMark(List<ByteArrayOutputStream> byteArrayOutputStreamList, List<String> bookMarkNames) throws IOException { PDDocument mergedDocument = new PDDocument(); PDDocumentOutline outline = null; int num=0; for (int i = 0; i < byteArrayOutputStreamList.size(); i++) { ByteArrayInputStream inputStream = new ByteArrayInputStream(byteArrayOutputStreamList.get(i).toByteArray()); PDDocument document = PDDocument.load(inputStream); for (PDPage page : document.getPages()) { mergedDocument.addPage(page); } if (i == 0) { outline = mergedDocument.getDocumentCatalog().getDocumentOutline(); if (outline == null) { outline = new PDDocumentOutline(); mergedDocument.getDocumentCatalog().setDocumentOutline(outline); } } PDOutlineItem item = new PDOutlineItem(); // 设置目标页面索引和目标位置坐标 PDPageXYZDestination destination = new PDPageXYZDestination(); destination.setPage(mergedDocument.getPage(num)); // 设置目标页面索引 destination.setLeft(0); // 设置目标位置坐标(这里设置为页面左上角) destination.setTop(0); item.setDestination(destination); item.setTitle(bookMarkNames.get(i)); outline.addLast(item); //计算索引页数 num=num+document.getNumberOfPages(); // 将 document.close(); 移到循环外 } }

可能出现的问题

java.io.IOException: Buffer already closed

优化

java
public static byte[] MergeByteArrayAddBookMark(List<ByteArrayOutputStream> byteArrayOutputStreamList, List<String> bookMarkNames) throws IOException { PDDocument mergedDocument = new PDDocument(); PDDocumentOutline outline = null; int num=0; List<PDDocument> docList = new ArrayList<>(); for (int i = 0; i < byteArrayOutputStreamList.size(); i++) { ByteArrayInputStream inputStream = new ByteArrayInputStream(byteArrayOutputStreamList.get(i).toByteArray()); PDDocument document= PDDocument.load(inputStream); docList.add(document); for (PDPage page : document.getPages()) { mergedDocument.addPage(page); } if (i == 0) { outline = mergedDocument.getDocumentCatalog().getDocumentOutline(); if (outline == null) { outline = new PDDocumentOutline(); mergedDocument.getDocumentCatalog().setDocumentOutline(outline); } } PDOutlineItem item = new PDOutlineItem(); // 设置目标页面索引和目标位置坐标 PDPageXYZDestination destination = new PDPageXYZDestination(); destination.setPage(mergedDocument.getPage(num)); // 设置目标页面索引 destination.setLeft(0); // 设置目标位置坐标(这里设置为页面左上角) destination.setTop(0); item.setDestination(destination); item.setTitle(bookMarkNames.get(i)); outline.addLast(item); //计算索引页数 num=num+document.getNumberOfPages(); } ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); mergedDocument.save(outputStream); for (PDDocument d:docList) { d.close(); } mergedDocument.close(); return outputStream.toByteArray(); }

本文作者:Weee

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!