[更文挑战]iText番盘-PDF神器-25

293 阅读3分钟

「这是我参与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更好使用. 也方便使用. 既可以合并一个文档, 并作修改, 也可以分开一个文档.这就是我们今天的内容了.