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;
	}
相关推荐
skywalk816310 分钟前
Clojure学习:运行在 Java 虚拟机(JVM)上的动态Lisp编程语言
java·lisp·clojure
weixin_5783718814 分钟前
pdf合并工具,pdf合并器,多个pdf合并成一个pdf
pdf
一碗谦谦粉14 分钟前
Spring之spring的单例bean是线程安全的吗
java·spring
liuliuliuliuyujie15 分钟前
学生管理系统
java
哎呀妈呀叮咚响啊16 分钟前
pdf已加密如何解除?解密密码的两个方法【可加密】
pdf
ItKevin爱java18 分钟前
java八股文面试题
java·开发语言
喜欢猪猪31 分钟前
两个线程之间是如何通信的呢?
java·开发语言
co松柏34 分钟前
在非 antd pro 项目中使用 umi OpenAPI
java·前端
java66666888835 分钟前
Spring Boot中的数据加密与解密
java·spring boot·后端
NightHacker1 小时前
什么是AOP思想?
java·开发语言