java通過freemarker模板導出pdf


需求:將網頁內容導出為pdf文件,其中包含文字,圖片,echarts圖
原理:利用freemarker模板與數據渲染所得到的html內容,通過 ITextRenderer對象解析html內容生成pdf
參考地址:
導出pdf
帶有圖片

 

使用itext將html生成pdf中文換行問題解決方案

 

 
本文內容是參考以上地址內容對需求的實現
 
1.添加依賴
<!-- freemarker -->
<dependency>
  <groupId>org.freemarker</groupId>
  <artifactId>freemarker</artifactId>
  <version>2.3.19</version>
</dependency>
<!-- itextpdf,導出pdf核心架包 -->
<dependency>
  <groupId>com.itextpdf</groupId>
  <artifactId>itextpdf</artifactId>
  <version>5.5.11</version>
</dependency>
<!-- itextpdf工具包,用來解析html生成pdf -->
<dependency>
  <groupId>com.itextpdf.tool</groupId>
  <artifactId>xmlworker</artifactId>
  <version>5.5.11</version>
</dependency>
<!-- flying saucer,支持對CSS高級特性的解析 -->
<dependency>
  <groupId>org.xhtmlrenderer</groupId>
  <artifactId>flying-saucer-pdf</artifactId>
  <version>9.1.5</version>
</dependency>
<dependency>
  <groupId>org.xhtmlrenderer</groupId>
  <artifactId>flying-saucer-pdf-itext5</artifactId>
  <version>9.1.5</version>
</dependency>
2.freemarker模板數據渲染html內容
// 獲設置模板路徑,供參考
static {
  freemarkerCfg =new Configuration();
  //freemarker的模板目錄
  freemarkerCfg.setClassForTemplateLoading(JavaToPdfHtmlFreeMarker.class,"/");
}
public static String freeMarkerRender(Map<String, Object> data, String htmlTmp) {
    Writer out = new StringWriter();
    try {
      // 獲取模板,並設置編碼方式
      Template template = freemarkerCfg.getTemplate(htmlTmp);
      template.setEncoding("UTF-8");
      // 合並數據模型與模板
      template.process(data, out); //將合並后的數據和模板寫入到流中,這里使用的字符流
      out.flush();
      return out.toString();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        out.close();
      } catch (IOException ex) {
        ex.printStackTrace();
      }
    }
    return null;
}
3.解析html內容生成pdf
public static void createPdf(String content,OutputStream out) throws IOException, com.lowagie.text.DocumentException {
  ITextRenderer render = new ITextRenderer();
 
  ITextFontResolver fontResolver = render.getFontResolver();
  fontResolver.addFont("C:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
 
  // 解析html生成pdf
  render.setDocumentFromString(content);
 
  //解決圖片相對路徑的問題
  //render.getSharedContext().setBaseURL("");
  render.layout();
  render.createPDF(out);
  render.finishPDF();
}
OutputStream out可以換作其他輸出流對象,比如new FileOutputStream("D:/a.pdf")
注意:設置字體后,需在CSS文件中也設置該字體,才可以顯示中文
圖片可以使用CSS設置背景圖片為base64碼格式展示
body{
  font-family:SimSun;
}
上面內容為網頁下載pdf所調用,調用方法如下(供參考):
try{
OutputStream out = null;
out = response.getOutputStream();
//設置響應對象上下文類型
response.setContentType( "application/pdf,charset=utf-8");
//文件名處理,防止亂碼問題
fileName += DateTimeUtils.currentDate("yyMMddHHmmss") + ".pdf";
 
String filename = "";
filename = request==null? java.net.URLEncoder.encode(fileName, "UTF-8"): AppUtils.encodingFileName(fileName,request);
//設置響應頭
response.setHeader("Content-Disposition","attachment;filename=" + filename);
 
JavaToPdfHtmlFreeMarker.createPdf(content,out);
 
//獲取響應對象輸出流並返回
if (out != null) {
out.close();
out = null;
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return super.outJsonStringFail();
} catch (IOException e) {
e.printStackTrace();
return super.outJsonStringFail();
} catch (com.lowagie.text.DocumentException e) {
e.printStackTrace();
return super.outJsonStringFail();
}

4.如有echarts圖,可添加一下js,將圖轉為base64碼放於css或者html中的style屬性中

/**
     * 將多個canvas畫布組成的圖表合成為一個完整的canvas,並獲取完整的dataURl
     * @param divId divId 包含整個畫布的divId
     * @returns {String} widthXheight@dataURL 例:
     * 400X300@data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA
     */

    function getFullCanvasDataURL(divId){
        //將第一個畫布作為基准。
        var baseCanvas = $("#"+divId).find("canvas").first()[0];
        if(!baseCanvas){
            return false;
        };
        var width = baseCanvas.width;
        var height = baseCanvas.height;
        var ctx = baseCanvas.getContext("2d");
        //遍歷,將后續的畫布添加到在第一個上
        $("#"+divId).find("canvas").each(function(i,canvasObj){
            if(i>0){
                var canvasTmp = $(canvasObj)[0];
                ctx.drawImage(canvasTmp,0,0,width,height);
            }
        });
        //獲取base64位的url
        return baseCanvas.toDataURL();
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM