itextpdf为pdf文件添加目录(可跳转)
来源:互联网 发布:淘宝网服装女装秋装 编辑:程序博客网 时间:2024/06/05 02:37
需求: 有一个pdf文件source.pdf , 有这个pdf的目录数据Map<String,Integer> catalogs , 将catalog作为目录添加到source.pdf文件中 ,且可以点击目录跳转到指定页
描述:原本的source.pdf是没有目录的 , 且catalog目录数据是用别的方法读出来的或者自定义的
原文链接: http://gitlab.itextsupport.com/itext7/samples/blob/master/publications/jumpstart/src/main/java/tutorial/chapter06/C06E06_88th_Oscar_Combine_AddTOC.java
工具代码如下:
//需要导入的包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<String, Integer> catalogs, int catalogPageSize) throws IOException { Map<String, Integer> catalogsTemp = new TreeMap<>(); catalogsTemp.putAll(catalogs); //实际页码索引偏移量为 目录占页数-1 int offset = catalogPageSize - 1; for (Map.Entry<String, Integer> 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<String, Integer> 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<String, Integer> 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<String, Integer> 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<String, Integer> 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<Strig,Integer> map ....int catalogPdfPageSize = createCatalogPdfOnly(blankPdf, catalogPagesTempFile, catalog);//完成 ,catalogPdfPageSize即目录所占总页数 ,可将此参数用作上边方法得偏移参数
阅读全文
0 0
- itextpdf为pdf文件添加目录(可跳转)
- Java 实现 pdf文件添加 图片水印 itextpdf 5.5.2
- java 用itextpdf读写pdf文件
- 如何给pdf文件添加目录/书签
- 使用barcode4j+itextpdf把条形码写入PDF文件
- itextPdf 可以写pdf文件,主要是文字的问题
- itextpdf输出PDF笔记
- itextPDF生成PDF
- 使用itextpdf操作pdf
- 使用Aspose.Pdf为PDF文件添加swf注释
- pdf添加目录
- itextpdf将图片转成pdf文件及pdfbox将多张pdf合成一张
- pdf转换为可编辑的ppt文件的方法
- 为pdf添加书签
- 使用itextpdf 将HTML转成PDF文件,并做电子签章
- 为 adobe reder(pdf文件)添加书签
- 为pdf文件添加设置超链接的小技巧
- java 使用itextpdf.jar和itext-asian.jar根据pdf模板填写数据后生成一个新的pdf文件
- String类和StringBuilder类
- swagger 常用注解
- 加/解密系列(三)-前端加密JS库--CryptoJS
- 微信小程序开发之网络请求(POST请求)
- Psr(psr1+psr2+psr3)
- itextpdf为pdf文件添加目录(可跳转)
- CTF中Crypty(密码类)入门必看
- Odoo10在win10下部署
- Lottie动画动态定位以及缩放
- Fragment懒加载机制
- RandomAccessFile
- elasticsearch之Document APIs【Get API】
- 小程序tabBar添加
- 正则表达式(足够用了)