一、项目依赖
1、maven版本:3.5.x
2、pom文件依赖
<!--itext的依赖jar-->
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
<type>pom</type>
</dependency>
二、所用工具类
package com.cloud.docment.pdf;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @Description: 按照pdf模板动态生成pdf
*/
public class Template2PdfUtils {
private static final Logger logger = LoggerFactory.getLogger(Template2PdfUtils.class);
private Template2PdfUtils() {
}
/**企业营业执照模板*/
public static final String COMPANY_TEMPLATE_PATH = "/com/cloud/docment/pdf/template/company_pdf_mb.pdf";
/**个体户*/
public static final String PERSONAL_TEMPLATE_PATH = "/com/cloud/docment/pdf/template/personal_pdf_mb.pdf";
/** 字体路径(宋体) */
private static final String DEFAULT_FONT_PATH = "/com/cloud/docment/picture/font/simsun.ttc,1";
/**
* 利用已有的pdf模板生成pdf(无图),外部模板中定义pdf表单域大小,位置以及允许换行等属性
* @param templatePath 模板路径
* @param newPdfPath 生成的新文件路径
* @param data 封装数据
*/
public static void outPdfFile(String templatePath, String newPdfPath, Map<String,String> data) {
PdfReader reader = null;
PdfStamper stamper = null;
try(FileOutputStream out = new FileOutputStream(newPdfPath);
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024)) {
//设置字体com/cloud/docment/picture/font/simsun.ttc
BaseFont bf = BaseFont.createFont(DEFAULT_FONT_PATH, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
//设置字体大小
/**Font chineseFont = new Font(bf, 14, Font.NORMAL, BaseColor.BLACK);*/
// 读取pdf模板
reader = new PdfReader(templatePath);
stamper = new PdfStamper(reader, bos);
/* 获取模版中的表单域字段 */
AcroFields form = stamper.getAcroFields();
//文字类的内容处理
//设置表单域中的格式
form.addSubstitutionFont(bf);
textFill(data, form);
// 如果为false,生成的PDF文件可以编辑,如果为true,生成的PDF文件不可以编辑
stamper.setFormFlattening(true);
stamper.close();
tempCopyPdf(out, bos);
/**out.write(bos.toByteArray());*/
out.flush();
logger.info("生成pdf处理完成");
} catch (IOException e) {
logger.info("outPdfFile生成本地,IO异常{}", e.getMessage());
} catch (DocumentException e) {
logger.info("outPdfFile生成本地,pdf操作异常{}", e.getMessage());
}
}
/**
* 利用已有的pdf模板生成pdf(无图),返回
* @param templatePath 模板路径
* @param data
*/
/**
* 利用已有的pdf模板生成pdf(无图),返回ByteArrayOutputStream
* @param templatePath 模板路径(允许为空,为空时使用个体工商模板)
* @param data 数据集
* @return ByteArrayOutputStream数据
*/
public static ByteArrayOutputStream outPdfFile(String templatePath, Map<String,String> data) {
PdfReader reader = null;
PdfStamper stamper = null;
try(OutputStream out = new ByteArrayOutputStream(1024);
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024)) {
//设置字体com/cloud/docment/picture/font/simsun.ttc
BaseFont bf = BaseFont.createFont(DEFAULT_FONT_PATH, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
//设置字体大小
/**Font chineseFont = new Font(bf, 14, Font.NORMAL, BaseColor.BLACK);*/
// 读取pdf模板
reader = new PdfReader(templatePath);
stamper = new PdfStamper(reader, bos);
/* 获取模版中的表单域字段 */
AcroFields form = stamper.getAcroFields();
//文字类的内容处理
//设置表单域中的格式
form.addSubstitutionFont(bf);
textFill(data, form);
// 如果为false,生成的PDF文件可以编辑,如果为true,生成的PDF文件不可以编辑
stamper.setFormFlattening(true);
stamper.close();
tempCopyPdf(out, bos);
out.flush();
logger.info("pdf模板处理完成");
return (ByteArrayOutputStream) out;
} catch (IOException e) {
logger.info("IO异常{}", e.getMessage());
} catch (DocumentException e) {
logger.info("pdf操作异常{}", e.getMessage());
}
return null;
}
/**
* 通过提供的pdf模板,按照需要填充的文字信息和图片信息生成pdf
* @param templatePath 模板对象
* @param data 文本信息数据
* @param imgMap 图片信息数据
* @return
*/
public static ByteArrayOutputStream outPdfFile(String templatePath, Map<String, String> data, Map<String, String> imgMap) {
PdfReader reader = null;
PdfStamper stamper = null;
try(OutputStream out = new ByteArrayOutputStream(1024);
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024)) {
//设置字体com/cloud/docment/picture/font/simsun.ttc
BaseFont bf = BaseFont.createFont(DEFAULT_FONT_PATH, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
//设置字体大小
/**Font chineseFont = new Font(bf, 14, Font.NORMAL, BaseColor.BLACK);*/
// 读取pdf模板
reader = new PdfReader(templatePath);
stamper = new PdfStamper(reader, bos);
/* 获取模版中的表单域字段 */
AcroFields form = stamper.getAcroFields();
//设置表单域中的格式
form.addSubstitutionFont(bf);
//文字类的内容处理
textFill(data, form);
//图片类处理
imageFill(imgMap, stamper, form);
// 如果为false,生成的PDF文件可以编辑,如果为true,生成的PDF文件不可以编辑
stamper.setFormFlattening(true);
stamper.close();
tempCopyPdf(out, bos);
/**out.write(bos.toByteArray());*/
out.flush();
logger.info("生成pdf处理完成");
return (ByteArrayOutputStream) out;
} catch (IOException e) {
logger.info("IO异常{}", e.getMessage());
} catch (DocumentException e) {
logger.info("pdf操作异常{}", e.getMessage());
}
return null;
}
/**
*
* @param imgMap 图片信息(含有组装字段和url键值对)
* @param stamper PdfStamper pdf页面对象
* @param form pdf表单域对象
* @throws IOException
* @throws DocumentException
*/
private static void imageFill(Map<String, String> imgMap, PdfStamper stamper, AcroFields form) throws IOException, DocumentException {
Set<Map.Entry<String, String>> entrySet = imgMap.entrySet();
for(Map.Entry<String, String> entry : entrySet) {
String imgpath = entry.getValue();
int pageNo = form.getFieldPositions(entry.getKey()).get(0).page;
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);
}
}
/**
* 根据输入的文字集信息填充表单中的文本域
* @param data 文本填充数据集
* @param form pdf表单域对象
* @throws IOException
* @throws DocumentException
*/
private static void textFill(Map<String, String> data, AcroFields form) throws IOException, DocumentException {
Set<Map.Entry<String, String>> entrySet = data.entrySet();
for (Map.Entry<String, String> entry : entrySet) {
form.setField(entry.getKey(), entry.getValue());
}
}
/**
* 通过填充的pdf生成副本pdf
* @param out 输出流(ByteArrayOutputStream指向父类型)
* @param bos 模板填充的输出流(ByteArrayOutputStream)
* @throws DocumentException
* @throws IOException
*/
private static void tempCopyPdf(OutputStream out, ByteArrayOutputStream bos) throws DocumentException, IOException {
Document doc = new Document();
PdfCopy copy = new PdfCopy(doc, out);
doc.open();
PdfImportedPage importPage = copy.getImportedPage(
new PdfReader(bos.toByteArray()), 1);
copy.addPage(importPage);
doc.close();
}
public static void main(String[] args) {
//测试企业法人
//QYMC ZCZB QYXZ CLRQ FRDB JYQX JYXKFW JYZZ
//测试个体户
String newPdfPath = "D:\\工作目录\\2020\\6月\\20200612\\personal_pdf_mb-cs2.pdf";
// String imgPath = "D:\\工作目录\\2020\\6月\\20200612\\lezhengkejichayan_erweima.png";
String imgPath = "http://www.baidu.com/img/dongsc_eb45d000832f8e889ff64951eaf7f381.gif";
Map<String,String> data = new HashMap<>(16);
//SHMC JYXS QYXZ CLRQ JYR JYZZ JYXKFW
data.put("SHXYDM", "91510100MA6B44RR2E");
data.put("SHMC", "个体商户测试商店540");
data.put("JYXS","经营形式:个体经营");
data.put("QYXZ","个体商户");
data.put("CLRQ","2020年6月9日");
data.put("JYR","(个体户)");
data.put("JYZZ","四川省成都市高新区永和大街 XXX 号");
data.put("JYXKFW","从事计算机类的软件开发/从事计算机类的软件开发/从事计算机类的软件开发/从事计算机类的软件开发/从事计算机类的软件开发/从事计算机类的软件开发/从事计算机类的软件开发");
Map<String,String> img = new HashMap<>(8);
img.put("IMG", imgPath);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
ByteArrayOutputStream baos = outPdfFile(Template2PdfUtils.PERSONAL_TEMPLATE_PATH, data, img);
if (null != baos) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File(newPdfPath+i));
baos.writeTo(fos);
baos.flush();
fos.close();
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long endTime = System.currentTimeMillis();
System.out.print("耗时毫秒数:" + (endTime - startTime));
System.out.print("\n");
}
}
三、其他资料
1、pdf模板制作使用的是Adobe Acrobat DC,软件下载地址:链接: https://pan.baidu.com/s/1WnQBxwC9EzL2iFX5RJY_cQ 提取码: apbw,内含有破解软件,教程件百度
2、模板制作要求:设置表单文本域,需要设置好文本域的相关属性,位置、范围大小、字体大小、字体是否换行显示、域的名称等重要内容;
3、中文使用的是宋体字体;
注意:由于dpf模板使用过程针对模板的要素体检太高,因此建议谨慎选择,有不足之处望诸君共勉。