根据业务要求需要将多个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 许可协议。转载请注明出处!