簡介
本文使用java引入apache提供的pdf操作工具生成pdf文件,主要是根據需求開發了一個util類,記錄一下學習和開發過程。
業務需求
因為業務需要,對於不同的用戶要生成一個不同的pdf文件,記錄了保險用戶的疾病信息和結算信息等,根據pdf模板,從數據庫中獲取用戶的基本和結算信息,然后生成該用戶的結算文件。
根據這個需求,寫了一個工具類,主要功能就是根據模板生成pdf文件,並保存到服務器指定位置。
引入jar包
pdfBox是apache提供的免費,開源的pdf操作工具,這個jar里面囊括了所有的pdfbox操作工具類,導入這一個就夠了 ,使用起來很方便。
這里使用maven引入jar包:
<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox --> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.13</version> </dependency>
pdf模板文件與方法參數
工具類有兩個必須的元素:pdf模板文件和從數據庫中抽出的數據。
pdf模板文件放在指定的路徑,下圖為部分pdf模板文件:

模板文件可以有多張,這里只截取一張當做參考。
入參和返回值,如下圖:

String型的為生成的pdf文件名(該參數可有可無,文件名可以在該方法內定義,也可以在調用該方法時調用);
Map<String,Object> 是從數據庫中抽取的用戶基本和結算信息,取出過程就不過多贅述了;
返回值為生成pdf文件的保存全路徑;
代碼部分
不多說,直接上代碼
/**
* 根據模板生成pdf
*@param pdfName 文件名
* @param data Map(String,Object)
* @return 文件保存全路徑文件
*/
public String createPDF(String pdfName, Map<String, Object> 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.文件的保存路徑在方法內定義的,也可以事前定義好,像文件名一樣以入參的形式傳參。
