您的位置:首页 > Web前端 > HTML

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

2017-11-03 15:59 525 查看
对于导出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

package entity;

import java.io.Serializable;

/**

* 选择题试题类

* @author 李益勇

*

*/

public class OptionQuestions implements Serializable{

/**

*

*/

private static final long serialVersionUID = -9200292678301275536L;

private String content;

private String option1;

private String option2;

private String option3;

private String option4;

public String getContent() {

return content;

}

public void setContent(String content) {

this.content = content;

}

public String getOption1() {

return option1;

}

public void setOption1(String option1) {

this.option1 = option1;

}

public String getOption2() {

return option2;

}

public void setOption2(String option2) {

this.option2 = option2;

}

public String getOption3() {

return option3;

}

public void setOption3(String option3) {

this.option3 = option3;

}

public String getOption4() {

return option4;

}

public void setOption4(String option4) {

this.option4 = option4;

}

}

user

[java] view
plain copy

package entity;

import java.io.Serializable;

/**

* User实体类

* @author 李益勇

*

*/

public class User implements Serializable{

/**

*

*/

private static final long serialVersionUID = 1L;

private String userName;

private String passWord;

private String age;

private String addr;

private String realName;

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public String getPassWord() {

return passWord;

}

public void setPassWord(String passWord) {

this.passWord = passWord;

}

public String getAge() {

return age;

}

public void setAge(String age) {

this.age = age;

}

public String getAddr() {

return addr;

}

public void setAddr(String addr) {

this.addr = addr;

}

public String getRealName() {

return realName;

}

public void setRealName(String realName) {

this.realName = realName;

}

}

模板解析Util类:

TemplateParseUtil

[java] view
plain copy

package util;

/**

* 模板解析实体类

*/

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStreamWriter;

import java.io.StringWriter;

import java.io.Writer;

import java.util.Map;

import freemarker.cache.StringTemplateLoader;

import freemarker.template.Configuration;

import freemarker.template.DefaultObjectWrapper;

import freemarker.template.Template;

import freemarker.template.TemplateException;

public class TemplateParseUtil {

/**

* 解析模板生成Excel

* @param templateDir 模板目录

* @param templateName 模板名称

* @param excelPath 生成的Excel文件路径

* @param data 数据参数

* @throws IOException

* @throws TemplateException

*/

public static void parse(String templateDir,String templateName,String excelPath,Map<String,Object> data) throws IOException, TemplateException {

//初始化工作

Configuration cfg = new Configuration();

//设置默认编码格式为UTF-8

cfg.setDefaultEncoding("UTF-8");

//全局数字格式

cfg.setNumberFormat("0.00");

//设置模板文件位置

cfg.setDirectoryForTemplateLoading(new File(templateDir));

cfg.setObjectWrapper(new DefaultObjectWrapper());

//加载模板

Template template = cfg.getTemplate(templateName,"utf-8");

OutputStreamWriter writer = null;

try{

//填充数据至Excel

writer = new OutputStreamWriter(new FileOutputStream(excelPath),"UTF-8");

template.process(data, writer);

writer.flush();

}finally{

writer.close();

}

}

/**

* 解析模板返回字节数组

* @param templateDir 模板目录

* @param templateName 模板名称

* @param data 数据参数

* @throws IOException

* @throws TemplateException

*/

public static byte[] parse(String templateDir,String templateName,Map<String,Object> data) throws TemplateException, IOException{

Configuration cfg = new Configuration();

cfg.setDefaultEncoding("UTF-8");

cfg.setNumberFormat("0.00");

cfg.setDirectoryForTemplateLoading(new File(templateDir));

cfg.setObjectWrapper(new DefaultObjectWrapper());

Template template = cfg.getTemplate(templateName,"utf-8");

ByteArrayOutputStream outStream = new ByteArrayOutputStream();

Writer out = new OutputStreamWriter(outStream,"UTF-8");

template.process(data, out);

return outStream.toByteArray();

}

/**

* 自定义模板字符串解析

* @param templateStr 模板字符串

* @param data 数据

* @return 解析后的字符串

* @throws IOException

* @throws TemplateException

*/

public static String parse(String templateStr, Map<String, Object> data)

throws IOException, TemplateException {

Configuration cfg = new Configuration();

cfg.setNumberFormat("#.##");

//设置装载模板

StringTemplateLoader stringLoader = new StringTemplateLoader();

stringLoader.putTemplate("myTemplate", templateStr);

cfg.setTemplateLoader(stringLoader);

//加载装载的模板

Template temp = cfg.getTemplate("myTemplate", "utf-8");

Writer out = new StringWriter();

temp.process(data, out);

return out.toString();

}

}


2.xml生成

创建模板:

新建一个文件xml文件:

内容如下:

[html] view
plain copy

<?xml version="1.0" encoding="UTF-8"?>

<xml>

<userList>

<#list userList as user>

<user>

<userName>${user.userName!}</userName>

<passWord>${user.passWord!}</passWord>

<realName>${user.realName!}</realName>

<age>${user.age!}</age>

<addr>${user.addr!}</addr>

</user>

</#list>

</userList>

</xml>

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

注:

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

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

测试:

java

[java] view
plain copy

/**

* 测试XML文件的生成

*/

@Test

public void xmlTest(){

List<User> userList = new ArrayList<User>();

for(int i = 1 ; i <= 3;i ++){

User user = new User();

user.setUserName("狗娃" + i);

user.setRealName("许文强");

user.setPassWord("123456");

user.setAddr("上海虎头帮总舵");

user.setAge("28");

userList.add(user);

}

//测试Excel文件生成

Map<String,Object> data = new HashMap<String, Object>();

data.put("userList", userList);

try {

TemplateParseUtil.parse("template", "xml.ftl", "tempFile/xmlTest.xml", data);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (TemplateException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

结果:

生成了:



内容如下:

[html] view
plain copy

<?xml version="1.0" encoding="UTF-8"?>

<xml>

<userList>

<user>

<userName>狗娃1</userName>

<passWord>123456</passWord>

<realName>许文强</realName>

<age>28</age>

<addr>上海虎头帮总舵</addr>

</user>

<user>

<userName>狗娃2</userName>

<passWord>123456</passWord>

<realName>许文强</realName>

<age>28</age>

<addr>上海虎头帮总舵</addr>

</user>

<user>

<userName>狗娃3</userName>

<passWord>123456</passWord>

<realName>许文强</realName>

<age>28</age>

<addr>上海虎头帮总舵</addr>

</user>

</userList>

</xml>


3.html生成

创建模板:

新建一个文件html文件:

内容如下:

[html] view
plain copy

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

<table border='1' width="99%">

<tr>

<td colspan="5" align="center"><font color="red" size="6">user用户列表〃</font></td>

</tr>

<#list userList as user>

<tr>

<td>${user.userName}</td>

<td>${user.passWord}</td>

<td>${user.realName}</td>

<td>${user.age}</td>

<td>${user.addr}</td>

</tr>

</#list>

</table>

</body>

</html>

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

测试:

java

[java] view
plain copy

/**

* 测试HTML文件的生成

*/

@Test

public void htmlTest(){

List<User> userList = new ArrayList<User>();

for(int i = 1 ; i <= 3;i ++){

User user = new User();

user.setUserName("狗娃" + i);

user.setRealName("许文强");

user.setPassWord("123456");

user.setAddr("上海虎头帮总舵");

user.setAge("28");

userList.add(user);

}

//测试Excel文件生成

Map<String,Object> data = new HashMap<String, Object>();

data.put("userList", userList);

try {

TemplateParseUtil.parse("template", "html.ftl", "tempFile/htmlTest.html", data);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (TemplateException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

结果:

生成了:



内容如下:

[html] view
plain copy

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

<table border='1' width="99%">

<tr>

<td colspan="5" align="center"><font color="red" size="6">user用户列表</font></td>

</tr>

<tr>

<td>狗娃1</td>

<td>123456</td>

<td>许文强</td>

<td>28</td>

<td>上海虎头帮总舵</td>

</tr>

<tr>

<td>狗娃2</td>

<td>123456</td>

<td>许文强</td>

<td>28</td>

<td>上海虎头帮总舵</td>

</tr>

<tr>

<td>狗娃3</td>

<td>123456</td>

<td>许文强</td>

<td>28</td>

<td>上海虎头帮总舵</td>

</tr>

</table>

</body>

</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

/**

* 测试Excel文件的生成

*/

@Test

public void excelTest(){

List<User> userList = new ArrayList<User>();

for(int i = 1 ; i < 10;i ++){

User user = new User();

user.setUserName("狗娃" + i);

user.setRealName("许文强");

user.setPassWord("123456");

user.setAddr("上海虎头帮总舵");

user.setAge("28");

userList.add(user);

}

//测试Excel文件生成

Map<String,Object> data = new HashMap<String, Object>();

data.put("userList", userList);

try {

TemplateParseUtil.parse("template", "excel.ftl", "tempFile/excelTest.xls", data);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (TemplateException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

结果:

生成了:



打开:



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

内容如下:




5.word生成

创建模板:

新建word



然后另存为xml格式



用EditPlus打开



将选中的改为:



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

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

测试:

[java] view
plain copy

/**

* 测试Word文件的生成

*/

@Test

public void wordTest(){

Map<String,Object> data = new HashMap<String,Object>();

List<OptionQuestions> options = new ArrayList<OptionQuestions>();

for(int i = 1;i <= 10; i++){

OptionQuestions option = new OptionQuestions();

option.setContent(i + "." + "“给力”这个词出自以下哪本名著?");

option.setOption1("A." + "《不给力啊,老湿》");

option.setOption2("B." + "《这货不是宿敌》");

option.setOption3("C." + "《西游记:旅程的终点》");

option.setOption4("D." + "《屌丝也有春天》");

options.add(option);

}

List<String> judges = new ArrayList<String>();

for(int i = 1;i <= 5; i++){

judges.add(i + "." + "正方形、长方形、平行四边形和梯形都是特殊四边形");

}

data.put("title", "全国人大代表考试题");

data.put("options", options);

data.put("judges",judges);

try {

TemplateParseUtil.parse("template", "word.ftl", "tempFile/wordTest.doc", data);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (TemplateException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

结果:

生成了:



内容如下:




6.下载地址

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

工程 及 freemarker.jar 下载地址:http://download.csdn.net/detail/u010722643/8224995
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: