掌握iText:轻松实现固定pdf模板的动态数据填充

++++

推荐语

如果你在工作中需要处理大量的PDF表单,那么使用iText5实现固定PDF模板的动态数据填充,将是一种非常有效的方法。这篇技术文章详细介绍了如何使用iText5库来读取已有的PDF模板,并动态地填充表单数据,生成最终的表单文件。通过这种方法,你可以大大提高工作效率,同时保证表单的格式和布局的统一性。无论你是企业员工、自由职业者还是个人用户,都可以从中受益。如果你想要掌握这种有用的技术,不妨看看这篇文章,相信会对你有所帮助。

需求描述

在工作和生活中,很多人都会遇到需要填写各种业务表单的情况。这些表单可能是申请表、报销单、登记表等,而这些表单通常都有着相对固定的格式和结构。为了简化流程并提高效率,许多组织和机构会事先设计好这些表单的PDF模板,并通过动态填充数据来生成最终的表单文件。

当我们面临这样的需求时,可以将预先设计好的PDF模板作为基础,根据实际情况动态地将数据填充到模板中。这样一来,我们就能够快速生成符合要求的表单文件,并可以选择将其导出或打印出来。通过动态填充数据到PDF模板中,我们可以确保所填写的信息准确无误地呈现在最终的表单文件中。这不仅节省了手工填写表格的时间和劳动力,还可以避免由于繁琐的手续或人为因素导致的错误。此外,使用固定格式的PDF模板还能确保表单的格式和布局的统一性,使得生成的表单文件具有更加专业和规范的外观。这对于企业和组织来说尤为重要,因为这些表单通常涉及到重要的业务流程和决策。

那么怎么实现这需求呢?这里提供一种方法:使用iText5来创建pdf模板和填充数据。

环境配置

XML 复制代码
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13.2</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>

具体实现

创建模板

使用iText创建一个pdf模板相对比较简单,这里以创建一个简单的表格模板为例,梳理一下具体的步骤:

  1. 首先,代码创建一个名为"form-template.pdf"的PDF文档对象,并设置文档大小为A4纸张大小。
  2. 然后创建了一个PdfWriter对象,用于将生成的PDF文档写入到文件中。
  3. 打开文档并添加页面。
  4. 创建一个包含两列的表格对象,并设置表格的宽度百分比、上下间距等属性。
  5. 向表格中添加标题行,标题为"Table Form",并设置字体样式为Helvetica、粗体等。
  6. 接着向表格中添加数据行,每行包括一个标签和一个文本输入框。每个文本输入框都使用TextField对象创建,并通过FieldCell对象包装成一个可添加到表格中的单元格。
  7. 将创建好的表格添加到文档中。
  8. 最后关闭文档,并输出"表格表单生成成功!"的提示信息。
java 复制代码
@Test
public void test() throws IOException, DocumentException {
    String fileName = "d:/pdf/form-template.pdf";
    // 创建一个PDF文档对象
    Document pdf = new Document(PageSize.A4);
    PdfWriter writer = PdfWriter.getInstance(pdf, new FileOutputStream(fileName));
    // 打开文档并添加页面
    pdf.open();
    pdf.newPage();
    // 创建表格对象
    PdfPTable table = new PdfPTable(2);
    table.setWidthPercentage(100);
    table.setSpacingBefore(20f);
    table.setSpacingAfter(20f);
    // 添加表格标题行
    PdfPCell cell = new PdfPCell(new Phrase("Table Form", new Font(Font.FontFamily.HELVETICA, 14, Font.BOLD)));
    cell.setColspan(2);
    cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
    table.addCell(cell);
    // 添加表格数据行
    table.addCell("Name:");
    cell = new PdfPCell();
    TextField textField = new TextField(writer, new Rectangle(0, 0), "name");
    FieldCell fieldCell = new FieldCell(textField);
    cell.setCellEvent(fieldCell);
    table.addCell(cell);
    table.addCell("Age:");
    cell = new PdfPCell();
    textField = new TextField(writer, new Rectangle(0, 0), "age");
    fieldCell = new FieldCell(textField);
    cell.setCellEvent(fieldCell);
    table.addCell(cell);
    // 将表格添加到文档中
    pdf.add(table);
    // 关闭文档
    pdf.close();
    System.out.println("表格表单生成成功!");
}

填充数据

在上面的示例中,使用iText5创建了一个含有表格的pdf模板,这里演示一下如何使用iText5向含有表格的pdf模板中动态填充数据如何实现,实现逻辑也是比较简单的,具体步骤:

  1. 首先,代码读取一个名为"form-template.pdf"的PDF模板文件。
  2. 然后创建一个PdfStamper对象,用于向模板中填充数据并生成新的PDF文档。
  3. 获取模板中的所有表单域,使用setField()方法填充表单域的值。
  4. 将PDF文档中的表单域转换为普通文本。
  5. 最后关闭PdfStamper和PdfReader对象,并输出"数据填充成功!"的提示信息。
  6. 除此之外,代码中还定义了两个辅助方法:createFormField()和FieldCell类。createFormField()方法用于创建一个包含TextField对象的单元格,FieldCell类定义了用于创建表单域的单元格事件。这些辅助方法的作用是将PDF文档中的表单域转换成可编辑的输入框,使得用户可以手动输入数据并提交表单。
java 复制代码
@Test
public void test2(){
    try {
        String templateName="d:/pdf/form-template.pdf";
        String outputFileName="d:/pdf/form-data.pdf";
        // 使用PdfReader读取模板文件,并向模板中填充数据
        PdfReader reader = new PdfReader(templateName);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFileName));
        AcroFields form = stamper.getAcroFields();
        form.setField("name", "John Doe");
        form.setField("age", "30");
        stamper.setFormFlattening(true); // 将表单域转换为普通文本
        stamper.close();
        reader.close();
        System.out.println("数据填充成功!");
    } catch (IOException | DocumentException e) {
        e.printStackTrace();
    }
}

// 创建一个表单域
private static PdfPCell createFormField(String fieldName, PdfWriter writer) throws IOException, DocumentException {
    PdfPCell cell = new PdfPCell();
    Rectangle rectangle = new Rectangle(0, 0);
    TextField field = new TextField(writer, rectangle, fieldName);
    cell.setCellEvent(new FieldCell(field));
    return cell;
}

// 定义用于创建表单域的单元格事件
private static class FieldCell implements PdfPCellEvent {
    private final TextField textField;

    public FieldCell(TextField textField) {
        this.textField = textField;
    }

    @Override
    public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
        PdfWriter writer = canvases[0].getPdfWriter();
        PdfFormField field = null;
        try {
            field = textField.getTextField();
        } catch (IOException | DocumentException e) {
            throw new RuntimeException(e);
        }
        field.setWidget(new Rectangle(position.getLeft(), position.getBottom(), position.getRight(), position.getTop()), PdfAnnotation.HIGHLIGHT_INVERT);
        writer.addAnnotation(field);
    }
}

写在最后

非常厉害,这么有耐心地阅读完本篇文章,这篇内容详细介绍了如何使用iText5库实现固定PDF模板的动态数据填充技术实现方法,如果觉得对您有帮助,请点赞并收藏,方便以后查阅!

相关推荐
Asthenia041226 分钟前
Spring扩展点与工具类获取容器Bean-基于ApplicationContextAware实现非IOC容器中调用IOC的Bean
后端
bobz96544 分钟前
ovs patch port 对比 veth pair
后端
Asthenia04121 小时前
Java受检异常与非受检异常分析
后端
uhakadotcom1 小时前
快速开始使用 n8n
后端·面试·github
JavaGuide1 小时前
公司来的新人用字符串存储日期,被组长怒怼了...
后端·mysql
bobz9651 小时前
qemu 网络使用基础
后端
Asthenia04122 小时前
面试攻略:如何应对 Spring 启动流程的层层追问
后端
Asthenia04122 小时前
Spring 启动流程:比喻表达
后端
Asthenia04122 小时前
Spring 启动流程分析-含时序图
后端
ONE_Gua2 小时前
chromium魔改——CDP(Chrome DevTools Protocol)检测01
前端·后端·爬虫