「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」
PDF神器iText英文版翻译与学习
作者: 薛大郎.
英文原版: iText in Action 2nd Edition.pdf
坚持. 分享. 成长. 利他 !
一. 前言
冬奥会开幕式昨日成功举办
首先庆祝首都成为第一个双奥城市. 也给我们的孩子们留下了很多知识点以后要记了.
XDM, 明天就要上班了
假期总是很短暂的, 如果你觉得难熬, 那说明你不是很快乐. 不管快乐不快乐, 要相信上班才是快乐的, 才是我们生活的一大部分. 才能够实现我们白吃白喝在外一年还能够剩下一些 money 回家. 所以兄弟们, 爱上工作吧.
二.正文.
继续详细学习下其他的事件
// 这是一个段落的事件实现类, 主要是做xia'hua'xian
class ParagraphPositions extends PdfPageEventHelper {
// 这个是在段落渲染之前触发的事件方法
public void onParagraph(PdfWriter writer, Document pdfDocument, float paragraphPosition) {
drawLine(writer.getDirectContent(), pdfDocument.left(), pdfDocument.right(), paragraphPosition - 8);
}
// 这个是在段落渲染之后触发的事件方法
public void onParagraphEnd(PdfWriter writer, Document pdfDocument, float paragraphPosition)
drawLine(writer.getDirectContent(), pdfDocument.left(), pdfDocument.right(), paragraphPosition - 5);
}
// 用以画一条下划线,
public void drawLine(PdfContentByte cb, float x1, float x2, float y) {
// 先移动至 x位置为x1, y位置为y的位置
cb.moveTo(x1, y);
// 然后从上边的位置开始划, 划到x位置为x2, y位置还是为y的位置.
cb.lineTo(x2, y);
// 完成这一笔
cb.stroke();
}
}
上边是我们比较常用到的段落事件的使用, 接下来我们继续学习章节的一些章节事件. 大家都知道当我们在使用Chapter 和 Section 时, 就会自动产生一个目录树, 使用Adobe pdf Reader时, 可以根据章节目录来定位查看相关章节内容. 这个目录树并不能打印, 我们可以使用这个事件扩展来形成可打印的目录树.
我们还是来解读书中的例子吧:
class ChapterSectionTOC extends PdfPageEventHelper {
// 所有章节 标题
List titles = new ArrayList<Paragraph>();
// 在章节渲染之前触发
public void onChapter(PdfWriter writer, Document document, float position, Paragraph title){
// 添加标题段落内容到 titles
titles.add( new Paragraph(title.getContent(), FONT[4]));
}
// 在章节渲染后触发
public void onChapterEnd(PdfWriter writer, Document document, position) {
// 画一条线
drawLine(writer.getDirectContent(), document.left(), document.right(), position - 5);
}
// 在章节渲染之前触发
public void onSection(PdfWriter writer, Document document,float position, int depth, Paragraph title) {
// 添加节的内容
title = new Paragraph(title.getContent(), FONT[4]);
// 设置左缩进
title.setIndentationLeft(18 * depth);
titles.add(title);
}
// 在章节渲染之后触发
public void onSectionEnd(PdfWriter writer, Document document, float position) {
// 画一条线
drawLine(writer.getDirectContent(),document.left(), document.right(), position - 3);
}
public void drawLine(PdfContentByte cb, float x1, float x2, float y) {
cb.moveTo(x1, y);
cb.lineTo(x2, y);
cb.stroke();
}
}
当我们已经拥有了这个titles以后, 也就是说我们已经将所有的内容添加到了Pdf中, 我们才能开始想办法渲染这些内容, 而页数 也需要处理. 下边是一个简单的处理方式, 其实可以有更好的处理方式, 后边我们再详细说.
// 获取一个新页
document.newPage();
// 获取总页数
int toc = writer.getPageNumber();
// 在新页里边添加所有的title, 当然如果写不完也会添加到一页
for (Paragraph p : event.titles) {
document.add(p);
}
// 重新获取最后的页码
document.newPage();
// 并获取总页码数
// if (order == null)
// return pages.size();
int total = writer.reorderPages(null);
// 组装页码数数组, 用以最后reorderPages的参数
int[] order = new int[total];
for (int i = 0; i < total; i++) {
order[i] = i + toc;
if (order[i] > total)
order[i] = order[i] - total;
}
// 按照 i => order[i] 来重新排序页面, 即将后边的目录页都移至最前边
writer.reorderPages(order);
document.close();
这个reorderPages 很好用, 大家可以试下.