简介
本文使用java引入apache提供的pdf操作工具生成pdf文件,主要是根据需求开发了一个util类,记录一下学习和开发过程。
业务需求
因为业务需要,对于不同的用户要生成一个不同的pdf文件,记录了保险用户的疾病信息和结算信息等,根据pdf模板,从数据库中获取用户的基本和结算信息,然后生成该用户的结算文件。
根据这个需求,写了一个工具类,主要功能就是根据模板生成pdf文件,并保存到服务器指定位置。
引入jar包
pdfBox是apache提供的免费,开源的pdf操作工具,这个jar里面囊括了所有的pdfbox操作工具类,导入这一个就够了 ,使用起来很方便。
这里使用maven引入jar包:
org.apache.pdfbox
pdfbox
2.0.13
pdf模板文件与方法参数
工具类有两个必须的元素:pdf模板文件和从数据库中抽出的数据。
pdf模板文件放在指定的路径,下图为部分pdf模板文件:
模板文件可以有多张,这里只截取一张当做参考。
入参和返回值,如下图:
String型的为生成的pdf文件名(该参数可有可无,文件名可以在该方法内定义,也可以在调用该方法时调用);
Map 是从数据库中抽取的用户基本和结算信息,取出过程就不过多赘述了;
返回值为生成pdf文件的保存全路径;
代码部分
不多说,直接上代码
/**
* 根据模板生成pdf
*@param pdfName 文件名
* @param data Map(String,Object)
* @return 文件保存全路径文件
*/
public String createPDF(String pdfName, Map data) {
PdfReader reader = null;
AcroFields s = null;
PdfStamper ps = null;
ByteArrayOutputStream bos = null;
String realPath = ResourceBundle.getBundle("systemconfig").getString("upLoadFolder") + File.separator + "comfirmationDoc";
String dateFolder = DateFormatUtils.format(new Date(), "yyyyMMdd");
String folderPath = realPath + File.separator + dateFolder;
//创建上传文件目录
File folder = new File(folderPath);
if (!folder.exists()) {
folder.mkdirs();
}
//设置文件名
String fileName = pdfName + "_" + DateFormatUtils.format(new Date(), "yyyyMMddhhmmss") + ".pdf";
String savePath = folderPath + File.separator + fileName;
try {
String file = this.getClass().getClassLoader().getResource("comfirmTemplate.pdf").getPath();
//设置字体
String font = this.getClass().getClassLoader().getResource("YaHei.ttf").getPath();
reader = new PdfReader(file);
bos = new ByteArrayOutputStream();
ps = new PdfStamper(reader, bos);
s = ps.getAcroFields();
//使用中文字体 使用 AcroFields填充值的不需要在程序中设置字体,在模板文件中设置字体为中文字体 Adobe 宋体 std L
BaseFont bfChinese = BaseFont.createFont(font, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
//设置编码格式
s.addSubstitutionFont(bfChinese);
// 遍历data 给pdf表单表格赋值
for (String key : data.keySet()) {
if (data.get(key) != null) {
s.setField(key, data.get(key).toString());
}
}
// 如果为false那么生成的PDF文件还能编辑,一定要设为true
ps.setFormFlattening(true);
ps.close();
FileOutputStream fos = new FileOutputStream(savePath);
fos.write(bos.toByteArray());
fos.flush();
fos.close();
return savePath;
} catch (IOException | DocumentException e) {
logger.error("读取文件异常");
e.printStackTrace();
return "";
} finally {
try {
bos.close();
reader.close();
} catch (IOException e) {
logger.error("关闭流异常");
e.printStackTrace();
}
}
}
经过实际使用,代码能够正常生成pdf文件,在这里就不上图了
总结归纳
1.pdf模板文件可以看做是key-value的键值对型,key值即为入参中的map中的key值,在pdf模板中隐藏,value即是根据key填充的值。
2.pdf模板文件中的checkbox默认是勾选上的,设置off,可以取消勾选当前选项,比如用户性别为女:使用map.put("sexMale","off");的方法取消性别中男性的已选择状态。
3.文件的保存路径在方法内定义的,也可以事前定义好,像文件名一样以入参的形式传参。