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

210 阅读3分钟

「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战

PDF神器iText英文版翻译与学习

作者: 薛大郎.
英文原版: iText in Action 2nd Edition.pdf

坚持. 分享. 成长. 利他 !

一. 前言

Valentine's Day

今天就是情人节了. 你是否收到礼物了?!

其实今天还是今天, 也是正常过, 只是要多花点钱, 为两人之间的关系加一个对对方好的理由, 如果没有这样的对方, 那我们还是正常过好这一天.

其实我们的情人可能有很多, 比如第一肯定是爱人, 第二才是你自己, 第三就是你的孩子. 第四就是你和爱人的父母. 这些最爱的亲人都是你真诚以待的人. 但是只有你的爱人和你自己才能拍陪你走完这一生.

二.正文.

1.4 使用PdfCopy来复制页面

上一节我们学了使用PdfCopy来复制Pdf页面并拆分和合并页面. 但是如果你真的实验了, 那你会发现使用PdfCopy出来的一些文件可能会占用空间是之前文件的好多倍. 对于Pdf这种特殊的文件来说, 本来内容看起来一摸一样的文件怎么占用空间差距这么大呢?

带着这个问题, 我们先来看下源码:

/**
 * PdfSmartCopy extends PdfCopy extends PdfWriter
 * 当你看PdfSmartCopy的文档注释的时候, 就找到了相应的答案, 顾名思义, PdfSmartCopy会将一些Pdf文件中的一些资源, 比如图片,字体等, 在内存中记录这些引用, 然后提高性能, 也减少Pdf文件复制出来的占用空间大小几乎与源文件相差不多. 
 */
public class PdfSmartCopy extends PdfCopy {

    /** 保存这些 stream 和 一些资源引用 */
    private HashMap<ByteStore, PdfIndirectReference> streamMap = null;
    private final HashMap<RefKey, Integer> serialized = new HashMap<RefKey, Integer>();

    /** Creates a PdfSmartCopy instance. */
    public PdfSmartCopy(Document document, OutputStream os) throws DocumentException {
        super(document, os);
        this.streamMap = new HashMap<ByteStore, PdfIndirectReference>();
    }
    
    省略大部分的源码
    ...

通过上边源码的分析, 不难看出来原因, 那是不是都应该使用PdfSmartCopy啊? iText实战指出, 这就是你要权衡的事情了:

  • 如果源文件的其他资源引用并不是很多, 而且要求性能也要求的不高, 并且生成的文件占用空间要求也不高, 清酒使用PdfCopy类.
  • 相反, 如果源文件的其他资源引用很多, 而且要求性能也极高, 越快越好, 而且不允许生成的文件占用空间尽可能小, 那就是用PdfSmartCopy类.

由于PdfSmartCopy直接继承自PdfCopy类, 所以可以完全直接替换, 下边就直接上代码:

    Document document = new Document();
    // PdfCopy copy = new PdfCopy(document, new FileOutputStream(RESULT));
    // TODO 直接替换就好了
    PdfSmartCopy copy = new PdfSmartCopy(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();

我们今天也将此章节学习完了, 主要学习了对于已存在的Pdf文件的复制文件, 添加页眉页脚生成新的文件, 合并和拆分文件, 以及学习了PdfCopy还有PdfSmartCopy的使用与分别.

今天的内容就先讲到这里, 由于时间有限.