需求: 有一个pdf文件source.pdf , 有这个pdf的目录数据Map catalogs , 将catalog作为目录添加到source.pdf文件中 ,且可以点击目录跳转到指定页

描述:原本的source.pdf是没有目录的 , 且catalog目录数据是用别的方法读出来的或者自定义的

工具代码如下:

//需要导入的包

import com.itextpdf.kernel.pdf.PdfDocument;

import com.itextpdf.kernel.pdf.PdfReader;

import com.itextpdf.kernel.pdf.PdfWriter;

import com.itextpdf.kernel.pdf.canvas.draw.DottedLine;

import com.itextpdf.layout.Document;

import com.itextpdf.layout.element.Paragraph;

import com.itextpdf.layout.element.Tab;

import com.itextpdf.layout.element.TabStop;

import com.itextpdf.layout.element.Text;

import com.itextpdf.layout.property.TabAlignment;

import com.itextpdf.layout.property.TextAlignment;

import com.itextpdf.text.DocumentException;

import com.itextpdf.text.Font;

import com.itextpdf.text.pdf.BaseFont;

import com.itextpdf.text.pdf.PdfPCell;

import java.io.File;

import java.io.IOException;

import java.util.Map;

import java.util.TreeMap;

/**

* 生成一个带有目录(可跳转)的pdf文件(支持中文).

* 如果目录两页,请为pdf多留出一页空白内容.

* 此方法不能生成书签.

*

* @param sourceFile 源pdf文件

* @param targetFile 带有目录(可跳转)的pdf文件

* @param catalogs 目录数据map

* @param catalogTitle 目录上方第一行文字

* @param catalogPageSize 目录占页大小(为锚点偏移做参数)

* @return targetFile

* @throws IOException

*/

public static String createPdfWithCatalog(String sourceFile,

String targetFile,

String catalogTitle,

Map catalogs,

int catalogPageSize) throws IOException {

Map catalogsTemp = new TreeMap<>();

catalogsTemp.putAll(catalogs);

//实际页码索引偏移量为 目录占页数-1

int offset = catalogPageSize - 1;

for (Map.Entry entry : catalogsTemp.entrySet()) {

entry.setValue(entry.getValue() + offset);

}

File file = new File(targetFile);

file.getParentFile().mkdirs();

PdfDocument pdfDoc = new PdfDocument(new PdfWriter(targetFile));

Document document = new Document(pdfDoc);

PdfFont font0 = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", false);

if (catalogTitle == null) {

catalogTitle = " ";

}

document.add(new Paragraph(new Text(catalogTitle))

.setTextAlignment(TextAlignment.CENTER).setFont(font0));

PdfDocument firstSourcePdf = new PdfDocument(new PdfReader(sourceFile));

int numberOfPages = firstSourcePdf.getNumberOfPages();

for (int i = 1; i <= numberOfPages; i++) {

PdfPage page = firstSourcePdf.getPage(i).copyTo(pdfDoc);

pdfDoc.addPage(page);

for (Map.Entry entry : catalogsTemp.entrySet()) {

if (i == entry.getValue()) {

String destinationKey = "p" + (pdfDoc.getNumberOfPages() - 1);

PdfArray destinationArray = new PdfArray();

destinationArray.add(page.getPdfObject());

destinationArray.add(PdfName.XYZ);

destinationArray.add(new PdfNumber(0));

destinationArray.add(new PdfNumber(page.getMediaBox().getHeight()));

destinationArray.add(new PdfNumber(1));

try {

pdfDoc.addNamedDestination(destinationKey, destinationArray);

} catch (Exception e) {

System.out.println(e.getMessage());

}

Paragraph p = new Paragraph();

PdfFont font = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", false);

p.setFont(font);

p.addTabStops(new TabStop(540, TabAlignment.RIGHT, new DottedLine()));

p.add(entry.getKey());

p.add(new Tab());

p.add(String.valueOf(pdfDoc.getNumberOfPages() - 1));

p.setProperty(Property.ACTION, PdfAction.createGoTo(destinationKey));

document.add(p);

}

}

}

firstSourcePdf.close();

document.close();

return targetFile;

}调用示例如下:

Map catalogs = new TreeMap<>();

catalogs.put("Performance by z中文1", 1);

catalogs.put("Performance by z中文12", 2);

catalogs.put("Performance by z中文22", 2);

catalogs.put("Performance by z中文32", 3);

catalogs.put("Performance by z中文42", 4);

catalogs.put("Performance by z中文52", 4);

catalogs.put("Performance by z中文62", 5);

//此处省略N行添加map.....

//catalogPdfPageSize,预测目录会有两页,此参数影响锚点的偏移和目录是否会与主要内容重叠(计算目录页数的方法在文章最后贴出,见分割线)

int catalogPdfPageSize =2;

createPdfWithCatalog("d://源文件.pdf", "d://转换后带有目录的pdf文件.pdf", "目录第一行标题随意啦", catalogs, catalogPdfPageSize);

///*************一个特别难看的分割线**************************一个特别难看的分割线*************************

计算目录能占多少页的方法,此方法通过用目录数据catalogs生成一个只有目录的pdf,然后返回pdf的page来获取到目录占页数量:

/**

* 新改的方法 ,生成目录pdf ,只是为了方便计算页数.

* 基于createPdfWithCatalog()代码改编,该方法进保留生成目录功能.

*

* @param sourceFile sourceFile

* @param targetFile targetFile

* @param catalogs catalogs

* @return 目录页数 page size

* @throws IOException IOException

*/

public static int createCatalogPdfOnly(String sourceFile, String targetFile, Map catalogs) throws IOException {

File file = new File(targetFile);

file.getParentFile().mkdirs();

PdfDocument pdfDoc = new PdfDocument(new PdfWriter(targetFile));

Document document = new Document(pdfDoc);

document.add(new Paragraph(new Text("The Revenant nominations list"))

.setTextAlignment(TextAlignment.CENTER));

PdfDocument firstSourcePdf = new PdfDocument(new PdfReader(sourceFile));

for (Map.Entry entry : catalogs.entrySet()) {

Paragraph p = new Paragraph();

p.addTabStops(new TabStop(540, TabAlignment.RIGHT, new DottedLine()));

p.add(entry.getKey());

p.add(new Tab());

p.add(String.valueOf(pdfDoc.getNumberOfPages() - 1));

document.add(p);

}

firstSourcePdf.close();

int pages = pdfDoc.getNumberOfPages();

document.close();

return pages;

}使用示例:

//一个只有一页的pdf文件,必须,该文件必须只有一页!!!

String blankPdf ="d://一个只有一页的pdf文件.pdf";

//生成的只有目录的pdf文件

String catalogPagesTempFile ="随便七个名字把.pdf";

//catalog 即上文中的catalogs数据 ,形式为 Map map ....

int catalogPdfPageSize = createCatalogPdfOnly(blankPdf, catalogPagesTempFile, catalog);

//完成 ,catalogPdfPageSize即目录所占总页数 ,可将此参数用作上边方法得偏移参数

PDF带目录导出java_itextpdf为pdf文件添加目录(可跳转)相关推荐

  1. 完美解决Markdown文件添加目录的问题

    文章目录 1. 按 2. 文件头添加TOC指令 2.1. 博客园或本地的VSCode+Markdown Preview Enhanced 2.2. CSDN 2.3. GitHub+Hexo+hexo ...

  2. Linux 文件与目录管理,玩转文件和目录管理的相关命令

    Linux 文件与目录管理 Linux的目录结构为树状结构,最顶级的目录为根目录 / 其他目录通过挂载可以将它们添加到树中,通过解除挂载可以移除它们 更新学习资料: https://edu.csdn. ...

  3. ActiveReports 9 新功能:借助目录(TOC)控件为报表添加目录功能

    ActiveReports 9 新功能:借助目录(TOC)控件为报表添加目录功能 原文:ActiveReports 9 新功能:借助目录(TOC)控件为报表添加目录功能 在最新发布的ActiveRep ...

  4. linux php目录是否存在,PHP判断文件或者目录是否可写,兼容windows/linux系统

    在PHP中,可用is_writable()函数来判断一个 文件/目录 是否可写,用是否可生成文件的方式判断目录是否可写:网上的一些代码大多数能判断linux系统,但windows服务器下判断不准确. ...

  5. php教程目录,php基础入门篇-文件和目录操作_PHP教程

    一篇关于php 入门的朋友参考的关于文件和目录的各种操作函数与实例应用,有需要的朋友可以简单的参考一下. 本章可以算是上一章的延续,介绍了除文件实际内容之外的附加信息,包括文件的大小.目录.访问权限等 ...

  6. linux怎么修改目录的所有者,linux修改文件或目录的所有者(chown)和用户组

    chown更改文件或目录的所有者 注意:所有者,必须存在于(/etc/passwd)下.比如: linux修改文件或目录的所有者(chown)和用户组 更改文件或目录的所有者命令: 1.新建测试文件t ...

  7. ubuntu中/usr目录下无法直接复制粘贴文件或目录

    遇到问题:直接鼠标右键复制粘贴或ctrl+c     ctrl+v不管用 利用终端窗口 sudo cp -r+"空格"+~/你要复制的文件的原目录/你要复制的文件+"空格 ...

  8. linux 切换目录,Linux切换目录命令cd与查看文件和目录命令ls

    一.  遍历目录 在 Linux系统上,可以使用cd切换目录命令. 分二种路径,一是绝对文件路径,另一种是相对文件路径. 1.绝对文件路径在虚拟目录中采用文件路径,以虚拟目录根目录开始,相当于目录的全 ...

  9. linux安装php的目录在哪,Linux php文件安装目录在哪-PHP问题

    php文件装置目次普通默许正在"/var/www"外面,假如是自界说装置,则能够用Linux的饬令进行查找,查找的饬令是"find / -name "*www* ...

  10. Shell-常用命令:删除文件、目录【rm 待删除文件或目录】

    rm (remove)删除文件或目录 rm -d (-directory) #直接把需删除的目录的硬连接数据删成0,删除该目录 rm -f (--force) #强制删除文件或目录:忽略不存在的文件, ...

最新文章

  1. jquery二维码生成插件jquery.qrcode.js
  2. aspnet_merge.exe”已退出,代码为1的错误的解决方法
  3. 项目:部署LNMP动态网站
  4. java中兴参与实参相同_中兴通讯_传输SDH试题(含答案)
  5. java开发利器 源码_Java开发的利器: 反编译工具 JD-GUI
  6. 均方根误差有没有单位_1千万年仅误差一秒,这台钟直接影响北斗卫星的导航定位精度...
  7. c++ 线程池_JAVA并发编程:线程池ThreadPoolExecutor源码分析
  8. Android 多种跑马灯的方法
  9. memset()详解
  10. csdn 挣积分和c币方法指南
  11. 微信 原创保护开通申请协议内容
  12. 8 升满壶和两个分别是 5 升、3 升的空壶 如何得到 4 升水?
  13. DNA损伤修复基因数据库
  14. 超强学位论文检索工具,你必须拥有!
  15. 【转】和老外聊天、发邮件常用英语缩写
  16. python怎么做图表好看_如何制作有趣好看的数据可视化图表?
  17. uniapp爱玩小灰视频播放器使用流程
  18. java需要学哪些知识习
  19. 如何进行微距摄影(转)
  20. 傻瓜式操作实现华为手机与其他品牌电脑实现NFC一碰传

热门文章

  1. 软考嵌入式系统设计师2013年上午试题总结
  2. linux 拷贝xlsx_linux 命令行将xlsx格式文件转换成CSV的5种方法
  3. 智能识别系统设计---图像特征提取
  4. 房聚良源系统功能介绍(SpringBoot)
  5. win7网络怎么添加一台计算机,win7网络共享的设置方法【详细步骤】
  6. 给前端工程师看的后端科普
  7. 求圆周长、圆面积、圆球表面积、圆球体积、圆柱体积。用scanf输入数据,输出计算结果
  8. 打印机驱动无法安装到计算机是,打印机后台程序服务没有运行,打印机驱动无法安装,打印机驱动安装失败-中关村在线...
  9. 贴片铝电容识别及型号_如何识别各种材质贴片电容
  10. 如何彻底卸载wamp