`
┿┅мīSS
  • 浏览: 96015 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Freemarker+Flying sauser +Itext 整合生成PDF

    博客分类:
  • J2EE
 
阅读更多

     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实践:

 

   

    测试数据模型:

 

package com.jeemiss.pdfsimple.entity;

public class User {
	
	private String name;
	private int age;
	private int sex;
	
	/**
	 * Constructor with all fields
	 * 
	 * @param name
	 * @param age
	 * @param sex
	 */
	public User(String name, int age, int sex) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
	}
	
	///////////////////////   getter and setter   ///////////////////////////////////////////
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public int getSex() {
		return sex;
	}
	public void setSex(int sex) {
		this.sex = sex;
	}
	
	

}

 

 

package com.jeemiss.pdfsimple.freemarker;

import freemarker.template.Configuration;

public class FreemarkerConfiguration {
	
	private static Configuration config = null;
	
	/**
	 * Static initialization.
	 * 
	 * Initialize the configuration of Freemarker.
	 */
	static{
		config = new Configuration();
		config.setClassForTemplateLoading(FreemarkerConfiguration.class, "template");
	}
	
	public static Configuration getConfiguation(){
		return config;
	}

}

 

 HTML生成器:

 

package com.jeemiss.pdfsimple.generator;

import java.io.BufferedWriter;
import java.io.StringWriter;
import java.util.Map;
import com.jeemiss.pdfsimple.freemarker.FreemarkerConfiguration;
import freemarker.template.Configuration;
import freemarker.template.Template;

public class HtmlGenerator {
	
	/**
	 * Generate html string.
	 * 
	 * @param template   the name of freemarker teamlate.
	 * @param variables  the data of teamlate.
	 * @return htmlStr
	 * @throws Exception
	 */
	public static String generate(String template, Map<String,Object> variables) throws Exception{
		Configuration config = FreemarkerConfiguration.getConfiguation();
		Template tp = config.getTemplate(template);
		StringWriter stringWriter = new StringWriter();  
		BufferedWriter writer = new BufferedWriter(stringWriter);  
		tp.setEncoding("UTF-8");  
		tp.process(variables, writer);  
		String htmlStr = stringWriter.toString();
		writer.flush();  
		writer.close();
		return htmlStr;
	}

}

   PDF 生成器:

 

 

package com.jeemiss.pdfsimple.generator;

import java.io.ByteArrayInputStream;
import java.io.OutputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.xhtmlrenderer.pdf.ITextRenderer;

public class PdfGenerator {

	/**
	 * Output a pdf to the specified outputstream
	 * 
	 * @param htmlStr the htmlstr
	 * @param out the specified outputstream
	 * @throws Exception
	 */
	public static void generate(String htmlStr, OutputStream out)
			throws Exception {
		DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		Document doc = builder.parse(new ByteArrayInputStream(htmlStr.getBytes()));
		ITextRenderer renderer = new ITextRenderer();
		renderer.setDocument(doc, null);
		renderer.layout();
		renderer.createPDF(out);
		out.close();
	}

}

 

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

 

<html>
<head>
  <title>${title}</title>
  <style>
     table {
    		 width:100%;border:green dotted ;border-width:2 0 0 2
     }
     td {
    		 border:green dotted;border-width:0 2 2 0
     }
     @page {  
              size: 8.5in 11in; 
              @bottom-center {
    				content: "page " counter(page) " of  " counter(pages);
  			  }
     }
  </style>
</head>
<body>
  <h1>Just a blank page.</h1>
  <div style="page-break-before:always;">
      <div align="center">
	      <h1>${title}</h1>
	  </div>
	  <table>
	     <tr>
	        <td><b>Name</b></td>
	        <td><b>Age</b></td>
	        <td><b>Sex</b></td>
	     </tr>
	     <#list userList as user>
	        <tr>
		        <td>${user.name}</td>
		        <td>${user.age}</td>
		        <td>
		           <#if user.sex = 1>
		             	 male
		           <#else>
		              	 female
		           </#if>
		        </td>
	        </tr>
	     </#list>
	  </table>
  </div>
</body>
</html> 

 

最后写个测试用例看看:

 

package com.jeemiss.pdfsimple.test;

import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import com.jeemiss.pdfsimple.entity.User;
import com.jeemiss.pdfsimple.generator.HtmlGenerator;
import com.jeemiss.pdfsimple.generator.PdfGenerator;

public class TestCase 
{
   @Test
   public void generatePDF() {
	   try{
		   String outputFile = "C:\\sample.pdf";
		   Map<String,Object> variables = new HashMap<String,Object>();
		    
		   List<User> userList = new ArrayList<User>();
		   
		   User tom = new User("Tom",19,1);
		   User amy = new User("Amy",28,0);
		   User leo = new User("Leo",23,1);
		   
		   userList.add(tom);
		   userList.add(amy);
		   userList.add(leo);
		   
		   variables.put("title", "User List");
		   variables.put("userList", userList);
		  
		   String htmlStr = HtmlGenerator.generate("sample.ftl", variables);
		   
		   OutputStream out = new FileOutputStream(outputFile);
		   PdfGenerator.generate(htmlStr, out);
		   
	   }catch(Exception ex){
		   ex.printStackTrace();
	   }
	   
   }
}

 

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

 

 

分享到:
评论
7 楼 xiefuzhong 2013-10-17  
怎么解决中文问题,
运行程序,中午不能显示,请解答,谢谢
6 楼 294676001 2012-07-31  
不支持中文 
5 楼 smith789 2012-03-01  
另外你的HtmlGenerator.java里没有设置Object wrappers,怎么能解析User成功?

报错:
Java backtrace for programmers:
----------
freemarker.template.TemplateModelException: Don't know how to present an object of this type to a template: com.jeemiss.pdfsimple.entity.User

加上下面一行就行了。
config.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);

来自Freemarker官方:
The most important ObjectWrapper implementations that the FreeMarker core provides are:

ObjectWrapper.DEFAULT_WRAPPER: It replaces String with SimpleScalar, Number with SimpleNumber, List and array with SimpleSequence, Map with SimpleHash, Boolean with TemplateBooleanModel.TRUE or TemplateBooleanModel.FALSE, W3C DOM nodes with freemarker.ext.dom.NodeModel. For Jython objects, this wrapper will invoke freemarker.ext.jython.JythonWrapper. For all other objects, it will invoke BEANS_WRAPPER.

ObjectWrapper.BEANS_WRAPPER: It can expose java Bean properties and other members of arbitrary objects using Java reflection. At least in FreeMarker 2.3, it is a freemarker.ext.beans.BeansWrapper instance; there is a separated chapter about it.
4 楼 smith789 2012-03-01  
String htmlStr = stringWriter.toString();
放到writer.close();后面吧,报错:

[Fatal Error] :1:1: Premature end of file.
org.xml.sax.SAXParseException: Premature end of file.
3 楼 wuhacoffee 2011-12-06  
非常感谢楼主的提供。。。正学习着呢!!

建议楼主把代码分享出来给大家。。。
2 楼 simulatestar 2011-11-09  
你好,请问,为何我按你这个例子做出来,以后报错呢
1 楼 yindashan 2011-10-09  
谢谢分享,

相关推荐

    freemarker+itext生成PDF

    这篇博客 "freemarker+itext生成PDF" 可能详细介绍了如何结合这两者来生成PDF文件,这在报表生成、发票打印或任何需要静态化输出的场景中非常有用。 首先,让我们了解FreeMarker。FreeMarker是一个基于模板的语言,...

    SpringBoot集成Freemarker+FlyingSaucer实现pdf在线预览.pdf

    SpringBoot集成Freemarker+FlyingSaucer实现pdf在线预览 本文讲述如何使用SpringBoot集成Freemarker和FlyingSaucer实现PDF在线预览、打印和下载的功能。该技术方案可以应用于各种在线文档预览、报表生成、电子邮件...

    iText-2.0.8.jar

    iText-2.0.8.jar,Freemarker+Flying sauser +Itext 整合生成PDF需要的JAR包,配合core-renderer.jar一起使用

    基于iText和flying saucer结合freemark生成pdf 范例

    基于iText和flying saucer结合freemark生成pdf 范例 ...itextpdf-5.3.0.jar jackson-core-asl-1.9.2.jar jackson-mapper-asl-1.9.2.jar junit-4.11.jar log4j-1.2.17.jar slf4j-api-1.7.5.jar

    FreeMarker+poi 模板生成word+导入图片

    FreeMarker和Apache POI是两种在Java开发中广泛使用的工具,它们在处理文档生成和操作方面各有专长。本文将详细介绍这两个库如何协同工作来创建带有图片的Word文档。 **FreeMarker** FreeMarker是一个模板引擎,...

    freemarker+html生成pdf.zip

    - Java代码:实现了`Freemarker`的配置、数据模型的构建、模板处理以及PDF生成。 - 示例数据:用于填充模板的数据。 - 测试用例:可能包含单元测试或集成测试,用于验证生成PDF的正确性。 在实际开发中,你可能需要...

    基于springboot+mvc+freemarker+aop实现校友信息管理系统源码.zip

    1、基于springboot+mvc+freemarker+aop实现校友信息管理系统源码.zip 2、该资源包括项目的全部源码,下载可以直接使用! 3、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考...

    基于springboot+mvc+freemarker+aop实现校友信息管理系统.zip

    基于springboot+mvc+freemarker+aop实现校友信息管理系统.zip基于springboot+mvc+freemarker+aop实现校友信息管理系统.zip基于springboot+mvc+freemarker+aop实现校友信息管理系统.zip基于springboot+mvc+freemarker...

    Freemarker模板生成pdf+java

    Freemarker模板生成pdf+javaFreemarker模板生成pdf+javaFreemarker模板生成pdf+javaFreemarker模板生成pdf+javaFreemarker模板生成pdf+java

    freemarker+struts2+spring完美整合!

    部署到tomcat中, 访问/freemarker/build_index.action 点击首页生成,当显示生成成功过后 然后访问 ...已经完美将struts2+freemarker+spring整合~ 希望对你们有所帮助。 经测试:tomcat5.5 无法正常运行

    基于itext7+freemarker模板导出pdf

    &lt;groupId&gt;com.itextpdf&lt;/groupId&gt; &lt;artifactId&gt;itext7-core &lt;version&gt;7.x.x &lt;groupId&gt;org.freemarker &lt;artifactId&gt;freemarker &lt;version&gt;2.x.x ``` 请替换`x.x.x`为最新版本号。 步骤二:创建...

    基于FreeMarker+SpringBoot+Mybatis实现的大学教室管理系统

    本系统是基于FreeMarker+SpringBoot+Mybatis实现的大学教室管理系统。主要实现对教室的预约、教学楼管理、教室管理、教室上课时间管理、班级管理、学生,老师,辅导员,楼长管理。 管理员登录页面:...

    基于SpringBoot+FreeMarker+MyBatis+ExtJs的一个通用后台管理系统源码(适合快速迭代开发).zip

    1、基于SpringBoot+FreeMarker+MyBatis+ExtJs实现的一个通用后台管理系统源码(适合快速迭代开发).zip 2、该资源包括项目的全部源码,下载可以直接使用! 3、本项目适合作为计算机、数学、电子信息等专业的课程设计...

    iText+Flying Saucer生成pdf文档所需要的jar包

    在“iText+Flying Saucer生成pdf文档jar包(修改后的)”这个描述中,"修改后的"可能指的是开发者对原始库进行了一些定制,以更好地支持中文显示。这可能包括修改字体设置、编码处理或者解决了某些特定的中文排版...

    基于SpringBoot+FreeMarker+MyBatis+ExtJs实现的一个通用后台管理系统,界面美观,适合快速迭代开发

    基于SpringBoot+FreeMarker+MyBatis+ExtJs实现的一个通用后台管理系统,界面美观,适合快速迭代开发 项目说明 技术栈: SpringBoot MyBatis Redis MySQL FreeMarker ExtJs 基于SpringBoot+FreeMarker+MyBatis+...

    springboot+freemarker+druid+mysql

    标题中的"springboot+freemarker+druid+mysql"是一个综合性的项目组合,涉及到四个主要的技术组件。这里,我们将深入探讨每个技术及其在实际应用中的作用。 **SpringBoot** SpringBoot是由Pivotal团队提供的全新...

    基于SpringBoot+FreeMarker+MyBatis的通用后台管理系统源码(界面美观,适合快速迭代开发).zip

    基于SpringBoot+FreeMarker+MyBatis的通用后台管理系统源码(界面美观,适合快速迭代开发).zip基于SpringBoot+FreeMarker+MyBatis的通用后台管理系统源码(界面美观,适合快速迭代开发).zip基于SpringBoot+...

    flying-saucer-core+flying-saucer-pdf-itext5.jar

    在具体实现时,开发者需要引入"flying-saucer-core"和"flying-saucer-pdf-itext5"的jar包,如" flying-saucer-core+flying-saucer-pdf-itext5.jar",并调用其提供的API进行操作。例如,可以使用`ITextRenderer`类来...

    java根据动态模板生成pdf(包含柱状图)所需jar包

    iText+FreeMarker+JFreeChart生成可动态配置的PDF文档。 iText有很强大的PDF处理能力,但是样式和排版不好控制,直接写PDF文档,数据的动态渲染很麻烦。 FreeMarker能配置动态的html模板,正好解决了样式、动态渲染...

    Struts2+Spring2.5+Hibernate3+Freemarker框架整合

    整合S2SH+Freemarker+oscache,后台用Spring管理各个bean,Hibernate做数据库持久化,viewer用Freemarker。整合中对Struts2,Hibernate,Spring都采用Annotation进行注解类。

Global site tag (gtag.js) - Google Analytics