如何用Java iText实现内嵌PDF的树状书签同文件跳转功能?
基于Java iText实现内嵌PDF树状书签跳转方案
前置依赖(Maven)
<!-- iText 7核心依赖 --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>kernel</artifactId> <version>7.2.5</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>layout</artifactId> <version>7.2.5</version> </dependency>
实现逻辑
- 先创建主PDF文档对象,同时将两份源PDF作为嵌入式附件存入主PDF的文件字典中,满足内嵌要求
- 依次读取两份源PDF的所有页面,导入到主PDF文档中,同步记录每份PDF在主文档中的起始页码
- 根据记录的页码创建顶级书签(大纲),分别命名为
pdf1、pdf2,跳转动作绑定到对应PDF的起始页,即可实现点击书签直接在当前文档内定位到对应内容,不会弹出独立文件
完整代码示例
import com.itextpdf.kernel.pdf.*; import com.itextpdf.kernel.utils.PdfMerger; import com.itextpdf.layout.Document; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class PdfTreeGenerator { public static void main(String[] args) throws IOException { // 待整合的PDF路径配置,自行替换为本地路径 String pdf1Path = "/本地路径/pdf1.pdf"; String pdf2Path = "/本地路径/pdf2.pdf"; String outputPath = "/本地路径/生成的主文件.pdf"; // 初始化主PDF PdfWriter writer = new PdfWriter(outputPath); PdfDocument mainPdf = new PdfDocument(writer); Document document = new Document(mainPdf); PdfMerger merger = new PdfMerger(mainPdf); // 存储文件名对应主文档起始页的映射 Map<String, Integer> pdfStartPageMap = new HashMap<>(); List<String> pdfPaths = new ArrayList<>(); pdfPaths.add(pdf1Path); pdfPaths.add(pdf2Path); // 依次导入PDF并记录起始页 for (String pdfPath : pdfPaths) { File pdfFile = new File(pdfPath); String fileName = pdfFile.getName(); // 记录导入前的总页数+1就是当前PDF的起始页 int startPage = mainPdf.getNumberOfPages() + 1; pdfStartPageMap.put(fileName, startPage); // 导入源PDF页面到主文档 PdfDocument srcPdf = new PdfDocument(new PdfReader(pdfPath)); merger.merge(srcPdf, 1, srcPdf.getNumberOfPages()); srcPdf.close(); // 将源PDF作为内嵌附件存入主文档 PdfFileSpec fileSpec = PdfFileSpec.createEmbeddedFileSpec(mainPdf, new FileInputStream(pdfFile), fileName, fileName, null, null, false); mainPdf.addFileAttachment(fileName, fileSpec); } // 创建书签(大纲)结构 PdfOutline rootOutline = mainPdf.getOutlines(false); for (Map.Entry<String, Integer> entry : pdfStartPageMap.entrySet()) { String fileName = entry.getKey(); Integer startPage = entry.getValue(); // 创建书签节点 PdfOutline childOutline = rootOutline.addOutline(fileName); // 设置跳转动作:跳转到对应PDF的起始页 PdfDestination destination = PdfExplicitDestination.createFit( mainPdf.getPage(startPage)); childOutline.addAction(PdfAction.createGoTo(destination)); } document.close(); mainPdf.close(); } }
注意事项
- 上述代码基于iText 7实现,如果使用iText 5版本,需要调整
PdfMerger、PdfOutline相关的API调用 - 生成的主PDF已经内嵌了两份原始PDF文件,同时书签点击直接跳转对应内容,不需要打开独立文件
内容的提问来源于stack exchange,提问作者user27
相关产品推荐
相关产品推荐

