1、用到的jar包
用到的jar包为freemarker-2.3.18.jar
<dependency>
<groupId>freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.1</version>
</dependency>
2、word模板文件处理
首先将确定好的word模板文件另存为xml格式,用notepad++打开,将要替换的部分用${**}替换掉,如下图所示:
如果有表格需要遍历显示的,找到对应需要遍历的行,在外层用<#list ? as row ></#list>进行包围,遍历的行用 ${row.?}来替换,如下图所示:
最后将替换好的xml文件后缀名改为.ftl.
3、java 代码部分
首先处理需要导出的数据,放入Map中(需要遍历的行数据以List
public void export(Long id,HttpServletResponse response) {
Configuration config = new Configuration();
config.setDefaultEncoding("UTF-8");
config.setClassForTemplateLoading(this.getClass(), "");
//获取需要导出的数据
Map<String, Object> dataMap = getDataMap(id);
Template t = null;
try {
//test.ftl为要装载的模板
String fileName = "立项申请书-" + System.currentTimeMillis() + ".doc";
String tempPath = AppConfigUtil.get("file.folder.root");
t = config.getTemplate("lxsq.ftl");
File outFile = new File(tempPath+File.separator+fileName);
if(!outFile.exists()){
outFile.createNewFile();
}
Writer out = null;
FileOutputStream fos=null;
fos = new FileOutputStream(outFile);
OutputStreamWriter oWriter = new OutputStreamWriter(fos,"UTF-8");
//这个地方对流的编码不可或缺,使用main()单独调用时,应该可以,但是如果是web请求导出时导出后word文档就会打不开,并且包XML文件错误。主要是编码格式不正确,无法解析。
//out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
out = new BufferedWriter(oWriter);
t.process(dataMap, out);
out.close();
fos.close();
download(outFile, response);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*下载生成的word文件并删除临时文件
*/
public void download(File file , HttpServletResponse response){
ServletOutputStream out = null;
FileInputStream inputStream = null;
try {
String filename = file.getName();
response.setCharacterEncoding("utf-8");
response.setContentType("application/DOWLOAD");
response.setHeader("Content-Disposition", "attachment; filename="+
String.valueOf(URLEncoder.encode(filename, "UTF-8")));
out = response.getOutputStream();
inputStream = new FileInputStream(file);
byte[] buffer = new byte[512];
int bytesToRead = -1;
// 通过循环将读入的Word文件的内容输出到浏览器中
while((bytesToRead = inputStream.read(buffer)) != -1){
out.write(buffer, 0, bytesToRead);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(null!=out) out.close();
if(null!=inputStream) inputStream.close();
file.delete();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
使用过程中注意在处理数据时要避免null值,否则导出过程会报错,此方法使用时处理好的模板需要放在java代码的同一级目录,具体Freemarker提供了3种加载模板目录的方法, 它使用Configuration类加载模板:
第一种:基于类路径,HttpWeb包下的framemaker.ftl文件
configuration.setClassForTemplateLoading(this.getClass(), "/HttpWeb");
configuration.getTemplate("framemaker.ftl"); //framemaker.ftl为要装载的模板
第二种:基于文件系统
configuration.setDirectoryForTemplateLoading(new File("/template"))
configuration.getTemplate("framemaker.ftl"); //framemaker.ftl为要装载的模板
第三种:基于Servlet Context,指的是基于WebRoot下的template下的framemaker.ftl文件
HttpServletRequest request = ServletActionContext.getRequest();
configuration.setServletContextForTemplateLoading(request.getSession().getServletContext(), "/template");
configuration.getTemplate("framemaker.ftl"); //framemaker.ftl为要装载的模板