PDF模板制作与填充(Java)
1.PDF模板制作
- 准备原始模板
准备一个原始PDF模板,可以编辑好Word,预留出要填充的部分,再转换成PDF格式。
- 设置表单域
用任意PDF编辑器打开PDF模板文件,设置表单域,下面以WPS为例:
拖动文本域到需要填充的位置,调整区域大小和位置,然后双击设置文本域属性
此处我添加了3个文本域,分别是NAME(姓名)、GENDER(性别)、IDNUMBER(身份证号),然后保存即可。
2.相关依赖
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.1.2</version>
</dependency>
3.模板填充
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.控制台输出
生成完毕:E:\test\pdf\目标PDF.pdf