方法一
依赖
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.13</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.10</version>
</dependency>
代码参考
PDFUtil工具类
/**
* 根据模板生成pdf
*@param pdfName 文件名
* @param data Map(String,Object)
* @return 文件保存全路径文件
*/
import cn.hutool.core.date.DateUtil;
import com.itextpdf.text.DocumentException;
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 lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
/**
* @author lin
*/
@Slf4j
public class PDFUtil {
public static String createPDF(String pdfName, Map<String, Object> data) {
//静态方法只能使用匿名类
String file = new Object() {
public String getPath() {
return Objects.requireNonNull(this.getClass().getResource("/")).getPath();
}
}.getPath();
System.out.println(file);
String dateFolder = DateUtil.today();
String folderPath = file + File.separator + dateFolder;
//创建上传文件目录
File folder = new File(folderPath);
if (!folder.exists()) {
folder.mkdirs();
}
//设置文件名
String fileName = "_"+pdfName + ".pdf";
String savePath = folderPath + File.separator +DateUtil.today() + fileName;
try {
PdfReader reader = new PdfReader(file+"/TEMP.pdf");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PdfStamper ps = new PdfStamper(reader, bos);
AcroFields s = ps.getAcroFields();
//TTC字体一般有多个所以选择正常的加载
BaseFont bfChinese = BaseFont.createFont(file+"/MSYH.TTC,1", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
//设置编码格式
s.addSubstitutionFont(bfChinese);
//这点可以直接传对象,但是怕变动,所以map好自定义一个值
for (String key : data.keySet()) {
if (data.get(key) != null) {
s.setField(key, data.get(key).toString());
}
}
ps.setFormFlattening(true);
ps.close();
FileOutputStream fos = new FileOutputStream(savePath);
fos.write(bos.toByteArray());
fos.flush();
fos.close();
return savePath;
} catch (IOException | DocumentException e) {
log.error("读取文件异常");
e.printStackTrace();
return "error";
}
}
}
import cn.hutool.core.bean.BeanUtil;
import com.example.demopdf.entry.PdfData;
import com.example.demopdf.utils.PDFUtil;
import java.util.Map;
/**
* @program: cherrypro
* @description:
* @author: lin
* @create: 2021-06-15 23:56
*/
public class TestDemo {
public static void main(String[] args) {
//你可以直接构造,我这里建造者模式
PdfData data = PdfData.builder()
.text1("XXXXX保险")
.text2("1111111111111111111")
.text3("一个小朋友")
.text4("女")
.text5("24")
.text6("1997-01-05")
.text7("12345619951215741X")
.text8("185")
.text9("45")
.text10(" ")
.text11(" ")
.text12(" ")
.text13("我希望你读很多书,走很远的路。 我希望你爱很多人,
也被很多人爱。 我希望你走过人山人海,也遍览山河湖海。我希望你看纸质书,送手写的祝福。
我要你独立坚强温暖明亮, 我要你在这寡淡的世上,深情的活。")
.text14("木木")
.text15("2021")
.text16("07")
.text17("04")
//这个选择框模版有bug,所以默认全部打勾,不需要的取消
.ch1("false")
.ch4("false")
.build();
Map<String, Object> map = BeanUtil.beanToMap(data);
String s = PDFUtil.createPDF("ayi",map);
System.out.println(s);
}
}
模板图片
数据域图片
生成结果
后记:做这个坑在于checkbox
,选择时候和理想不一样,代码操作选择就是×
,所以反其道行之,这个版本做的并不满意,希望那位小朋友顺利搞完
有空的话,会升级下itextpdf
版本,官方已经停止5.0
,现在推荐7.0
,的确7.0
简单,之后会放在GitHub。
方法二
pom依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.2</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf/itext7-core -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.1.15</version>
<type>pom</type>
</dependency>
PDFUtil工具类
package com.example.demopdf.utils;
import cn.hutool.core.bean.BeanUtil;
import com.example.demopdf.entry.PdfData;
import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.forms.fields.PdfFormField;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* iText Pdf属性表单数据填充
*/
public class PDFUtil {
/**
* 简单文本填充
*
* @param src 原始文件路径
* @param out 输出文件路径
* @param map 填充数据
* @return
* @throws Exception
*/
public static byte[] fileProcess(String src, String out, Map<String, Object> map) throws Exception {
//输出流
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
//获取文档
PdfDocument pdfDoc = new PdfDocument(new PdfReader(new File(src)), new PdfWriter(new File(out)));
//转换为表单
PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, false);
//属性填充
for (Map.Entry<String, Object> entry : map.entrySet()) {
form.getField(entry.getKey()).setValue((String) entry.getValue());
}
//锁定字段
form.flattenFields();
pdfDoc.close();
return outputStream.toByteArray();
}
public static void main(String[] args) throws Exception {
String file = new Object() {
public String getPath() {
return Objects.requireNonNull(this.getClass().getResource("/")).getPath();
}
}.getPath();
PdfData data = PdfData.builder()
.text1("xxxxxxx保险")
.text2("1111111111111111111")
.text3("xxx")
.text4("女")
.text5("24")
.text6("1997-01-05")
.text7("12345619951215741X")
.text8("185")
.text9("45")
.text10(" ")
.text11(" ")
.text12(" ")
.text13("我希望你读很多书,走很远的路。 我希望你爱很多人,也被很多人爱。 我希望你走过人山人海,也遍览山河湖海。 我希望你看纸质书,送手写的祝福。 我要你独立坚强温暖明亮, 我要你在这寡淡的世上,深情的活。")
.text14("木木")
.text15("2021")
.text16("07")
.text17("04")
//这个选择框模版好像不对,但就是这个意思,我忘记对勾了
.ch1("on")
.ch2("off")
.ch3("off")
.ch4("on")
.ch15("是")
.ch16("on")
.build();
Map<String, Object> map = BeanUtil.beanToMap(data);
String local = file + "Temp.pdf";
String pdf = file + "demo.pdf";
byte[] strings = fileProcess(local, pdf, map);
}
}