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

news2024/11/26 9:56:24

推荐语

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

需求描述

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

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

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

环境配置

<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. 最后关闭文档,并输出"表格表单生成成功!"的提示信息。
@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文档中的表单域转换成可编辑的输入框,使得用户可以手动输入数据并提交表单。
@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模板的动态数据填充技术实现方法,如果觉得对您有帮助,请点赞并收藏,方便以后查阅!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1332487.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虚拟机的下载、安装(模拟出服务器)

下载 vmware workstation&#xff08;收费的虚拟机&#xff09; 下载vbox 网址&#xff1a;Oracle VM VirtualBox&#xff08;免费的虚拟机&#xff09; 以下选择一个下载即可&#xff0c;建议下载vbox&#xff0c;因为是免费的。安装的时候默认下一步即可&#xff08;路径最好…

Vue2从源码角度来回答一些常见的问题

1.请说一下Vue2响应式数据的理解&#xff08;先知道基本的问题在哪里&#xff0c;源码的角度来回答&#xff0c;用的时候会有哪些问题&#xff09; 可以监控一个数据的修改和获取操作。针对对象格式会给每个对象的属性进行劫持 Object.defineProperty 源码层面 initData ->…

卷积神经网络基础与补充

参考自 up主的b站链接&#xff1a;霹雳吧啦Wz的个人空间-霹雳吧啦Wz个人主页-哔哩哔哩视频这位大佬的博客 https://blog.csdn.net/m0_37867091?typeblog CNN的历史发展&#xff1a; 这一点老师上课的时候也有讲到&#xff0c;BP的出现对CNN的发展至关重要 卷积的特性&#x…

nodejs+vue+ElementUi大学新生入学系统的设计与实现1hme0

采用B/S模式架构系统&#xff0c;开发简单&#xff0c;只需要连接网络即可登录本系统&#xff0c;不需要安装任何客户端。开发工具采用VSCode&#xff0c;前端采用VueElementUI&#xff0c;后端采用Node.js&#xff0c;数据库采用MySQL。 涉及的技术栈 1&#xff09; 前台页面…

kubelet源码学习(二):kubelet创建Pod流程

本文基于Kubernetes v1.22.4版本进行源码学习 4、kubelet创建Pod流程 syncLoop()的主要逻辑是在syncLoopIteration()方法中实现&#xff0c;Pod创建相关代码只需要看处理configCh部分的代码 // pkg/kubelet/kubelet.go // 该方法会监听多个channel,当发现任何一个channel有数…

Springboot+vue的交通管理在线服务系统(有报告)。Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的交通管理在线服务系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的交通管理在线服务系统&#xff0c;采用M&#xff08;m…

hyper-v ubuntu 3节点 k8s集群搭建

前奏 搭建一主二从的k8s集群&#xff0c;如图所示&#xff0c;准备3台虚拟机。 不会创建的同学&#xff0c;可以看我上上篇博客&#xff1a;https://blog.csdn.net/dawnto/article/details/135086252 和上篇博客&#xff1a;https://blog.csdn.net/dawnto/article/details/135…

借势API,电商如何进行电商平台数据采集汇总分析?

电商数据采集的网页抓取数据、淘宝、天猫、京东等平台的电商数据抓取&#xff0c;网页爬虫、采集网站数据、网页数据采集软件、python爬虫、HTM网页提取、APP数据抓包、APP数据采集、一站式网站采集技术、BI数据的数据分析、数据标注等成为大数据发展中的热门技术关键词。那么电…

基于SpringBoot的瑜伽馆管理系统 JAVA简易版

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 瑜伽课程模块2.3 课程预约模块2.4 系统公告模块2.5 课程评价模块2.6 瑜伽器械模块 三、系统设计3.1 实体类设计3.1.1 瑜伽课程3.1.2 瑜伽课程预约3.1.3 系统公告3.1.4 瑜伽课程评价 3.2 数据库设计3.2.…

JavaScript系列——原型、原型链、继承

文章目录 前置话题原型定义作用例子说明获取对象原型 原型链定义例子说明原型链演示图 JavaScript 继承通过构造函数继承代码示例 自有属性小结更多内容 前置话题 JavaScript 是一门面向对象的编程语言&#xff0c;其中有一个特征就是可继承性&#xff0c;和java编程语言不同&…

史上最全,资深测试老鸟-接口测试总结,看这篇就足够了...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、什么是接口 接…

R语言基础 | 安徽某高校《统计建模与R软件》期末复习

第一节 数字、字符与向量 1.1 向量的赋值 c<-(1,2,3,4,5) 1.2 向量的运算 对于向量&#xff0c;我们可以直接对其作加&#xff08;&#xff09;&#xff0c;减&#xff08;-&#xff09;&#xff0c;乘&#xff08;*&#xff09;&#xff0c;除&#xff08;/&#xff09…

Python数据科学视频讲解:特征决策树分箱

5.3 特征决策树分箱 视频为《Python数据科学应用从入门到精通》张甜 杨维忠 清华大学出版社一书的随书赠送视频讲解5.3节内容。本书已正式出版上市&#xff0c;当当、京东、淘宝等平台热销中&#xff0c;搜索书名即可。内容涵盖数据科学应用的全流程&#xff0c;包括数据科学应…

网络安全行业证书【含金量排名】

文章目录 一、前言二、CISP三、CISAW四、NISP五、为什么很多人考不下来 一、前言 现在想找网络安全之类的工作&#xff0c;光有技术是不够的&#xff0c;还得有东西证明自己&#xff0c;网安三大敲门砖&#xff1a;CTF、漏洞证明和专业证书。 对于CTF的话只是少数人能参加的…

Lambda表达式超详解

目录 背景 Lambda表达式的用法 函数式接口 Lambda表达式的基本使用 语法精简 变量捕获 匿名内部类 匿名内部类中的变量捕获 Lambda的变量捕获 Lambda表达式在类集中的使用 Collection接口 List接口 Map接口 总结 背景 Lambda表达式是Java SE 8中的一个重要的新特性.…

swing快速入门(二十七)

注释很详细&#xff0c;直接上代码 上一篇 新增内容 1.为按钮指定图标 2. 列表框的并列 3.菜单项绑定快捷键 4.控件悬浮提示信息 5.菜单项设置小图标 6.五种布局风格右键选择切换 package swing21_30;import javax.swing.*; import java.awt.*; import java.awt.event.…

JBoss 5.x/6.x 反序列化 CVE-2017-12149 已亲自复现

JBoss 5.x/6.x 反序列化 CVE-2017-12149 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议总结 漏洞名称 漏洞描述 2017年8月30日&#xff0c;厂商Redhat发布了一个JBOSSAS 5.x 的反序列化远程代码执行漏洞通告。该漏洞位于JBoss的HttpInvoker组件中的…

HALCONVS .net混合编程案例【02】:检测芯片的管脚间距

前言&#xff1a; 本章给出的HALCON和Visual Studio的WPF项目中联合编程的案例。 VS中WPF的编程&#xff0c;UI的设计非常方便&#xff0c;如果结合HALCON的算法&#xff0c;可以很快实施机器视觉相关的应用。本例的应用&#xff0c;实现了自动检测的一个三洋的芯片的管脚的间…

实验五 用户进程管理-实验部分

目录 一、知识点 1.Unix进程创建API 1.1.创建新进程API 1.2.fork()地址空间的复制 1.4.shell中调用fork()图示 1.5.fork()创建进程个数示例 1.6.fork()与exec()的比较 2.实验执行流程概述 3.创建用户进程 3.1.应用程序的组成和编译 3.2.用户进程的虚拟地址空间 3.3…

初识QT(上篇):What Qt

初识QT&#xff08;上篇&#xff09;&#xff1a;What Qt 前言 & 说明前言说明 初识QT1.1 QT的what1. 介绍2. 发展历程3. QT架构的主要内容4.QT的常用模块 1.2 QT的 why1. QT的核心机制 下篇笔记链接 前言 & 说明 前言 前言&#xff1a; 之前说要share的qt相关知识&am…