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;
	}
相关推荐
曼岛_32 分钟前
[图解密码学]第4章 古典密码
java·数据库·密码学
一枕槐安48732 分钟前
RAG 服务扛住高并发:缓存、队列、限流三件套
java·spring·缓存·异步任务·rag·断路器
Wang's Blog33 分钟前
Java 项目实战: 交友项目 - 动态查询开工:昨日回顾与今日任务
java·python·交友
云和数据.ChenGuang1 小时前
光哥说Python 异常深度解析:从异常模型到工程化实践
java·前端·人工智能·python·langchain
SL_staff1 小时前
APS动态重排实践:在多品种小批量场景下实现5分钟插单响应
java·开源·产品
captain3762 小时前
Spring MVC(4)-响应
java·spring boot·后端
Lichee203 小时前
招行Java 面试知识点梳理:Spring 事务、锁、线程池、集合
java·面试
YDS8293 小时前
Small Spring IOC篇:作用域和FactoryBean
java·后端·spring
Shaoshing3 小时前
LeetCode100 42.接雨水
java·算法·leetcode
枫子有风3 小时前
卡码网盘项目深挖
java·redis·jwt·es·pgvector