freemarker生成excel、word、html、xml实例教程

对于导出excel我一直以为用poi、jxt的实现就够了,直到接触了freemarker以后,我才发现我错了,原来还有一种实现比前两者都更简单、便捷。

今天研究了一天的freemarker,一口气写了4个例子,分别实现了对excel、word、html、xml的生成操作。


freemarker页面函数语法地址:http://blog.csdn.net/u010722643/article/details/41720517

工程 及 freemarker.jar 下载地址:http://download.csdn.net/detail/u010722643/8224995


工程结构为:


1.freemarker的java代码

entity:


OptionQuestions

[java]  view plain  copy
  1. package entity;  
  2.   
  3. import java.io.Serializable;  
  4. /** 
  5.  * 选择题试题类 
  6.  * @author 李益勇 
  7.  * 
  8.  */  
  9. public class OptionQuestions implements Serializable{  
  10.     /** 
  11.      *  
  12.      */  
  13.     private static final long serialVersionUID = -9200292678301275536L;  
  14.     private String content;  
  15.     private String option1;  
  16.     private String option2;  
  17.     private String option3;  
  18.     private String option4;  
  19.       
  20.     public String getContent() {  
  21.         return content;  
  22.     }  
  23.     public void setContent(String content) {  
  24.         this.content = content;  
  25.     }  
  26.     public String getOption1() {  
  27.         return option1;  
  28.     }  
  29.     public void setOption1(String option1) {  
  30.         this.option1 = option1;  
  31.     }  
  32.     public String getOption2() {  
  33.         return option2;  
  34.     }  
  35.     public void setOption2(String option2) {  
  36.         this.option2 = option2;  
  37.     }  
  38.     public String getOption3() {  
  39.         return option3;  
  40.     }  
  41.     public void setOption3(String option3) {  
  42.         this.option3 = option3;  
  43.     }  
  44.     public String getOption4() {  
  45.         return option4;  
  46.     }  
  47.     public void setOption4(String option4) {  
  48.         this.option4 = option4;  
  49.     }  
  50. }  

user

[java]  view plain  copy
  1. package entity;  
  2.   
  3. import java.io.Serializable;  
  4. /** 
  5.  * User实体类 
  6.  * @author 李益勇 
  7.  * 
  8.  */  
  9. public class User implements Serializable{  
  10.       
  11.     /** 
  12.      *  
  13.      */  
  14.     private static final long serialVersionUID = 1L;  
  15.     private String userName;  
  16.     private String passWord;  
  17.     private String age;  
  18.     private String addr;  
  19.     private String realName;  
  20.       
  21.     public String getUserName() {  
  22.         return userName;  
  23.     }  
  24.     public void setUserName(String userName) {  
  25.         this.userName = userName;  
  26.     }  
  27.     public String getPassWord() {  
  28.         return passWord;  
  29.     }  
  30.     public void setPassWord(String passWord) {  
  31.         this.passWord = passWord;  
  32.     }  
  33.     public String getAge() {  
  34.         return age;  
  35.     }  
  36.     public void setAge(String age) {  
  37.         this.age = age;  
  38.     }  
  39.     public String getAddr() {  
  40.         return addr;  
  41.     }  
  42.     public void setAddr(String addr) {  
  43.         this.addr = addr;  
  44.     }  
  45.     public String getRealName() {  
  46.         return realName;  
  47.     }  
  48.     public void setRealName(String realName) {  
  49.         this.realName = realName;  
  50.     }  
  51. }  

模板解析Util类:

TemplateParseUtil

[java]  view plain  copy
  1. package util;  
  2. /** 
  3.  * 模板解析实体类 
  4.  */  
  5. import java.io.ByteArrayOutputStream;  
  6. import java.io.File;  
  7. import java.io.FileOutputStream;  
  8. import java.io.IOException;  
  9. import java.io.OutputStreamWriter;  
  10. import java.io.StringWriter;  
  11. import java.io.Writer;  
  12. import java.util.Map;  
  13. import freemarker.cache.StringTemplateLoader;  
  14. import freemarker.template.Configuration;  
  15. import freemarker.template.DefaultObjectWrapper;  
  16. import freemarker.template.Template;  
  17. import freemarker.template.TemplateException;  
  18.   
  19. public class TemplateParseUtil {  
  20.     /** 
  21.      * 解析模板生成Excel 
  22.      * @param templateDir  模板目录 
  23.      * @param templateName 模板名称 
  24.      * @param excelPath 生成的Excel文件路径 
  25.      * @param data 数据参数 
  26.      * @throws IOException 
  27.      * @throws TemplateException 
  28.      */  
  29.     public static void parse(String templateDir,String templateName,String excelPath,Map<String,Object> data) throws IOException, TemplateException {  
  30.         //初始化工作  
  31.         Configuration cfg = new Configuration();  
  32.         //设置默认编码格式为UTF-8  
  33.         cfg.setDefaultEncoding("UTF-8");   
  34.         //全局数字格式  
  35.         cfg.setNumberFormat("0.00");  
  36.         //设置模板文件位置  
  37.         cfg.setDirectoryForTemplateLoading(new File(templateDir));  
  38.         cfg.setObjectWrapper(new DefaultObjectWrapper());  
  39.         //加载模板  
  40.         Template template = cfg.getTemplate(templateName,"utf-8");  
  41.         OutputStreamWriter writer = null;  
  42.         try{  
  43.             //填充数据至Excel  
  44.             writer = new OutputStreamWriter(new FileOutputStream(excelPath),"UTF-8");  
  45.             template.process(data, writer);  
  46.             writer.flush();  
  47.         }finally{  
  48.             writer.close();  
  49.         }     
  50.     }  
  51.   
  52.   
  53.     /** 
  54.      * 解析模板返回字节数组 
  55.      * @param templateDir  模板目录 
  56.      * @param templateName 模板名称 
  57.      * @param data 数据参数 
  58.      * @throws IOException 
  59.      * @throws TemplateException 
  60.      */  
  61.     public static byte[] parse(String templateDir,String templateName,Map<String,Object> data) throws TemplateException, IOException{  
  62.         Configuration cfg = new Configuration();  
  63.         cfg.setDefaultEncoding("UTF-8");  
  64.         cfg.setNumberFormat("0.00");  
  65.         cfg.setDirectoryForTemplateLoading(new File(templateDir));  
  66.         cfg.setObjectWrapper(new DefaultObjectWrapper());  
  67.         Template template = cfg.getTemplate(templateName,"utf-8");  
  68.         ByteArrayOutputStream outStream = new ByteArrayOutputStream();  
  69.         Writer out = new OutputStreamWriter(outStream,"UTF-8");  
  70.         template.process(data, out);  
  71.         return outStream.toByteArray();  
  72.     }  
  73.       
  74.     /** 
  75.      * 自定义模板字符串解析 
  76.      * @param templateStr  模板字符串 
  77.      * @param data 数据   
  78.      * @return 解析后的字符串 
  79.      * @throws IOException 
  80.      * @throws TemplateException 
  81.      */  
  82.     public static String parse(String templateStr, Map<String, Object> data)  
  83.             throws IOException, TemplateException {  
  84.         Configuration cfg = new Configuration();  
  85.         cfg.setNumberFormat("#.##");  
  86.         //设置装载模板  
  87.         StringTemplateLoader stringLoader = new StringTemplateLoader();   
  88.         stringLoader.putTemplate("myTemplate", templateStr);      
  89.         cfg.setTemplateLoader(stringLoader);  
  90.         //加载装载的模板  
  91.         Template temp = cfg.getTemplate("myTemplate""utf-8");  
  92.         Writer out = new StringWriter();  
  93.         temp.process(data, out);  
  94.         return out.toString();  
  95.     }  
  96. }  


2.xml生成

创建模板

新建一个文件xml文件:

内容如下:

[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <xml>  
  3.     <userList>  
  4.         <#list userList as user>  
  5.             <user>  
  6.                 <userName>${user.userName!}</userName>  
  7.                 <passWord>${user.passWord!}</passWord>  
  8.                 <realName>${user.realName!}</realName>  
  9.                 <age>${user.age!}</age>  
  10.                 <addr>${user.addr!}</addr>  
  11.             </user>  
  12.         </#list>  
  13.     </userList>  
  14. </xml>  
然后再将文件后缀改为ft l格式

注:

        <#list userList as user>标签为循环遍历List集合(遍历userList,得到元素命名为user),其语法为<#list list as item>。

        这里我将 ${user.userName}等 改为了 ${user.userName!} ,在后面加了" ! ",这里是为了防止userName为null保错(这里是freemarker的验证机制,有点恶心),解决办法就是:在后面加上 " ! " ,就可以防止字段为null报错这个问题了。

测试:

java

[java]  view plain  copy
  1. /** 
  2.  * 测试XML文件的生成 
  3.  */  
  4. @Test  
  5. public void xmlTest(){  
  6.     List<User> userList = new ArrayList<User>();   
  7.     for(int i = 1 ; i <= 3;i ++){  
  8.         User user = new User();  
  9.         user.setUserName("狗娃" + i);  
  10.         user.setRealName("许文强");  
  11.         user.setPassWord("123456");  
  12.         user.setAddr("上海虎头帮总舵");  
  13.         user.setAge("28");  
  14.         userList.add(user);  
  15.     }  
  16.     //测试Excel文件生成  
  17.     Map<String,Object> data = new HashMap<String, Object>();  
  18.     data.put("userList", userList);  
  19.     try {  
  20.         TemplateParseUtil.parse("template""xml.ftl""tempFile/xmlTest.xml", data);  
  21.     } catch (IOException e) {  
  22.         // TODO Auto-generated catch block  
  23.         e.printStackTrace();  
  24.     } catch (TemplateException e) {  
  25.         // TODO Auto-generated catch block  
  26.         e.printStackTrace();  
  27.     }  
  28.        }  


结果:

生成了:

内容如下:

[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <xml>  
  3.     <userList>  
  4.             <user>  
  5.                 <userName>狗娃1</userName>  
  6.                 <passWord>123456</passWord>  
  7.                 <realName>许文强</realName>  
  8.                 <age>28</age>  
  9.                 <addr>上海虎头帮总舵</addr>  
  10.             </user>  
  11.             <user>  
  12.                 <userName>狗娃2</userName>  
  13.                 <passWord>123456</passWord>  
  14.                 <realName>许文强</realName>  
  15.                 <age>28</age>  
  16.                 <addr>上海虎头帮总舵</addr>  
  17.             </user>  
  18.             <user>  
  19.                 <userName>狗娃3</userName>  
  20.                 <passWord>123456</passWord>  
  21.                 <realName>许文强</realName>  
  22.                 <age>28</age>  
  23.                 <addr>上海虎头帮总舵</addr>  
  24.             </user>  
  25.     </userList>  
  26. </xml>  

3.html生成

创建模板

新建一个文件html文件:

内容如下:

[html]  view plain  copy
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  2. <html>  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  5. <title>Insert title here</title>  
  6. </head>  
  7.     <body>  
  8.         <table border='1' width="99%">  
  9.             <tr>  
  10.                 <td colspan="5" align="center"><font color="red" size="6">user用户列表〃</font></td>  
  11.             </tr>  
  12.             <#list userList as user>  
  13.                 <tr>  
  14.                     <td>${user.userName}</td>  
  15.                     <td>${user.passWord}</td>  
  16.                     <td>${user.realName}</td>  
  17.                     <td>${user.age}</td>  
  18.                     <td>${user.addr}</td>  
  19.                 </tr>  
  20.             </#list>  
  21.         </table>  
  22.      </body>  
  23. </html>  

然后再将文件后缀改为ftl格式


测试:

java

[java]  view plain  copy
  1. /** 
  2.  * 测试HTML文件的生成 
  3.  */  
  4. @Test  
  5. public void htmlTest(){  
  6.     List<User> userList = new ArrayList<User>();   
  7.     for(int i = 1 ; i <= 3;i ++){  
  8.         User user = new User();  
  9.         user.setUserName("狗娃" + i);  
  10.         user.setRealName("许文强");  
  11.         user.setPassWord("123456");  
  12.         user.setAddr("上海虎头帮总舵");  
  13.         user.setAge("28");  
  14.         userList.add(user);  
  15.     }  
  16.     //测试Excel文件生成  
  17.     Map<String,Object> data = new HashMap<String, Object>();  
  18.     data.put("userList", userList);  
  19.     try {  
  20.         TemplateParseUtil.parse("template""html.ftl""tempFile/htmlTest.html", data);  
  21.     } catch (IOException e) {  
  22.         // TODO Auto-generated catch block  
  23.         e.printStackTrace();  
  24.     } catch (TemplateException e) {  
  25.         // TODO Auto-generated catch block  
  26.         e.printStackTrace();  
  27.     }  
  28. }  

结果:

生成了:

内容如下:

[html]  view plain  copy
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  2. <html>  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  5. <title>Insert title here</title>  
  6. </head>  
  7.     <body>  
  8.         <table border='1' width="99%">  
  9.             <tr>   
  10.                 <td colspan="5" align="center"><font color="red" size="6">user用户列表</font></td>  
  11.             </tr>  
  12.                             <tr>  
  13.                     <td>狗娃1</td>  
  14.                     <td>123456</td>  
  15.                     <td>许文强</td>  
  16.                     <td>28</td>  
  17.                     <td>上海虎头帮总舵</td>  
  18.                 </tr>  
  19.                 <tr>  
  20.                     <td>狗娃2</td>  
  21.                     <td>123456</td>  
  22.                     <td>许文强</td>  
  23.                     <td>28</td>  
  24.                     <td>上海虎头帮总舵</td>  
  25.                 </tr>  
  26.                 <tr>  
  27.                     <td>狗娃3</td>  
  28.                     <td>123456</td>  
  29.                     <td>许文强</td>  
  30.                     <td>28</td>  
  31.                     <td>上海虎头帮总舵</td>  
  32.                 </tr>  
  33.         </table>  
  34.      </body>  
  35. </html>  

效果:


4.excel生成

创建模板


新建excel




然后另存为xml格式



用EditPlus打开




将选中的改为:


注:这里一定要改,因为这里设置的是excel的行数,要动态的加载数据,则行数也要跟着改变(设置的行数必须>=实际的行数,不然生成的excel会打不开),${userList?size + 6}是得到userList的大小加上原来标题格式所占的6行,${list?size}可以得到list的大小。


接着继续




在<row>上添加<#list userList as user>循环遍历 userList 的标签




OK,然后再将文件后缀改为ftl格式


测试:

java


[java]  view plain  copy
  1. /** 
  2.  * 测试Excel文件的生成 
  3.  */  
  4. @Test  
  5. public void excelTest(){  
  6.     List<User> userList = new ArrayList<User>();   
  7.     for(int i = 1 ; i < 10;i ++){  
  8.         User user = new User();  
  9.         user.setUserName("狗娃" + i);  
  10.         user.setRealName("许文强");  
  11.         user.setPassWord("123456");  
  12.         user.setAddr("上海虎头帮总舵");  
  13.         user.setAge("28");  
  14.         userList.add(user);  
  15.     }  
  16.     //测试Excel文件生成  
  17.     Map<String,Object> data = new HashMap<String, Object>();  
  18.     data.put("userList", userList);  
  19.     try {  
  20.         TemplateParseUtil.parse("template""excel.ftl""tempFile/excelTest.xls", data);  
  21.     } catch (IOException e) {  
  22.         // TODO Auto-generated catch block  
  23.         e.printStackTrace();  
  24.     } catch (TemplateException e) {  
  25.         // TODO Auto-generated catch block  
  26.         e.printStackTrace();  
  27.     }  
  28.        }   


结果:

生成了:


打开:




打开excel文件,会出现上面的弹框,这个问题一直不好解决,因为我们生成的是xml标记语言,只是将后缀改为xls显示而已,但实际上不是xls文件,希望有大神帮忙解决这个问题,如果有好的解决方案(不是修改注册表的掩耳盗铃的方式),期待留言!


内容如下:




5.word生成

创建模板

新建word




然后另存为xml格式




用EditPlus打开



将选中的改为:




添加<#list list as item>标签,动态循环遍历数据(标签加在</w:p>标签后,</w:p>是换行)。


OK,然后再将文件后缀改为ftl格式


测试:

[java]  view plain  copy
  1. /** 
  2.  * 测试Word文件的生成 
  3.  */  
  4. @Test  
  5. public void wordTest(){  
  6.     Map<String,Object> data = new HashMap<String,Object>();  
  7.     List<OptionQuestions> options = new ArrayList<OptionQuestions>();  
  8.     for(int i = 1;i <= 10; i++){  
  9.         OptionQuestions option = new OptionQuestions();  
  10.         option.setContent(i + "." + "“给力”这个词出自以下哪本名著?");  
  11.         option.setOption1("A." + "《不给力啊,老湿》");  
  12.         option.setOption2("B." + "《这货不是宿敌》");  
  13.         option.setOption3("C." + "《西游记:旅程的终点》");  
  14.         option.setOption4("D." + "《屌丝也有春天》");  
  15.         options.add(option);  
  16.     }  
  17.     List<String> judges = new ArrayList<String>();  
  18.     for(int i = 1;i <= 5; i++){  
  19.         judges.add(i + "." + "正方形、长方形、平行四边形和梯形都是特殊四边形");  
  20.     }  
  21.     data.put("title""全国人大代表考试题");  
  22.     data.put("options", options);  
  23.     data.put("judges",judges);  
  24.     try {  
  25.         TemplateParseUtil.parse("template""word.ftl""tempFile/wordTest.doc", data);  
  26.     } catch (IOException e) {  
  27.         // TODO Auto-generated catch block  
  28.         e.printStackTrace();  
  29.     } catch (TemplateException e) {  
  30.         // TODO Auto-generated catch block  
  31.         e.printStackTrace();  
  32.     }  
  33. }  


结果:

生成了:



内容如下:



6.下载地址

freemarker页面函数语法地址:http://blog.csdn.net/u010722643/article/details/41720517

工程 及 freemarker.jar 下载地址:http://download.csdn.net/detail/u010722643/8224995

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值