PDF模板制作与填充(Java)

1.PDF模板制作
  • 准备原始模板

准备一个原始PDF模板,可以编辑好Word,预留出要填充的部分,再转换成PDF格式。

  • 设置表单域

用任意PDF编辑器打开PDF模板文件,设置表单域,下面以WPS为例:



拖动文本域到需要填充的位置,调整区域大小和位置,然后双击设置文本域属性




此处我添加了3个文本域,分别是NAME (姓名)、GENDER (性别)、IDNUMBER(身份证号),然后保存即可。

2.相关依赖
xml 复制代码
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.1.2</version>
</dependency>
3.模板填充
java 复制代码
package com.visy.utils;

import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author visy.wang
 * @date 2024/11/7 18:29
 */
public class PdfUtil {
    private final static Logger logger = LoggerFactory.getLogger(PdfUtil.class);

    /**
     * PDF模板填充
     * @param tmplUrl 模板地址(可以是本地文件路径,也可以是Url)
     * @param targetFile 目标PDF(基于模板填充后的输出)
     * @param fieldMap 表单域(<表单域名称,表单域填充值>)
     */
    public static void templateFill(String tmplUrl, File targetFile, Map<String, Object> fieldMap){
        ByteArrayOutputStream bos = null;
        FileOutputStream fos = null;
        try {
            PdfReader reader = new PdfReader(tmplUrl);
            PdfStamper ps = new PdfStamper(reader, bos = new ByteArrayOutputStream());

            AcroFields acroFields = ps.getAcroFields();

            //解决中文
            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
            acroFields.addSubstitutionFont(bfChinese);

            //模板表单域赋值
            Map<String, AcroFields.Item> fields = acroFields.getFields();
            for (Map.Entry<String, AcroFields.Item> field : fields.entrySet()) {
                String fieldName = field.getKey();
                if(Objects.nonNull(fieldName) && fieldMap.containsKey(fieldName)){
                    Object fieldValue = fieldMap.get(fieldName);
                    acroFields.setField(fieldName, Objects.isNull(fieldValue) ? "" : fieldValue.toString());
                }
            }

            ps.setFreeTextFlattening(true);
            ps.setFormFlattening(true);
            ps.close();

            fos = new FileOutputStream(targetFile);
            fos.write(bos.toByteArray());
            fos.flush();
        }catch (Exception e){
            logger.info("fillPdfTemplate error: {}", e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }finally {
            try{
                if(Objects.nonNull(fos)){
                    fos.close();
                }
                if(Objects.nonNull(bos)){
                    bos.close();
                }
            }catch(Exception e){
                logger.info("fillPdfTemplate close error: {}", e.getMessage(), e);
            }
        }
    }

    public static void main(String[] args) {
        String tmplUrl = "E:\\test\\pdf\\PDF测试模板.pdf";
        File targetFile = new File("E:\\test\\pdf\\目标PDF.pdf");
        Map<String,Object> fieldMap = new HashMap<>();
        fieldMap.put("NAME", "张三");
        fieldMap.put("GENDER", "男");
        fieldMap.put("IDNUMBER", "513126198803120435");

        //基于模板生成文件
        templateFill(tmplUrl, targetFile, fieldMap);

        System.out.println("生成完毕:"+targetFile.getAbsolutePath());
    }
}
4.控制台输出
java 复制代码
生成完毕:E:\test\pdf\目标PDF.pdf
5.目标PDF
相关推荐
程序员黎剑7 小时前
Spring-Bean生命周期-构造器访问Autowired字段为null
java·后端·spring
古法安卓7 小时前
Android-重启流程源码解析
android·java·android studio
清水白石0087 小时前
Python 类型设计深度解析:TypedDict 能否替代 dataclass?从 JSON 数据边界到 API 设计的最佳实践
java·python·json
晊晌_h8 小时前
嵌入式从0到精通——线程
java·开发语言·jvm
一木 之林8 小时前
五、C++ 新特性、关键字与编译原理(进阶)(二)
java·开发语言·c++
洋不写bug8 小时前
绕过权限检查,访问修改私有属性,反射,枚举,lambda
java·枚举·lambda·反射
evans在进步8 小时前
Java 常用设计模式入门:建造者、工厂、单例、外观与代理
java·python·设计模式
lisin-lee-cooper8 小时前
【leetcode658】有序数组找出k个最接近x的数
java·数据结构·算法
sunburn-9 小时前
Java堆(Heap)详解与实战教学
java·开发语言·数据结构·ide·算法
Kyrie_kk9 小时前
Java--TimeUnit时间单位枚举类(时间单位规范)
java·后端