一、前言
本篇文章是实现填充PDF模板并生成图片,代码中使用到根据占位符添加文本和图片,以及根据横纵坐标,偏移量添加勾选“√”,大佬们有不足的地方可直接指出,java萌新成长之路
二、PDF准备
通过第三方工具给我们的PDF添加输入框并标记占位符,修改完成后直接保存下载
三、依赖
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<!-- iText -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.2</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>kernel</artifactId>
<version>7.1.16</version> <!-- Use the version that suits your project -->
</dependency>
<!-- pdfbox -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.24</version>
</dependency>
四、测试demo
1)测试方法
public static void main(String[] args) {
String basePath = "D:\\storage\\pdf-demo";
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("chineseName", "刘志");
dataMap.put("englishName", "LiuZhi");
dataMap.put("idNumber", "34122119740702392X");
dataMap.put("dataOfIssue", "2018-08-11");
dataMap.put("dateOfExpiry", "2034-08-11");
dataMap.put("nationality", "CHN");
dataMap.put("create_time", "2024-12-20");
Map<String, Object> imageMap = new HashMap<>();
imageMap.put("img_af_image", basePath + "/20241220105431.png");
Map<String, Object> formMap = new HashMap<>();
formMap.put("dataMap", dataMap);
formMap.put("imageMap", imageMap);
formMap.put("sex", "F");
String imgPath = basePath + "/img/AAA";
String pdfPath = basePath + "/QQF_SQ_1.pdf";
try {
fillPDFTemplate(formMap, pdfPath, imgPath);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}
2)实现代码
/**
* 填充PDF模板并生成图片
*
* @param sourceMap 数据源Map
* @param newPdfPath 新的PDF路径
*/
public static void fillPDFTemplate(Map<String, Object> sourceMap, String PdfPath, String newPdfPath) throws IOException, DocumentException {
PdfReader reader = new PdfReader(PdfPath);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, bos);
AcroFields form = stamper.getAcroFields();
String sex = sourceMap.get("sex").toString();
if ("M".equals(sex)) {
addTextByXY(stamper, 170, 705, 14);
} else {
addTextByXY(stamper, 200, 705, 14);
}
BaseFont baseFont;
if (isWindowsSystem()) {
baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
} else {
// 设置 SimSun 字体
baseFont = BaseFont.createFont("/usr/share/fonts/chinese/SIMSUN.TTC,0", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
}
// 处理文字内容
Map<String, String> dataMap = (Map<String, String>) sourceMap.get("dataMap");
for (Map.Entry<String, String> entry : dataMap.entrySet()) {
String value = formatValue(entry.getValue());
Font font = new Font(baseFont, 9);
form.setFieldProperty(entry.getKey(), "textfont", baseFont, null);
form.setFieldProperty(entry.getKey(), "textsize", (font.getSize()), null);
form.setField(entry.getKey(), value);
}
// 处理图片内容
Map<String, Object> imageMap = (Map<String, Object>) sourceMap.get("imageMap");
for (Map.Entry<String, Object> entry : imageMap.entrySet()) {
String imgpath = entry.getValue().toString();
if (form.getFieldPositions(entry.getKey()) != null) {
int pageNo = form.getFieldPositions(entry.getKey()).get(0).page;
com.itextpdf.text.Rectangle signRect = form.getFieldPositions(entry.getKey()).get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
Image image = Image.getInstance(imgpath);
PdfContentByte under = stamper.getOverContent(pageNo);
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
image.setAbsolutePosition(x, y);
under.addImage(image);
}
}
stamper.setFormFlattening(true);
stamper.close();
// 将填充后的PDF转换为图片
PDDocument pdDocument = PDDocument.load(new ByteArrayInputStream(bos.toByteArray()));
PDFRenderer pdfRenderer = new PDFRenderer(pdDocument);
ImageIO.setUseCache(false);
BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(0, 300, ImageType.RGB);
// 创建目标文件夹
File targetFolder = new File(newPdfPath);
if (!targetFolder.exists()) {
targetFolder.mkdirs();
}
ImageIO.write(bufferedImage, "jpg", new File(newPdfPath + "/" + "_4.jpg"));
reader.close();
bos.close();
pdDocument.close();
}
public static boolean isWindowsSystem() {
String property = System.getProperty("os.name").toLowerCase();
return property.contains("windows");
}
/**
* 格式化值为字符串
*
* @param value 要格式化的值
* @return 格式化后的字符串
*/
private static String formatValue(Object value) {
if (value instanceof Date) {
return DATE_FORMAT.format((Date) value);
}
return value.toString();
}
private static void addTextByXY(PdfStamper stamper, Integer x, Integer y, Integer size) throws DocumentException, IOException {
PdfContentByte content = stamper.getOverContent(1);
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
content.beginText();
content.setFontAndSize(base, size);
content.showTextAligned(Element.ALIGN_CENTER, "√", x, y, 0);
content.endText();
}
五、效果展示