最近项目中用到了导出word。突然想到博客中没有这样的一篇文章,借此机会进行充足一下。
其实跟html导出一样的道理。获取模板,调用freemaker的方法将数据写到模版中。利用el表达式
进行渲染即可。好多都是固定写法。写出的一个demo,已经测过可用。
DEMO已经上传,欢迎下载:http://download.csdn.net/download/a909422229/10191535
使用Freemaker原因
1.将一些不会修改的文件使用静态资源,不会存在性能问题,加载效率也会提升,例如商品的详情页面。
2.打印接口
3.速度快,省去了Jsp编译过程
使用步骤
1.获取模板,对模板进行基本设置,例如:编码、模板所在路径、模板名称
2.设置模板生成文件的路径、文件名,调用process方法,使用流将数据写到模板中。
FreeMarker具备以下优点:
1、逻辑分离好,View层不出现逻辑代码,可维护性好
2、美工和技术的工作分离
3、速度快,省去了Jsp编译过程
4、可以在IDE中运行,换句话说是可以进行单元测试
5、可以制作Macro
项目中:
门户中管理员会发布一些通知公告,样式内容是相同的,只是内容不同。
而且都是固定不变的内容,所以使用freemarker模板进行静态资源。
这样nginx直接将静态资源拿过来展示即可。
本次使用的jar:freemarker-2.3.19.jar
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.entity.User;
import freemarker.template.Configuration;
import freemarker.template.Template;
@WebServlet(urlPatterns = "/wordTest", name = "wordServlet")
public class WordTest extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final String modelName = "word.ftl";
private static final String modelUrl = "/com/ftlmodel";
private static final String exportFilePath = "D:/outFile.doc";
private static final String newName = "word.doc";
//加载模版路径
private Configuration configuration = null;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("1");
Map<String, Object> detaMap = new HashMap<String, Object>();
detaMap = getData(detaMap);
createDoc(modelName,modelUrl,exportFilePath,detaMap,newName,response);
}
/**
* word导出
*
* @param modelName
* 模板的名称
* @param modelUrl
* 放置模板的路径,格式:/url
* @param exportFilePath
* 导出的路径
* @param dataMap
* 导出文件的数据
* @param newName
* 导出文件的新名称
* @param response
*
* @author wangsh
* @date 2018年1月6日 10:27:00
* @version 1.0
*/
public void createDoc(String modelName, String modelUrl, String exportFilePath, Map<String, Object> dataMap,
String newName, HttpServletResponse response) {
configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
// 1、导入模板
configuration.setClassForTemplateLoading(this.getClass(), modelUrl);
// 2、打包数据--每次导出的word文件模板不同,打包数据的方法要单独写
// 3、导出文件
// 输出文档路径及名称
File outFile = new File(exportFilePath);
Writer out = null;
Template t = null;
try {
// test.ftl为要装载的模板。获取模板事例对象
t = configuration.getTemplate(modelName);
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"));
t.process(dataMap, out);
} catch (Exception e) {
e.printStackTrace();
}
upload(response, outFile, newName);
outFile.delete();
}
/**
* 下载文件
*
* @param response
* @param file
* 需要下载的文件路径
* @param fileName
* 文件名称
* @date 2018年1月6日 10:27:00
* @version 1.0
*/
public void upload(HttpServletResponse response, File file, String fileName) {
response.reset();// 清空输出流
response.setContentType("application/zip;charset=UTF-8");
try {
fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
try {
FileInputStream in = new FileInputStream(file);
OutputStream out = response.getOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.flush();
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 封装数据
* @param dataMap
* @return
*/
private Map<String, Object> getData(Map<String, Object> dataMap) {
User u = new User();
u.setId(1);
u.setName("姓名1");
u.setPhone("123");
u.setAge("10岁");
// User u1 = new User();
// u1.setId(2);
// u1.setName("姓名2");
// u1.setPhone("456");
// u1.setAge("20岁");
// List<User> list = new ArrayList<User>();
// list.add(u);
// list.add(u1);
dataMap.put("user", u);
return dataMap;
}
}
ftl模板建议使用:word导出2003版本的XML。后缀名修改为ftl即可。另外为了方便浏览修改数据。可以使用代码格式化进行格式。http://tool.oschina.net/codeformat/xml/