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

142 阅读3分钟

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

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

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

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

一. 前言

<天道>中有这样一段经典对话

芮小丹: "书店里教人炒股的满柜台都是, 怎么到了你这儿连说都不能说了."

丁元英说: 真有赚钱的秘笈人家能告诉你? 能那样赚钱也就不用写书了.

最近本人就在看天道这个电视剧, 名场面较多, 而且涉及的只是也很多. 我们能从中学到的不只是经典语录, 更重要的是能学到很多实用和悟到一些道理.

对于开发人员来说, 赚钱的秘笈确实很多写在了书里, 只要你学到, 就可以卷别人. 人家写书就是赚到了这部分钱, 而且为了更系统的复习, 才写书. 所以这句话其实并不是绝对的对, 但是对于炒股我想是对的.

二.正文.

1.3 PdfStamper继续探究

上一篇提到 PdfStamper#getOverContent(); 其实他还有另一个方法 即: PdfStamper#getUnderContent() 类似于 PdfWriter#getDirectContentUnder(). 他也返回PdfContentByte类.

PdfStamper源码 使用了委托模式, 真正处理的是 PdfStamperImp 类.

之前我们就提到了Pdf中可以使用 AcroFields 字段来生成一个表单, 用以实现相关需求. 也就是说我们可以准备一个特定格式的待填充多个局部小字段的Pdf文件, 然后填充好以后成为一个真正的Pdf文件, 相当于模板模式.或者说模板引擎的方式.

当然我们可以使用不同的软件生成此模板, 然后要使用一个可以向Pdf添加form表单的软件. 在这里我想大家推荐2款软件: Open OfficePDFelement

  • Open Office, 是Apache基金会推出的一套免费的跨平台的办公室软件套件, 如果你想使用它添加Form表单, 首先需要将他保存为 ODT文件,然后另存为Pdf文档(Export as PDF).但是要确保PdfOption中 CreatePDF form的选项是选中的
  • PDFelement, 是万兴推出的一款付费软件, 口号为: 操作简单,像Word一样编辑PDF文档, 使用起来更方便. 作为开发人员, 可以漂(非错别字, 只是意思)下, 你懂的.

当整好此文件时, 使用Adobe Pdf Reader打开, 向field中填充字段, 是无法保存的. 当然也有可以保存的, 具体要看是什么样的软件弄得什么样的Form. 我们可以使用编程的方式, 来达到我们的目的, 即使用 iText 的PdfStamper来实现. 那怎样实现呢?

    // 要填充的内容, key为设置Form时 设置好的字段name
    Map<String,String> dataModel;
    PdfReader reader = new PdfReader(FORM_PDF_RESOURCE);
    PdfStamper stamper = new PdfStamper(reader, bos);
    // 获取所有的Fields
    AcroFields form = stamper.getAcroFields();
    // 设置字体
    form.addSubstitutionFont(bf);
    // 设置字段的值.
    for (String key : dataModel.keySet()) {
        String value = dataModel.get(key);
        form.setField(key, value);
    }
    // 下边就是要设置是否可以编辑的, 也就是我们使用Adobe Pdf Reader时编辑完还可以编辑的一个设置.
    // 如果为false,生成的PDF文件表单可以编辑,
    // 如果为true,生成的PDF文件表单不可以编辑
    stamper.setFormFlattening(true);
    Document doc = new Document();
    PdfCopy copy = new PdfCopy(doc, out);
    doc.open();
    stamper.close();

    PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);
    copy.addPage(importPage);
    doc.close();