一、Maven依賴css
<dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.23</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.4.2</version> </dependency> <dependency> <groupId>com.itextpdf.tool</groupId> <artifactId>xmlworker</artifactId> <version>5.4.1</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version> </dependency> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf</artifactId> <version>9.0.3</version> </dependency>
二、pdfTemplate.ftl模板html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <meta http-equiv="content-type" content="text/html;charset=utf-8"></meta> <style type="text/css"> body { font-family: SimSun; } @page{size:A3 } .pianyi{ display:block; font-family:SimSun; padding-left:15px; padding-right:15px; -webkit-margin-after:16px; -webkit-margin-before:16px; -webkit-margin-end:0px; -webkit-margin-start:0px; } .textSpan { padding-left: 15px; padding-right: 15px; line-height: 27px; } </style> </head> <body> <h3 style="text-align: center;">電子受權書</h3> <p class="pianyi">被受權人名稱</p> <span class="textSpan">受權人(申請人)姓名: ${name}</span><br></br> <span class="textSpan">身份證號: ${idCardNo}</span><br></br> <span class="textSpan">受權協議生效日期: ${dateD} </span><br></br> <br/> <div style="word-wrap: break-word;word-break: break-all;overflow: hidden; "> ${content} </div> <div style="padding-left:15px;padding-right:15px;">簽名處:</div> </body> </html>
三、建立GeneratePdf類java
package com.wap.common; import com.itextpdf.text.pdf.BaseFont; import freemarker.template.Configuration; import freemarker.template.Template; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xhtmlrenderer.pdf.ITextRenderer; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.io.StringWriter; import java.util.HashMap; import java.util.Locale; import java.util.Map; /** * 生成Pdf * Created by dgl on 2018/8/6. */ public class GeneratePdf implements Runnable { private static Logger logger = LoggerFactory.getLogger(GeneratePdf.class); private String webPath; //= PathUtil.getPath();//web根目錄 /** * 指定FreeMarker模板文件的位置 */ private String templatePath; /** * freeMarker模板文件名稱 */ private static String templateFileName = "pdfTemplate.ftl"; /** * 圖片路徑 —— 默認是classpath下面的images文件夾 */ private static String imagePath = "/upload/"; /** * 指定編碼 */ private static String encoding = "UTF-8"; /** * 字體 [宋體][simsun.ttc] [黑體][simhei.ttf] */ private String font; /** * 須要傳入的數據 */ private Map<String, Object> dateMap; /** * 申請單號 */ private String applyFromCode; //上傳的目錄 /*private static String directory;*/ public GeneratePdf() { } public GeneratePdf(Map<String, Object> dateMap, String applyFromCode, String webPath) { this.dateMap = dateMap; this.applyFromCode = applyFromCode; this.webPath = webPath; this.templatePath = webPath + "/uf/template/"; this.font = templatePath + "/simsun/simsun.ttc"; } /** * 建立pdf * * @param data 變量數據 * @param applyFromCode 新pdf地址 (一個單號只能有一個PDF文件,因此就直接用申請單號來命名) * @throws Exception */ public Map<String, Object> createPdf(Map<String, Object> data, String applyFromCode) { Map<String, Object> map = new HashMap<>(); String message = ""; String detail = ""; Boolean status = true; String code = "200"; try { //建立文件 //生成的pdf文件路徑 String newPdfPath = webPath + imagePath + applyFromCode + ".pdf"; // String newPdfPath = webPath + Setting.APPLY_FROM_PDF_PATH + "/" + applyFromCode + ".pdf"; File file = new File(newPdfPath); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } FileOutputStream out = new FileOutputStream(file); GeneratePdf pdf = new GeneratePdf(); pdf.createPDF(data, out); message = "建立成功"; //建立完成後的pdf文件所在地址 detail = newPdfPath; logger.info("建立基礎PDF完成"); //線程休息 Thread.sleep(1000); out.close(); out.flush(); } catch (Exception e) { e.printStackTrace(); message = "建立pdf文件錯誤失敗"; status = false; code = "5005"; detail = ""; logger.error("建立pdf文件錯誤" + e.getMessage()); } map.put("status", status); map.put("message", message); map.put("detail", detail); map.put("code", code); return map; } /** * 根據模板生成pdf * * @param data 傳入到freemarker模板裏的數據 * @param out 生成的pdf文件流 */ public void createPDF(Object data, OutputStream out) throws Exception { // 建立一個FreeMarker實例, 負責管理FreeMarker模板的Configuration實例 Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); // 指定FreeMarker模板文件的位置 ITextRenderer renderer = new ITextRenderer(); try { cfg.setDirectoryForTemplateLoading(new File(templatePath)); // 設置 css中 的字體樣式(暫時僅支持宋體和黑體) renderer.getFontResolver().addFont(font, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); // 設置模板的編碼格式 cfg.setEncoding(Locale.CHINA, encoding); // 獲取模板文件 template.ftl Template template = cfg.getTemplate(templateFileName, encoding); StringWriter writer = new StringWriter(); // 將數據輸出到html中 template.process(data, writer); writer.flush(); String html = writer.toString(); // 把html代碼傳入渲染器中 renderer.setDocumentFromString(html); // 解決圖片的相對路徑問題 ##必須在設置document後再設置圖片路徑,否則不起做用 // 若是使用絕對路徑依然有問題,能夠在路徑前面加"file:/" renderer.layout(); renderer.createPDF(out, false); renderer.finishPDF(); out.close(); out.flush(); } catch (Exception e) { e.printStackTrace(); } finally { out.close(); } } @Override public void run() { logger.info("開始異步生成PDF文件"); createPdf(dateMap, applyFromCode); logger.info("異步生成PDF文件完成"); } public String getApplyFromCode() { return applyFromCode; } public void setApplyFromCode(String applyFromCode) { this.applyFromCode = applyFromCode; } }
四、方法調用web
/*** * Pdf sftp上傳服務器 * @param name 申請人名字 * @param idCardNo 申請人身份證號 * @param dateD 申請時間 * @param content 內容說明 * @param applyFromCode 申請單號 * @paramdirectory 服務器存儲路徑 */ public static void printPdf(String webPath, String name, String idCardNo, String dateD, String content, String applyFromCode) { HashMap<String, Object> map = new HashMap<String, Object>(); map.put("name", name); map.put("idCardNo", idCardNo); map.put("dateD", dateD); map.put("content", content); GeneratePdf s = new GeneratePdf(map, applyFromCode, webPath); s.run(); }