PDF带目录导出java_itextpdf为pdf文件添加目录(可跳转)
需求: 有一个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文件添加目录(可跳转)相关推荐
- 完美解决Markdown文件添加目录的问题
文章目录 1. 按 2. 文件头添加TOC指令 2.1. 博客园或本地的VSCode+Markdown Preview Enhanced 2.2. CSDN 2.3. GitHub+Hexo+hexo ...
- Linux 文件与目录管理,玩转文件和目录管理的相关命令
Linux 文件与目录管理 Linux的目录结构为树状结构,最顶级的目录为根目录 / 其他目录通过挂载可以将它们添加到树中,通过解除挂载可以移除它们 更新学习资料: https://edu.csdn. ...
- ActiveReports 9 新功能:借助目录(TOC)控件为报表添加目录功能
ActiveReports 9 新功能:借助目录(TOC)控件为报表添加目录功能 原文:ActiveReports 9 新功能:借助目录(TOC)控件为报表添加目录功能 在最新发布的ActiveRep ...
- linux php目录是否存在,PHP判断文件或者目录是否可写,兼容windows/linux系统
在PHP中,可用is_writable()函数来判断一个 文件/目录 是否可写,用是否可生成文件的方式判断目录是否可写:网上的一些代码大多数能判断linux系统,但windows服务器下判断不准确. ...
- php教程目录,php基础入门篇-文件和目录操作_PHP教程
一篇关于php 入门的朋友参考的关于文件和目录的各种操作函数与实例应用,有需要的朋友可以简单的参考一下. 本章可以算是上一章的延续,介绍了除文件实际内容之外的附加信息,包括文件的大小.目录.访问权限等 ...
- linux怎么修改目录的所有者,linux修改文件或目录的所有者(chown)和用户组
chown更改文件或目录的所有者 注意:所有者,必须存在于(/etc/passwd)下.比如: linux修改文件或目录的所有者(chown)和用户组 更改文件或目录的所有者命令: 1.新建测试文件t ...
- ubuntu中/usr目录下无法直接复制粘贴文件或目录
遇到问题:直接鼠标右键复制粘贴或ctrl+c ctrl+v不管用 利用终端窗口 sudo cp -r+"空格"+~/你要复制的文件的原目录/你要复制的文件+"空格 ...
- linux 切换目录,Linux切换目录命令cd与查看文件和目录命令ls
一. 遍历目录 在 Linux系统上,可以使用cd切换目录命令. 分二种路径,一是绝对文件路径,另一种是相对文件路径. 1.绝对文件路径在虚拟目录中采用文件路径,以虚拟目录根目录开始,相当于目录的全 ...
- linux安装php的目录在哪,Linux php文件安装目录在哪-PHP问题
php文件装置目次普通默许正在"/var/www"外面,假如是自界说装置,则能够用Linux的饬令进行查找,查找的饬令是"find / -name "*www* ...
- Shell-常用命令:删除文件、目录【rm 待删除文件或目录】
rm (remove)删除文件或目录 rm -d (-directory) #直接把需删除的目录的硬连接数据删成0,删除该目录 rm -f (--force) #强制删除文件或目录:忽略不存在的文件, ...
最新文章
- jquery二维码生成插件jquery.qrcode.js
- aspnet_merge.exe”已退出,代码为1的错误的解决方法
- 项目:部署LNMP动态网站
- java中兴参与实参相同_中兴通讯_传输SDH试题(含答案)
- java开发利器 源码_Java开发的利器: 反编译工具 JD-GUI
- 均方根误差有没有单位_1千万年仅误差一秒,这台钟直接影响北斗卫星的导航定位精度...
- c++ 线程池_JAVA并发编程:线程池ThreadPoolExecutor源码分析
- Android 多种跑马灯的方法
- memset()详解
- csdn 挣积分和c币方法指南
- 微信 原创保护开通申请协议内容
- 8 升满壶和两个分别是 5 升、3 升的空壶 如何得到 4 升水?
- DNA损伤修复基因数据库
- 超强学位论文检索工具,你必须拥有!
- 【转】和老外聊天、发邮件常用英语缩写
- python怎么做图表好看_如何制作有趣好看的数据可视化图表?
- uniapp爱玩小灰视频播放器使用流程
- java需要学哪些知识习
- 如何进行微距摄影(转)
- 傻瓜式操作实现华为手机与其他品牌电脑实现NFC一碰传
热门文章
- 软考嵌入式系统设计师2013年上午试题总结
- linux 拷贝xlsx_linux 命令行将xlsx格式文件转换成CSV的5种方法
- 智能识别系统设计---图像特征提取
- 房聚良源系统功能介绍(SpringBoot)
- win7网络怎么添加一台计算机,win7网络共享的设置方法【详细步骤】
- 给前端工程师看的后端科普
- 求圆周长、圆面积、圆球表面积、圆球体积、圆柱体积。用scanf输入数据,输出计算结果
- 打印机驱动无法安装到计算机是,打印机后台程序服务没有运行,打印机驱动无法安装,打印机驱动安装失败-中关村在线...
- 贴片铝电容识别及型号_如何识别各种材质贴片电容
- 如何彻底卸载wamp