java中根據模板生成pdf檔案
簡介
本文使用java引入apach提供的pdf操作工具生成pdf檔案,主要是根據需求開發了一個util類,記錄一下學習和開發過程。
業務需求
因為業務需要,對於不同的使用者要生成一個不同的pdf檔案,記錄了保險使用者的疾病資訊和結算資訊等,根據pdf模板,從資料庫中獲取使用者的基本和結算資訊,然後生成該使用者的結算檔案。
根據這個需求,寫了一個工具類,主要功能就是根據模板生成pdf檔案,並儲存到伺服器指定位置。
引入jar包
pdfBox是apach提供的免費,開源的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 * @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("pdf生成:讀取檔案異常"); e.printStackTrace(); return ""; } finally { try { bos.close(); reader.close(); } catch (IOException e) { logger.error("pdf生成:關閉流異常"); e.printStackTrace(); } } }
經過實際使用,程式碼能夠正常生成pdf檔案,在這裡就不上圖了
總結歸納
1.pdf模板檔案可以看做是key-value的鍵值對型,key值即為入參中的map中的key值,在pdf模板中隱藏,value即是根據key填充的值。
2.pdf模板檔案中的checkbox預設是勾選上的,設定off,可以取消勾選當前選項,比如使用者性別為女:使用map.put("sexMale","off");的方法取消性別中男性的已選擇狀態。
3.檔案的儲存路徑在方法內定義的,也可以事前定義好,像檔名一樣以入參的形式傳參。