1. 依赖引入 --这里只包含额外引入的包 原有项目包不含括在内
xml
<!-- pdf编辑相关-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
2. pdf模板建立
- 首先需要准备一个可编辑的pdf文件,文件中要包含表单内容
- 为表单建立域(这里以Adobe Acrobat DC为例)
- 找到工具栏的准备表单,然后点击,如下图所示
- 针对域设置字段名
- 另存为此时文件就是一个pdf填充模板,后面代码实现可以直接使用
3. 代码实现--工具类可以直接使用(注意修改文件位置,需要提前准备好模板)
java
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
/**
* @desc: pdf编辑相关工具类
* @author: lc
* @since: 2023/12/13
*/
public class PdfUtils {
/**
* 利用模板生成pdf保存到某路径下
*/
public static void pdfOut(Map<String, Object> map) throws IOException, DocumentException {
// 模板路径
String templatePath = (String) map.get("templatePath");
//新的pdf文件
String newPdfPath = (String) map.get("newPdfPath");
//签字图片的地址
String signPath = (String) map.get("signPath");
File file1 = new File(newPdfPath);
if (!file1.exists()) {
try {
file1.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
//pdf模板文件
InputStream input = new FileInputStream(templatePath);
//生成的新文件
File file = new File(newPdfPath);
FileOutputStream fos = new FileOutputStream(file);
PdfReader reader = new PdfReader(input);
PdfStamper stamper = new PdfStamper(reader, fos);
// 提取PDF中的表单
AcroFields form = stamper.getAcroFields();
// 设置中文字体
String prefixFont = "";
String os = System.getProperties().getProperty("os.name");
if (os.startsWith("win") || os.startsWith("Win")) {
prefixFont = "C:\\Windows\\Fonts" + File.separator;
} else {
prefixFont = "/usr/share/fonts/chinese" + File.separator;
}
BaseFont baseFont = BaseFont.createFont(prefixFont + "simsun.ttc,0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
form.addSubstitutionFont(baseFont);
//文字类的内容处理
Map<String, String> datemap = (Map<String, String>) map.get("dateMap");
//填充值
for (String key : datemap.keySet()) {
String value = datemap.get(key);
//设置字体大小
form.setFieldProperty(key, "textsize", 12f, null);
form.setField(key, value);
}
//签名图片路径存在才进行图片合并
if (StringUtils.isNotBlank(signPath)){
//进行签字的填充
int pageNo = form.getFieldPositions("sign").get(0).page;
Rectangle signRect = form.getFieldPositions("sign").get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
//读取图片
Image image = Image.getInstance(signPath);
//获取操作的页面
PdfContentByte content = stamper.getOverContent(pageNo);
// 根据域的大小缩放图片
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
// 添加图片
image.setAbsolutePosition(x, y);
content.addImage(image);
fos.flush();
}
// 生成PDF
stamper.setFormFlattening(true);
stamper.close();
reader.close();
fos.close();
input.close();
}
public static void main(String[] args) throws DocumentException, IOException {
Map<String, Object> params = new HashMap<>();
//测试数据
HashMap<String, Object> map = new HashMap<>();
map.put("username","测试号");
map.put("name1","张三");
map.put("name2","李四");
map.put("sex","男");
map.put("address","8号楼");
//需要赋值的模板内容
params.put("dateMap",map);
//模板位置
String templatePath = "C:\\Users\\lc\\Desktop\\test.pdf";
//新生成pdf文件位置
String newPdfPath = "C:\\Users\\lc\\Desktop\\test1.pdf";
//签名图片位置
String signPath = "C:\\Users\\lc\\Desktop\\qs.png";
params.put("templatePath",templatePath);
params.put("newPdfPath",newPdfPath);
params.put("signPath",signPath);
pdfOut(params);
}
}
部署到linux服务器上可能存在字体不存在的问题,可以在linux下载对应的字体或者将window中的字体拷贝到linux上,这里就不详述了可以自行百度