Freemarker+Flying sauser +Itext 整合生成PDF

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

 

    Freemarker+Flying sauser +Itext 整合生成PDF_第1张图片

    测试数据模型:

 

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 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强制分页和输出分页信息

 



  ${title}
  


  

Just a blank page.

${title}

<#list userList as user>
Name Age Sex
${user.name} ${user.age} <#if user.sex = 1> male <#else> female

 

最后写个测试用例看看:

 

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 variables = new HashMap();
		    
		   List userList = new ArrayList();
		   
		   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 ,看看输出的结果:

 

 

Freemarker+Flying sauser +Itext 整合生成PDF_第2张图片

你可能感兴趣的:(J2EE)