最后将文件保存之后重命名,后缀由xml改为ftl。使得freemarker能识别相应的模板。
第二步:将ftl文件放入项目中。编写下载word的java代码。
项目的文件存放位置。
项目是比较简单的web项目,使用的是Struts2。下面是web.xml中的配置,一切从简。
只有一个简单的跳转,当链接访问/saveDocServlet的时候请求会进入MyServlet中,进行逻辑处理。
下面是MyServlet的代码;
package com.zhutong.servlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zhutong.util.WordGenerator;
public class MyServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding(“utf-8”);
Map<String, Object> map = new HashMap<String, Object>();
/* Enumeration paramNames = req.getParameterNames();
// 通过循环将表单参数放入键值对映射中
while (paramNames.hasMoreElements()) {
String key = paramNames.nextElement();
String value = req.getParameter(key);
map.put(key, value);
}*/
map.put(“topic”, “我是标题”);
map.put(“module”, “我是模块”);
// 提示:在调用工具类生成Word文档之前应当检查所有字段是否完整
// 否则Freemarker的模板殷勤在处理时可能会因为找不到值而报错 这里暂时忽略这个步骤了
File file = null;
InputStream fin = null;
ServletOutputStream out = null;
try {
// 调用工具类WordGenerator的createDoc方法生成Word文档
file = WordGenerator.createDoc(map, “resume”);
fin = new FileInputStream(file);
resp.setCharacterEncoding(“utf-8”);
resp.setContentType(“application/msword”);
// 设置浏览器以下载的方式处理该文件默认名为resume.doc
resp.addHeader(“Content-Disposition”,“attachment;filename=resume.doc”);
out = resp.getOutputStream();
byte[] buffer = new byte[512]; // 缓冲区
int bytesToRead = -1;
// 通过循环将读入的Word文件的内容输出到浏览器中
while ((bytesToRead = fin.read(buffer)) != -1) {
out.write(buffer, 0, bytesToRead);
}
} finally {
if (fin != null)
fin.close();
if (out != null)
out.close();
if (file != null)
file.delete(); // 删除临时文件
}
}
}
map中key值对应ftl模板${topic}中的属性,可以直接取到key值对应的value值。value值可以是写死的,可以是前后台交互的变量,上面代码中注释的是其中一部分,稍加扩展就可以实现。
上面代码中引用到一个生成word文件的工具类WordGenerator.createDoc(map,“resume”)
下面是工具类的对应的代码:
package com.zhutong.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
@SuppressWarnings(“deprecation”)
public class WordGenerator {
private static Configuration configuration = null;
private static HashMap<String, Template> allTemplates = null;
static {
configuration = new Configuration();
configuration.setDefaultEncoding(“utf-8”);
configuration.setClassForTemplateLoading(WordGenerator.class,“/com/zhutong/ftl”);
/*
- allTemplates = new HashMap<>(); // Java 7 钻石语法
*/
allTemplates = new HashMap<String, Template>();
try {
allTemplates.put(“resume”, configuration.getTemplate(“resume.ftl”));
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
private WordGenerator() {
throw new AssertionError();
}
public static File createDoc(Map<?, ?> dataMap, String type) {
String name = “temp” + (int) (Math.random() * 100000) + “.doc”;
File f = new File(name);
Template t = allTemplates.get(type);
try {
// 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
Writer w = new OutputStreamWriter(new FileOutputStream(f), “utf-8”);
t.process(dataMap, w);
w.close();
} catch (Exception ex) {
ex.printStackTrace();