需求描述:在当前项目中实现word附件的下载,且附件中的部分数据是需要查询数据库动态生成的。
需求分析:完成该需求需要使用Freemarker模板技术
需求实现:
1. ftl模板准备:打开word文档,将文档另存为xml文件(word支持)。新生成的xml文档是没有格式,这时候,将文档内容复制到一个jsp中, 格式化代码即可(Eclipse快捷键:Ctrl + Shift + F). 在类路径下新建ftl文件,并将格式化好的xml文件内容复制进去。
2. 在pom文件中引入freemarker依赖。
<dependency>
<groupId>freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.9</version>
</dependency>
- Freemarker工具类:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
public class FreeMarkerUtils {
private static Configuration configuration;
/**
* 生成Freemarker配置对象并设置模板读取路径
*/
static {
if (null == configuration) {
configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
configuration.setClassForTemplateLoading(FreeMarkerUtils.class, "/templates");
// 设置对象的包装器
configuration.setObjectWrapper(new DefaultObjectWrapper());
// 设置异常处理器//这样的话就可以${a.b.c.d}即使没有属性也不会出错
configuration.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
}
}
/**
* <pre>getTemplate(获取Freemarker模板)
* @param templateName 模板名称
* @return
* @throws IOException</pre>
*/
private static Template getTemplate(String templateName) throws IOException{
Template template = configuration.getTemplate(templateName);
template.setEncoding("UTF-8");
return template;
}
/**
* <pre>write(生成模板文件)
* @param templateName 模板的名称
* @param rootMap 模板中数据的集合</pre>
*/
public static File write(String templateName, Map<String, Object> rootMap){
File file = new File("tempFileName");
try {
Template template = getTemplate(templateName);
Writer out = new OutputStreamWriter(new FileOutputStream(file),"utf-8");
template.process(rootMap, out);
out.close();
} catch (IOException | TemplateException e) {
e.printStackTrace();
}
return file;
}
}
- web层实现(Web层使用SpringMVC)
@RequestMapping("/repaymentapply")
public void repayapply(@RequestParam Map<String, Object> requestParam,
HttpServletResponse response) {
Map<String, Object> data = repaymentService.getRepaymentapply(requestParam);
if (data == null) {
data = new HashMap<String, Object>();
}
response.setCharacterEncoding("UTF-8");
response.setContentType("application/msword");
File file = null;
InputStream inputStream = null;
ServletOutputStream out = null;
try {
String fileName = "还款申请书.doc";
fileName = new String(fileName.getBytes("gbk"),"iso-8859-1");
response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
file = FreeMarkerUtils.write("repaymentapply.ftl", data);
inputStream = new FileInputStream(file);
out = response.getOutputStream();
byte[] buffer = new byte[512]; // 缓冲区
int bytesToRead = -1;
// 通过循环将读入的Word文件的内容输出到浏览器中
while((bytesToRead = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, bytesToRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (out != null) {
out.close();
}
if (file != null) {
file.delete();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
参考链接:
http://blog.youkuaiyun.com/jackfrued/article/details/39449021
http://songfeng-123.iteye.com/blog/2333116
http://www.wang1314.com/doc/topic-1568137-1.html