「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」
PDF神器iText英文版翻译与学习
作者: 薛大郎.
英文原版: iText in Action 2nd Edition.pdf
坚持. 分享. 成长. 利他 !
一. 前言
明天是情人节了.
仪式感这个词越来越受重视, 尤其是有爱情基础的两个人, 这两个人只以物质作为基础还好, 思想物质化后, 仪式物质化后, 甚至都要以物质来评论一些事儿, 以及这些事儿作为一种价值观去强加给另一方的时候, 爱情或许就是些点滴.
喜欢<遥远的救世主>里芮小丹的爱情观: 既然爱了就坦然爱,为什么要驾驭?拿什么?是你的,不用拿,不是你的,你拿不了,拿什么?爱就是了
二.正文.
1.4 使用PdfCopy来复制页面
PdfImportedPage这个类是一个只读的类, 它继承自PdfTemplate. 我们不能使用PdfWriter和PdfStamper添加任何内容到一个importedPage中, 这倒是没什么大不了. 因为我们可以很容易地从上下两层中添加内容到这个importedPage中. 现在我们要使用PdfCopy了, 他也有一些有意思的操作.
下边的案例为合并两个文档, 并将每页添加 page X of Y
页脚.
Document document = new Document();
PdfCopy copy = new PdfCopy(document, new FileOutputStream(RESULT));
document.open();
PdfReader reader1 = new PdfReader(MovieLinks1.RESULT);
int n1 = reader1.getNumberOfPages();
PdfReader reader2 = new PdfReader(MovieHistory.RESULT);
int n2 = reader2.getNumberOfPages();
PdfImportedPage page;
PdfCopy.PageStamp stamp;
// 第一个文档的处理
for (int i = 0; i < n1; ) {
// 获取第一个文件中的某一页
page = copy.getImportedPage(reader1, ++i);
// 创建一个pageStamp
stamp = copy.createPageStamp(page);
// 使用ColumnText展示文本到下层内容中.
ColumnText.showTextAligned(stamp.getUnderContent(), Element.ALIGN_CENTER,
new Phrase(String.format("page %d of %d", i, n1 + n2)),297.5f, 28, 0);
// 调用此方法用以修改. 否则不生效
stamp.alterContents();
copy.addPage(page);
}
for (int i = 0; i < n2; ) {
page = copy.getImportedPage(reader2, ++i);
stamp = copy.createPageStamp(page);
ColumnText.showTextAligned(
stamp.getUnderContent(), Element.ALIGN_CENTER, new Phrase(
String.format("page %d of %d", n1 + i, n1 + n2)),297.5f, 28, 0);
stamp.alterContents();
copy.addPage(page);
}
document.close();
接下来我们可以看下PdfCopy.PageStamp的源码, 以及PdfCopy.StampContent的源码, 可见一斑.
// PageStamp为PdfCopy类的静态内部类.
public static class PageStamp {
PdfDictionary pageN;
PdfCopy.StampContent under;
PdfCopy.StampContent over;
PageResources pageResources;
PdfReader reader;
PdfCopy cstp;
// 也是获取下边的一层的PdfContentBype但是 他其实真正的是 PdfCopy.StampContent.
public PdfContentByte getUnderContent(){
if (under == null) {
if (pageResources == null) {
pageResources = new PageResources();
PdfDictionary resources = pageN.getAsDict(PdfName.RESOURCES);
pageResources.setOriginalResources(resources, cstp.namePtr);
}
under = new PdfCopy.StampContent(cstp, pageResources);
}
return under;
}
public PdfContentByte getOverContent(){
if (over == null) {
if (pageResources == null) {
pageResources = new PageResources();
PdfDictionary resources = pageN.getAsDict(PdfName.RESOURCES);
pageResources.setOriginalResources(resources, cstp.namePtr);
}
over = new PdfCopy.StampContent(cstp, pageResources);
}
return over;
}
// 真正修改相关内容.
public void alterContents() throws IOException {...}
// 省略N行代码
...
}
// 也是PdfCopy的静态内部类. 父类为PdfContentByte.
public static class StampContent extends PdfContentByte {
PageResources pageResources;
StampContent(PdfWriter writer, PageResources pageResources) {
super(writer);
this.pageResources = pageResources;
}
// 通过引用复制所有的内容.
@Override
public PdfContentByte getDuplicate() {
return new PdfCopy.StampContent(writer, pageResources);
}
@Override
PageResources getPageResources() {
return pageResources;
}
}
下边为分开一个Pdf文件.
PdfReader reader = new PdfReader(MovieTemplates.RESULT);
Document document;
PdfCopy copy;
int n = reader.getNumberOfPages();
for (int i = 0; i < n; ) {
document = new Document();
copy = new PdfCopy(document, new FileOutputStream(String.format(RESULT, ++i)));
document.open();
copy.addPage(copy.getImportedPage(reader, i));
document.close();
}
这就是PdfCopy的特殊之处, 比PdfStamper更好使用. 也方便使用. 既可以合并一个文档, 并作修改, 也可以分开一个文档.这就是我们今天的内容了.