PDF 生成在左侧目录栏目录信息的目录 点击跳转

pdf 导出的内容 是itextpdf 写的

目录信息 得用 pdfbox 里的 PDDocumentOutline

XML 复制代码
		<dependency>
			<groupId>com.itextpdf</groupId>
			<artifactId>itextpdf</artifactId>
			<version>5.4.3</version>
		</dependency>

		<dependency>
			<groupId>org.apache.pdfbox</groupId>
			<artifactId>pdfbox</artifactId>
			<version>3.0.1</version>
		</dependency>

思路:

1.itextpdf 输出文件过程中 在 pdfbox 的 PDDocumentOutline 添加目录信息

2.pdfbox 复制文件 配置 PDDocumentOutline 目录信息

  1. 删除 没有目录信息的文件
java 复制代码
// 目录
PDDocumentOutline documentOutline = new PDDocumentOutline();
documentOutline.addFirst(pdOutlineItem);
documentOutline.addLast(pdOutlineItem);
Iterable<PDOutlineItem> children = documentOutline.children();
documentOutline.openNode();
documentOutline.closeNode();
java 复制代码
        OutputStream os = FileUtil.getOutputStream(finalTempFilePath);
        Document document = new Document(PageSize.A4, 36, 36, 36, 36);
		PdfWriter writer = PdfWriter.getInstance(document, os);

		// 目录
		PDDocumentOutline documentOutline = new PDDocumentOutline();

        // 存目录条目 和对应的页号 在代码最后 配置目录要跳转的page
		List<Pair<PDOutlineItem, Integer>> itemList = Lists.newArrayList();

        document.open();
		writer.setPageEmpty(false);

		// 目录信息
		addOutline(documentOutline, "封面", writer.getPageNumber(), itemList);

        for (一级目录){
    
            
            PDOutlineNode pdOutlineItem = addOutline(documentOutline, "一级目录名",                   
                                    writer.getPageNumber(), itemList);
		
            for (二级目录){
                // 目录信息
		        addOutline(pdOutlineItem , "二级目录名", writer.getPageNumber(), 
                            itemList);
            }
		    
        }

        // 4. 复制文件
		try(
			PDDocument pdfDoc = Loader.loadPDF(new File(finalTempFilePath));
			PDDocument pdfPage = new PDDocument();
		){

			for (int i = 0; i < footerEndNum-1; i++) {

                // 这个if 是把 在文章最后的 目录 挪到前面
				if(i==footerBeginNum-1){
					for (int j = footerEndNum-1; j < menuPageEndNum; j++) {
						PDPage page = pdfDoc.getPage(j);
						pdfPage.addPage(page);
					}
				}

				PDPage page = pdfDoc.getPage(i);
				pdfPage.addPage(page);

			}

            // 给目录 配置跳转的page 
			for (Pair<PDOutlineItem, Integer> pdOutlineItemIntegerPair : itemList) {

				Integer second = pdOutlineItemIntegerPair.getSecond();
				PDPage page = pdfDoc.getPage(second);

				PDPageFitDestination dest = new PDPageFitDestination();
				dest.setPage(page);

				PDOutlineItem first = pdOutlineItemIntegerPair.getFirst();
				first.setDestination(dest);
			}

            // 给文件 加目录信息
			pdfPage.getDocumentCatalog().setDocumentOutline(documentOutline);

			// 存
			pdfPage.save(finalMenuFilePath);
		}
java 复制代码
	public PDOutlineItem addOutline (PDOutlineNode pDOutlineNode, String title, int pageNumber,
									 List<Pair<PDOutlineItem, Integer>> itemList) {
		PDOutlineItem pdOutlineItem = new PDOutlineItem();
		pdOutlineItem.setTitle(title);
//		PDPageXYZDestination pdPageXYZDestination = new PDPageXYZDestination();
//		pdPageXYZDestination.setPageNumber(pageNumber);
//		pdOutlineItem.setDestination(pdPageXYZDestination);
		pDOutlineNode.addLast(pdOutlineItem);

		itemList.add(new Pair<PDOutlineItem, Integer>(pdOutlineItem, pageNumber));
		return pdOutlineItem;
	}
相关推荐
人活一口气2 小时前
从JVM调优到MCP协议:Java全栈技术体系深度总结与企业级架构实践
java·spring boot
NE_STOP4 小时前
Vibe Coding -- 完整项目案例实操
java
荣码4 小时前
GraphRAG:普通RAG只能回答"点"的问题,我踩了4个坑才搞懂
java·python
SimonKing4 小时前
Google第三方授权登录
java·后端·程序员
明月光8184 小时前
从一行 @Builder 说起:重新拾起 Java 的 Lombok、注解与 Builder 模式
java
考虑考虑13 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯14 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
青石路18 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
像我这样帅的人丶你还21 小时前
Java 后端详解(五):Redis 缓存
java·后端·全栈
plainGeekDev1 天前
GreenDAO → Room
android·java·kotlin