「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战」
PDF神器iText英文版翻译与学习
作者: 薛大郎.
英文原版: iText in Action 2nd Edition.pdf
坚持. 分享. 成长. 利他 !
一. 前言
路漫漫其修远兮, 吾将上下而求索
本人深知写作水平有限, 废话较多, 抓不住重点. 有些人一句话即明了又简洁, 就如小傅哥的<你上车,我就把你带成卷王!> 中的这句话 新年放假,捅了3次核酸,去了三个地方,体会了三种快乐。
一语中的, 而且不拖泥带水, 而且后边重点提到自己舒服区. 发人深省. 希望自己能多写写, 不仅也能收获慢慢, 也能有所见地.
二.正文.
1.2 从已有Pdf文件中复制页面内容
上上一篇中, 我们强调了Pdf如果生成了文件, 就会是固定格式的.
我们复制已有Pdf文件的最简单最常用的方式:
Document document = new Document();
// RESULT 新文件
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
document.open();
// 把已有文件的页面放到一个Table中展示
PdfPTable table = new PdfPTable(2);
// RESOURCE 已有文件
PdfReader reader = new PdfReader(RESOURCE);
int n = reader.getNumberOfPages();
// PdfImportedPage extends PdfTemplate
PdfImportedPage page;
for (int i = 1; i <= n; i++) {
// 使用Writer.getImportedPage(PdfReader,int)来获取某一个引入页面.
page = writer.getImportedPage(reader, i);
// Image
// public static Image getInstance(final PdfTemplate template) throws BadElementException
table.addCell(Image.getInstance(page));
}
document.add(table);
document.close();
我们经常使用的就是writer来从Reader中获取一个引入的页, 也就是 PdfImportedPage 的一个对象, 看源码可知这个是 PdfTemplate 的一个子类, 而且无法修改.
那么看过 PdfReader 的源码的同学可能就要问了, 为什么不用 PdfReader#getPageContent 方法来获取这个页面的内容呢? 其实主要的原因为:
如果Pdf文件有外部引用的图片, 字体, 等等链接, 由于getPageContent是获取的Pdf语法的内容, 并不会从此文件外部再引入进行修改这些内容, 所以会失效, 或者会报警告, 这是Pdf文件的优势, 也是劣势.
从 PdfImportedPage extends PdfTemplate
可以想象到, 我们之前学过的, 使用 PdfContentByte#addTemplate 可以添加template内容.
// 但是当查看方法源码的时候, 会发现, 他又好多float参数, 暂时我也还是一头雾水, 只知道最后两个float参数为 x轴,y轴 的参数. 而前4个, 暂时还不清楚, 猜测为矩形方位 即要放的template内容的大小地方
public void addTemplate(final PdfTemplate template, final float a, final float b, final float c, final float d, final float e, final float f, boolean tagContent) ;
当然我们使用的更多的是 PdfStamper 这个类.
// 最开始的一篇中的 helloworld.
PdfReader reader = new PdfReader(src);
// 构造PdfStamper类, 类似于 PdfWriter类的使用
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
// 取第一页的PdfContentByte
PdfContentByte canvas = stamper.getOverContent(1);
// 写入文本. 并展示
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, new Phrase("Hello people!"), 36, 540, 0);
stamper.close();
查看PdfStamper的源码可知, 构造中真正干的其实是内部维护的一个 PdfStamperImp stamper; 而此 stamper extends PdfWriter. 是不是感觉, 还是很好玩的, 也就是扩展了这个PdfWriter类. 方便我们使用.
PdfStamper#getOverContent方法 类似于 PdfWriter#getDirectContent方法. 他也返回PdfContentByte类.
今天由于时间有限, 先写到这里, 明天继续探究 PdfStamper.