「这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战」
PDF神器iText英文版翻译与学习
作者: 薛大郎.
英文原版:iText in Action 2nd Edition.pdf
坚持. 分享. 成长. 利他 !
一. 前言
人家的总结真是总结, 自己的总结也只是总结
刚看完小傅哥の总结我觉得我没必要总结了,因为人家的总结真的是总结. 但是我们自己的总结还是要做, 想想自己到底进步了吗, 想想我们是否应该怎样改变下, 才能不枉时光, 毕竟我们的征途是星辰大海, 即使你才刚出发, 坚信通往成功的路上就如考驾照的路上一样, 与年龄无关, 与背景无关
, 只需要你努力了, 收获就有了. 而且有小傅哥这样的优秀博主在鼓励着大家.
二.正文.
5.2 Image和印章对象PdfTemplate
当想将同一个图片添加到同一个Pdf文件中时, 请使用同一个图片的实例. 因为在正常情况下,图像的位和字节存储在单独的存储空间中, 即PDF文件中的流对象。而包含此类图像的页面也就是此外部图像对象这样的对象也称为XObject。有很多种XObject, 其中我们用的最多的莫过于 Image和Form XObject, 比如当我们想建立一个PDF文件的模板, 只是向当中添加少量的文字的时候, 我们更多的实战方案不是需要使用iText编码所有的文字和内容, 而是使用iText复制现成的带有Form表单的Pdf文件模板, 然后将form表单的字段KEY-VALUE填充到Pdf的复制文件中, 并生成即可.
这里我们先讲一下Image XObject
// 从自定义的资源中获取一个Image的实例
Image img = Image.getInstance(RESOURCE);
// 计算并设置图片的绝对位置
img.setAbsolutePosition((PageSize.POSTCARD.getWidth() - img.getScaledWidth()) / 2,
(PageSize.POSTCARD.getHeight() - img.getScaledHeight()) / 2);
// 获取的是DirectContentByte的实例, 即将图片添加到了所有内容的最顶层的layer中.
writer.getDirectContent().addImage(img);
// 添加一段文字
Paragraph p = new Paragraph("Foobar Text", new Font(FontFamily.HELVETICA, 22));
// 设置水平居中对齐
p.setAlignment(Element.ALIGN_CENTER);
// 添加到文档中
document.add(p);
那么这样一来我们只会看到图片看不到Foobar Text
文字了. 将Image的实例多次使用这个并不难. 主要今天的讲解是下边这个PdfTemplate
类
PdfTemplate是PdfContentByte的子类, 源码中注释为 Implements the form XObject.
,即也是Form XObject的一种实现, 除了这种实现还有AcroForm
和XFA forms
, 最常用的还是PdfTemplate和AcroForm.
这个最典型的例子还是iText in Action
中电影胶卷的例子:
// 还是获取的最上边的一层 来填充内容
PdfContentByte canvas = writer.getDirectContent();
// 创建一个 宽595, 高84.2的一个胶卷 PdfTemplate实例
PdfTemplate celluloid = canvas.createTemplate(595, 84.2f);
// 在胶卷中设置一个矩形, 起点x轴为8,起点y轴为8,宽度为579, 高度为68
// 宽度为什么设置为 579, 是因为两边都留了8个单位的宽度,即 595 - (8 * 2) = 579;
celluloid.rectangle(8, 8, 579, 68);
for (float f = 8.25f; f < 581; f+= 6.5f) {
// 添加胶片中的上下两个圆边小矩形.
celluloid.roundRectangle(f, 8.5f, 6, 3, 1.5f);
celluloid.roundRectangle(f, 72.5f, 6, 3, 1.5f);
}
// 填充颜色 0(黑色)和 1(白色)之间的值
celluloid.setGrayFill(0.1f);
// 填充路径,使用奇偶规则确定要填充的区域。 即1-2填充, 2-3不填充 就形成了胶卷图像.
celluloid.eoFill();
writer.releaseTemplate(celluloid);
// 一页添加10个胶卷Template
for (int i = 0; i < 10; i++) {
canvas.addTemplate(celluloid, 0, i * 84.2f);
}
// 获取所有的电影.
List movies = PojoFactory.getMovies(connection);
Image img;
float x = 11.5f;
float y = 769.7f;
// 从上至下, 从左到右开始添加每个电影的海报.
for (Movie movie : movies) {
img = Image.getInstance(String.format(RESOURCE, movie.getImdb()));
img.scaleToFit(1000, 60);
img.setAbsolutePosition(x + (45 - img.getScaledWidth()) / 2, y);
canvas.addImage(img);
x += 48;
if (x > 578) {
x = 11.5f;
y -= 84.2f;
}
}
效果图: 整个过程需要耐心的计算各个元素的x,y轴的起点和宽度才能使得最后的结果美观. 完全就是数学和iText实现的美工UI工作.