/Java /Flying-Saucer使用HTML或者FTL(Freemarker模板)生成PDF

Flying-Saucer使用HTML或者FTL(Freemarker模板)生成PDF

/Java /Flying-Saucer使用HTML或者FTL(Freemarker模板)生成PDFcss

  • 2015年6月4日
  •     飛翔的拖鞋uphtml

  • Javajava

                   

分享到:Google+QQ空間QQ好友新浪微博更多5api

  

     下載地址:http://pan.baidu.com/s/1i3pJ2PBide


PDF導出工具備itext,可是itext對中文支持很差,還有樣式CSS支持也很差,使用IReport比較複雜,上手不太容易,怎麼辦?工具

幸虧有Flying-Saucer這個項目,幫助咱們解決了以上問題!Flying-Saucer最重要的是很方便,不須要使用IReport的複雜操做,只會寫html就可以作PDF導出的模板。字體

使用freemarker的思路this

一、編寫ftl模板spa

二、使用freemarker生成htmlcode

三、根據生成的html在生成PDF

來一張圖片,不然無圖無真相

項目依賴

< properties >
         < servlet >3.1.0</ servlet >
         < freemarker >2.3.22</ freemarker >
         < flying-saucer >9.0.3</ flying-saucer >
     </ properties >
     < dependencies >
         < dependency >
             < groupId >javax.servlet</ groupId >
             < artifactId >javax.servlet-api</ artifactId >
             < version >${servlet}</ version >
             < scope >provided</ scope >
         </ dependency >
         < dependency >
             < groupId >org.freemarker</ groupId >
             < artifactId >freemarker</ artifactId >
             < version >${freemarker}</ version >
         </ dependency >
         < dependency >
             < groupId >org.xhtmlrenderer</ groupId >
             < artifactId >flying-saucer-pdf</ artifactId >
             < version >${flying-saucer}</ version >
         </ dependency >
     </ dependencies >


依賴關係圖

項目結構圖

主要的操做類

PdfUtils

package  org.xdemo.example.pdf;
 
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.OutputStream;
import  java.util.HashMap;
import  java.util.Map;
 
import  javax.servlet.http.HttpServletResponse;
 
import  org.xhtmlrenderer.pdf.ITextRenderer;
 
import  com.lowagie.text.DocumentException;
 
import  freemarker.core.ParseException;
import  freemarker.template.MalformedTemplateNameException;
import  freemarker.template.TemplateException;
import  freemarker.template.TemplateNotFoundException;
 
/**
  * PDF生成工具類
  * @author Goofy <a href="http://www.xdemo.org">http://www.xdemo.org</a>
  *
  */
public  class  PdfUtils {
 
     public  static  void  main(String[] args) {
         try  {
 
             Map<Object, Object> o= new  HashMap<Object, Object>();
             o.put( "name" "http://www.xdemo.org/" );
             
             String path=PdfHelper.getPath();
             
             generateToFile(path,  "resources/tpl.ftl" ,path+ "resources/" , o,  "D:\\xdemo.pdf" );
             
         catch  (Exception e) {
             e.printStackTrace();
         }
 
     }
     
     /**
      * 生成PDF到文件
      * @param ftlPath 模板文件路徑(不含文件名)
      * @param ftlName 模板文件嗎(不含路徑)
      * @param imageDiskPath 圖片的磁盤路徑
      * @param data 數據
      * @param outputFile 目標文件(全路徑名稱)
      * @throws Exception
      */
     public  static  void  generateToFile(String ftlPath,String ftlName,String imageDiskPath,Object data,String outputFile)  throws  Exception {
         String html=PdfHelper.getPdfContent(ftlPath, ftlName, data);
         OutputStream out =  null ;
         ITextRenderer render =  null ;
         out =  new  FileOutputStream(outputFile);
         render = PdfHelper.getRender();
         render.setDocumentFromString(html);
         if (imageDiskPath!= null &&!imageDiskPath.equals( "" )){
             //html中若是有圖片,圖片的路徑則使用這裏設置的路徑的相對路徑,這個是做爲根路徑
             render.getSharedContext().setBaseURL( "file:/" +imageDiskPath);
         }
         render.layout();
         render.createPDF(out);
         render.finishPDF();
         render =  null ;
         out.close();
     }
     
     /**
      * 生成PDF到輸出流中(ServletOutputStream用於下載PDF)
      * @param ftlPath ftl模板文件的路徑(不含文件名)
      * @param ftlName ftl模板文件的名稱(不含路徑)
      * @param imageDiskPath 若是PDF中要求圖片,那麼須要傳入圖片所在位置的磁盤路徑
      * @param data 輸入到FTL中的數據
      * @param response HttpServletResponse
      * @return
      * @throws TemplateNotFoundException
      * @throws MalformedTemplateNameException
      * @throws ParseException
      * @throws IOException
      * @throws TemplateException
      * @throws DocumentException
      */
     public  static  OutputStream generateToServletOutputStream(String ftlPath,String ftlName,String imageDiskPath,Object data,HttpServletResponse response)  throws  TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException, DocumentException{
         String html=PdfHelper.getPdfContent(ftlPath, ftlName, data);
         OutputStream out =  null ;
         ITextRenderer render =  null ;
         out = response.getOutputStream();
         render = PdfHelper.getRender();
         render.setDocumentFromString(html);
         if (imageDiskPath!= null &&!imageDiskPath.equals( "" )){
             //html中若是有圖片,圖片的路徑則使用這裏設置的路徑的相對路徑,這個是做爲根路徑
             render.getSharedContext().setBaseURL( "file:/" +imageDiskPath);
         }
         render.layout();
         render.createPDF(out);
         render.finishPDF();
         render =  null ;
         return  out;
     }
 
}

輔助類

package  org.xdemo.example.pdf;
 
import  java.io.File;
import  java.io.IOException;
import  java.io.StringWriter;
import  java.util.Locale;
 
import  org.xhtmlrenderer.pdf.ITextRenderer;
 
import  com.lowagie.text.DocumentException;
import  com.lowagie.text.pdf.BaseFont;
 
import  freemarker.core.ParseException;
import  freemarker.template.Configuration;
import  freemarker.template.MalformedTemplateNameException;
import  freemarker.template.Template;
import  freemarker.template.TemplateException;
import  freemarker.template.TemplateNotFoundException;
 
/**
  * PDF生成輔助類
  * @author Goofy <a href="http://www.xdemo.org">http://www.xdemo.org</a>
  *
  */
@SuppressWarnings ( "deprecation" )
public  class  PdfHelper {
 
     public  static  ITextRenderer getRender()  throws  DocumentException, IOException {
 
         ITextRenderer render =  new  ITextRenderer();
 
         String path = getPath();
         //添加字體,以支持中文
         render.getFontResolver().addFont(path +  "resources/ARIALUNI.TTF" , BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
         render.getFontResolver().addFont(path +  "resources/SIMSUN.TTC" , BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
 
         return  render;
     }
 
     //獲取要寫入PDF的內容
     public  static  String getPdfContent(String ftlPath, String ftlName, Object o)  throws  TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
         return  useTemplate(ftlPath, ftlName, o);
     }
 
     //使用freemarker獲得html內容
     public  static  String useTemplate(String ftlPath, String ftlName, Object o)  throws  TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
 
         String html =  null ;
 
         Template tpl = getFreemarkerConfig(ftlPath).getTemplate(ftlName);
         tpl.setEncoding( "UTF-8" );
 
         StringWriter writer =  new  StringWriter();
         tpl.process(o, writer);
         writer.flush();
         html = writer.toString();
         return  html;
     }
 
     /**
      * 獲取Freemarker配置
      * @param templatePath
      * @return
      * @throws IOException
      */
     private  static  Configuration getFreemarkerConfig(String templatePath)  throws  IOException {
         Configuration config =  new  Configuration();
         config.setDirectoryForTemplateLoading( new  File(templatePath));
         config.setEncoding(Locale.CHINA,  "utf-8" );
         return  config;
     }
     
     /**
      * 獲取類路徑
      * @return
      */
     public  static  String getPath(){
         return  PdfHelper. class .getResource( "" ).getPath().substring( 1 );
     }
 
}

模板文件

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
< html  xmlns = "http://www.w3.org/1999/xhtml" >
< head >
< title ></ title >
< style  type = "text/css" >
body {
     margin-left: 45px;
     margin-right: 45px;
     font-family: Arial Unicode MS;
     font-size: 10px;
}
 
table {
     margin: auto;
     width: 100%;
     border-collapse: collapse;
     border: 1px solid #444444;
}
 
th,td {
     border: 1px solid #444444;
     font-size: 10px;
     margin-left: 5px;
}
 
.mcContent {
     line-height: 180%;
     padding: 20px;
}
 
.logo {
     text-align: center;
}
 
.title {
     text-align: center;
     font-weight: bold;
     font-size: 20px;
}
 
.notes {
     font-weight: normal;
     margin-left: 5px;
     margin-right: 5px;
     line-height: 18px;
}
 
.text_content {
     margin-left: 5px;
     margin-right: 5px;
     line-height: 18px;
}
 
.sum_insured_first_row {
     width: 20%;
}
 
.sum_insured_span {
     font-size: 10px;
}
 
.special_agreements_div {
     page-break-before: always;
     font-size: 14px;
     margin-top: 20px;
}
 
.special_agreements_div .special_agreements {
     font-size: 18px;
     font-weight: bold;
}
 
.title_right {
     width: 100%;
     margin: 0 auto;
}
 
.title_right p {
     text-align: left;
     margin: 0;
     margin-left: 50%;
     padding: 0;
}
 
@page {
     size: 8.5in 11in;
     @
     bottom-center
     {
     content
     :
     "page "
     counter(
     page
     )
     " of  "
     counter(
     pages
     );
}
 
.signature {
     margin: 0 auto;
     clear: both;
     font-size: 16px;
     font-weight: bold;
}
 
.signature_table {
/*     font-size: 16px; */
     font-weight: bold;
}
 
</ style >
</ head >
< body >
     做者:< a  href = "http://www.xdemo.org/" >http://www.xdemo.org/</ a >
     < div >
         < p >你好:${name}</ p >
         < div  class = "logo" > <!--這裏的圖片使用相對與ITextRenderer.getSharedContext().setBaseURL("file:/"+imageDiskPath);的路徑-->
             圖片支持< img  src = "logo1.png"  />
         </ div >
         < div >
             < p >Hello PDF: 中文支持</ p >
             < div  style = "border:1px solid red;color:red;" >
                 樣式支持,紅邊框,紅字
             </ div >
             < div  style = "border:10px solid blue;color:blue;" >
                 樣式支持,藍色10像素的邊框,藍字
             </ div >
             < hr />
             < table >
                 < tr  style = "background:gray;" >
                     < th >A</ th >
                     < th >B</ th >
                     < th >C</ th >
                     < th >D</ th >
                 </ tr >
                 < tr >
                     < td >100</ td >
                     < td >29</ td >
                     < td >32</ td >
                     < td >43</ td >
                 </ tr >
                 < tr >
                     < td >100</ td >
                     < td >29</ td >
                     < td >32</ td >
                     < td >43</ td >
                 </ tr >
                 < tr >
                     < td >100</ td >
                     < td >29</ td >
                     < td >32</ td >
                     < td >43</ td >
                 </ tr >
                 < tr >
                     < td >100</ td >
                     < td >29</ td >
                     < td >32</ td >
                     < td >43</ td >
                 </ tr >
                 < tr >
                     < td >100</ td >
                     < td >29</ td >
                     < td >32</ td >
                     < td >43</ td >
                 </ tr >
             </ table >
         </ div >
     </ div >
</ body >
</ html >

注意

本 工具類提供了兩種字體支持中文,因此定義樣式的時候字體只能用:simsun或者arial unicode MS,不然中文顯示不出來,如需其餘字體另行添加),另外請注意圖片的路徑問題,html中z若是有圖片,圖片的路徑則使用這裏設置的路徑的相對路徑,這 個是做爲根路徑,如

< div  class = "logo" >
     <!--這裏的圖片使用相對與ITextRenderer.getSharedContext().setBaseURL("file:/"+imageDiskPath);的路徑-->
     圖片支持< img  src = "logo1.png"  />
</ div >

若是須要PDF的下載,能夠經過generateToServletOutputStream這個方法來獲取PDF的輸出流,而後經過response寫到客戶端去

轉載請註明來源: http://www.xdemo.org/flying-saucer-html-freemarker-pdf/

相關文章
相關標籤/搜索