- 引入依赖包。
<!-- 生成pdf文件 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.10</version>
</dependency>
<!-- 识别中文汉字 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
- 使用工具处理PDF模板,添加文本域、复选框域。如使用福晰阅读器工具:
-
文本域
-
复选框,注意此处设置复选框是否勾选的值为:Yes。
3、工具类
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import java.io.*;
import java.util.List;
import java.util.Map;
public class PDFUtil {
/**
* @param templateName 模板路径
* @param outputFileUrl 生成新文件路径
* @param map 数据集
* @param imageMap 图片集
* @return
*/
public static File pdfTemplateInsert(String templateName, String outputFileUrl, Map<String,Object> map,Map<String,String> imageMap) {
//临时文件
File tmpFile = new File(outputFileUrl);
//临时文件输出文件流
OutputStream os = null;
//表单域
PdfStamper ps = null;
PdfReader reader = null;
try {
os = new FileOutputStream(tmpFile);
//获取模板文件流
//InputStream ins = new FileInputStream(templateName);
InputStream ins = PDFUtil.class.getResourceAsStream(templateName);
//读取pdf表单
reader = new PdfReader(ins);
//根据表单生成一个新的pdf文件
ps = new PdfStamper(reader, os);
//获取pdf表单
AcroFields form = ps.getAcroFields();
//给表单中添加中文字体
BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
form.addSubstitutionFont(bf);
//1、处理文本
Map<String,String> dataMap = (Map) map.get("dataMap");
if (!StringUtils.isEmpty(dataMap)) {
for (String key : dataMap.keySet()) {
//处理空值
if (StringUtils.isEmpty(dataMap.get(key))){
dataMap.put(key,"");
}
//处理文本
form.setField(key, dataMap.get(key));
}
}
//2、处理复选框
Map<String,String> checkMap = (Map) map.get("checkMap");
if (!StringUtils.isEmpty(checkMap)) {
for (String key : checkMap.keySet()) {
//注意此处设置复选框是否勾选的值为:Yes,和PDF模板复选框对应
form.setField(key, "Yes", true);
}
}
//3、处理图片
if (!StringUtils.isEmpty(imageMap)) {
for (String key : imageMap.keySet()) {
insertImagePro(form, ps, key, imageMap.get(key));
}
}
/*必须要调用这个,否则文档不会生成的 如果为false那么生成的PDF文件还能编辑,一定要设为true*/
ps.setFormFlattening(true);
ps.close();
} catch (Exception e) {
System.out.println(e.getMessage());
throw new RuntimeException("处理PDF模板失败!");
} finally {
try {
if (os != null) {
os.flush();
os.close();
}
if (reader != null) {
reader.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return tmpFile;
}
/**
* 添加图片
*
* @param form pdf表单
* @param stamper 表单域
* @param key 文本域主键标识
* @param url 图片url
* @throws IOException
* @throws DocumentException
*/
private static void insertImagePro(AcroFields form, PdfStamper stamper, String key, String url) throws DocumentException {
//根据文本域主键标识,获取所在页码
List<AcroFields.FieldPosition> list = form.getFieldPositions(key);
if (StringUtils.isEmpty(list) || list.size() < 1) {
return;
}
int pageNo = list.get(0).page;
//获取文本域位置信息
Rectangle signRect = form.getFieldPositions(key).get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
// 图片临时文件流
InputStream ins = FileUtils.getInputStreamByURL(url, "");
Image image = getImageFromInputStream(ins);
// 获取操作的页面
PdfContentByte under = stamper.getOverContent(pageNo);
// 根据域的大小缩放图片
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
// 添加图片
image.setAbsolutePosition(x, y);
under.addImage(image);
}
/**
* @param inputStream
* @return 将InputStream转化为Image
* @throws Exception
*/
public static Image getImageFromInputStream(InputStream inputStream) {
Image image = null;
try {
int n;
byte[] buffer = new byte[4096];
ByteArrayOutputStream output = new ByteArrayOutputStream();
while (-1 != (n = inputStream.read(buffer))) {
output.write(buffer, 0, n);
}
image = Image.getInstance(output.toByteArray());
} catch (Exception e) {
}
return image;
}
}
- 测试
public static void main(String[] args) {
//模板路径
String inputUrl = "C:\\Users\\issuser\\Desktop\\文件\\test.pdf";
//生成的文件路径
String outputUrl = "C:\\Users\\issuser\\Desktop\\文件\\yyh-test.pdf";
Map<String, Object> map = new HashMap<>();
//文本数据
Map dateMap = new HashMap();
dateMap.put("text","文字");
//复选框数据
Map checkMap = new HashMap();
checkMap.put("check",“Yes”);
map.put("dateMap",dateMap);
map.put("checkMap",checkMap);
//图片数据
Map<String, String> imageMap = new HashMap<>();
imageMap .put("url",url);
PDFUtil.pdfTemplateInsert(inputUrl, outputUrl, map, imageMap);
}