Freemarker、Flying sauser 、Itext 整合生成 pdf

原博文地址:

http://jeemiss.iteye.com/blog/1112765


Freemarker、Flying sauser 、Itext ,这三个框架的作用就不详细介绍了,google一下就知道了。

Itext提供了很多底层的API,让我们可以用java代码画一个pdf出来,但是很不灵活,布局渲染代码都hard code 进java类里面了。

当需求发生改变时,哪怕只需要更改一个属性名,我们都要重新修改那段代码,很不符合开放关闭的原则。想到用模版来做渲染,但自己实现起来比较繁琐,然后google了下,找到了用freemarker做模版,Flying sauser 照着模版做渲染,让Itext做输出生成PDF的方案。

 

   freemarker和itext都比较熟悉了,Flying sauser 第一次听说,看完官方的user guide(http://flyingsaucerproject.github.com/flyingsaucer/r8/guide/users-guide-R8.html)后,自己着手做了个demo实践:

 

   

    测试数据模型:

 

Java代码   收藏代码
  1. package com.jeemiss.pdfsimple.entity;  
  2.   
  3. public class User {  
  4.       
  5.     private String name;  
  6.     private int age;  
  7.     private int sex;  
  8.       
  9.     /** 
  10.      * Constructor with all fields 
  11.      *  
  12.      * @param name 
  13.      * @param age 
  14.      * @param sex 
  15.      */  
  16.     public User(String name, int age, int sex) {  
  17.         super();  
  18.         this.name = name;  
  19.         this.age = age;  
  20.         this.sex = sex;  
  21.     }  
  22.       
  23.     ///   getter and setter   ///  
  24.       
  25.     public String getName() {  
  26.         return name;  
  27.     }  
  28.     public void setName(String name) {  
  29.         this.name = name;  
  30.     }  
  31.     public int getAge() {  
  32.         return age;  
  33.     }  
  34.     public void setAge(int age) {  
  35.         this.age = age;  
  36.     }  
  37.     public int getSex() {  
  38.         return sex;  
  39.     }  
  40.     public void setSex(int sex) {  
  41.         this.sex = sex;  
  42.     }  
  43.       
  44.       
  45.   
  46. }  

 

 

Java代码   收藏代码
  1. package com.jeemiss.pdfsimple.freemarker;  
  2.   
  3. import freemarker.template.Configuration;  
  4.   
  5. public class FreemarkerConfiguration {  
  6.       
  7.     private static Configuration config = null;  
  8.       
  9.     /** 
  10.      * Static initialization. 
  11.      *  
  12.      * Initialize the configuration of Freemarker. 
  13.      */  
  14.     static{  
  15.         config = new Configuration();  
  16.         config.setClassForTemplateLoading(FreemarkerConfiguration.class"template");  
  17.     }  
  18.       
  19.     public static Configuration getConfiguation(){  
  20.         return config;  
  21.     }  
  22.   
  23. }  

 

 HTML生成器:

 

Java代码   收藏代码
  1. package com.jeemiss.pdfsimple.generator;  
  2.   
  3. import java.io.BufferedWriter;  
  4. import java.io.StringWriter;  
  5. import java.util.Map;  
  6. import com.jeemiss.pdfsimple.freemarker.FreemarkerConfiguration;  
  7. import freemarker.template.Configuration;  
  8. import freemarker.template.Template;  
  9.   
  10. public class HtmlGenerator {  
  11.       
  12.     /** 
  13.      * Generate html string. 
  14.      *  
  15.      * @param template   the name of freemarker teamlate. 
  16.      * @param variables  the data of teamlate. 
  17.      * @return htmlStr 
  18.      * @throws Exception 
  19.      */  
  20.     public static String generate(String template, Map<String,Object> variables) throws Exception{  
  21.         Configuration config = FreemarkerConfiguration.getConfiguation();  
  22.         Template tp = config.getTemplate(template);  
  23.         StringWriter stringWriter = new StringWriter();    
  24.         BufferedWriter writer = new BufferedWriter(stringWriter);    
  25.         tp.setEncoding("UTF-8");    
  26.         tp.process(variables, writer);    
  27.         String htmlStr = stringWriter.toString();  
  28.         writer.flush();    
  29.         writer.close();  
  30.         return htmlStr;  
  31.     }  
  32.   
  33. }  

   PDF 生成器:

 

 

Java代码   收藏代码
  1. package com.jeemiss.pdfsimple.generator;  
  2.   
  3. import java.io.ByteArrayInputStream;  
  4. import java.io.OutputStream;  
  5. import javax.xml.parsers.DocumentBuilder;  
  6. import javax.xml.parsers.DocumentBuilderFactory;  
  7. import org.w3c.dom.Document;  
  8. import org.xhtmlrenderer.pdf.ITextRenderer;  
  9.   
  10. public class PdfGenerator {  
  11.   
  12.     /** 
  13.      * Output a pdf to the specified outputstream 
  14.      *  
  15.      * @param htmlStr the htmlstr 
  16.      * @param out the specified outputstream 
  17.      * @throws Exception 
  18.      */  
  19.     public static void generate(String htmlStr, OutputStream out)  
  20.             throws Exception {  
  21.         DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();  
  22.         Document doc = builder.parse(new ByteArrayInputStream(htmlStr.getBytes()));  
  23.         ITextRenderer renderer = new ITextRenderer();  
  24.         renderer.setDocument(doc, null);  
  25.         renderer.layout();  
  26.         renderer.createPDF(out);  
  27.         out.close();  
  28.     }  
  29.   
  30. }  

 

    用来做测试的ftl模版,用到部分css3.0的属性来控制pdf强制分页和输出分页信息

 

Html代码   收藏代码
  1. <html>  
  2. <head>  
  3.   <title>${title}</title>  
  4.   <style>  
  5.      table {  
  6.              width:100%;border:green dotted ;border-width:2 0 0 2  
  7.      }  
  8.      td {  
  9.              border:green dotted;border-width:0 2 2 0  
  10.      }  
  11.      @page {    
  12.               size: 8.5in 11in;   
  13.               @bottom-center {  
  14.                     content: "page " counter(page) " of  " counter(pages);  
  15.               }  
  16.      }  
  17.   </style>  
  18. </head>  
  19. <body>  
  20.   <h1>Just a blank page.</h1>  
  21.   <div style="page-break-before:always;">  
  22.       <div align="center">  
  23.           <h1>${title}</h1>  
  24.       </div>  
  25.       <table>  
  26.          <tr>  
  27.             <td><b>Name</b></td>  
  28.             <td><b>Age</b></td>  
  29.             <td><b>Sex</b></td>  
  30.          </tr>  
  31.          <#list userList as user>  
  32.             <tr>  
  33.                 <td>${user.name}</td>  
  34.                 <td>${user.age}</td>  
  35.                 <td>  
  36.                    <#if user.sex = 1>  
  37.                          male  
  38.                    <#else>  
  39.                          female  
  40.                    </#if>  
  41.                 </td>  
  42.             </tr>  
  43.          </#list>  
  44.       </table>  
  45.   </div>  
  46. </body>  
  47. </html>   

 

最后写个测试用例看看:

 

Java代码   收藏代码
  1. package com.jeemiss.pdfsimple.test;  
  2.   
  3. import java.io.FileOutputStream;  
  4. import java.io.OutputStream;  
  5. import java.util.ArrayList;  
  6. import java.util.HashMap;  
  7. import java.util.List;  
  8. import java.util.Map;  
  9. import org.junit.Test;  
  10. import com.jeemiss.pdfsimple.entity.User;  
  11. import com.jeemiss.pdfsimple.generator.HtmlGenerator;  
  12. import com.jeemiss.pdfsimple.generator.PdfGenerator;  
  13.   
  14. public class TestCase   
  15. {  
  16.    @Test  
  17.    public void generatePDF() {  
  18.        try{  
  19.            String outputFile = "C:\\sample.pdf";  
  20.            Map<String,Object> variables = new HashMap<String,Object>();  
  21.               
  22.            List<User> userList = new ArrayList<User>();  
  23.              
  24.            User tom = new User("Tom",19,1);  
  25.            User amy = new User("Amy",28,0);  
  26.            User leo = new User("Leo",23,1);  
  27.              
  28.            userList.add(tom);  
  29.            userList.add(amy);  
  30.            userList.add(leo);  
  31.              
  32.            variables.put("title""User List");  
  33.            variables.put("userList", userList);  
  34.             
  35.            String htmlStr = HtmlGenerator.generate("sample.ftl", variables);  
  36.              
  37.            OutputStream out = new FileOutputStream(outputFile);  
  38.            PdfGenerator.generate(htmlStr, out);  
  39.              
  40.        }catch(Exception ex){  
  41.            ex.printStackTrace();  
  42.        }  
  43.          
  44.    }  
  45. }  

 

到C盘下打开sample.pdf ,看看输出的结果:

 

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值