Freemarker官网,英文,可以用谷歌浏览器的自动翻译,英文水平高的忽略这句。。
简单来说:FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写。FreeMarker被设计用来生成HTMLWeb页面,特别是基于MVC模式的应用程序。
这里使用freemarker生成Word文档,非常方便。
惯例,先看看Demo整体结构:
Demo结构:
这里要引入freemarker包,通过Freemarker加载word文档的模版
生成Word文档类ToCreateDoc:
package org.javasun.createDoc;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class ToCreateDoc {
private Configuration configuration = null;
public ToCreateDoc() {
configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
}
public void createDoc(Writer out, Map<String, Object> dataMap, String ftlName) {
configuration.setClassForTemplateLoading(getClass(), "/ftl");
try {
Template t = null;
t = configuration.getTemplate(ftlName,"UTF-8");
t.process(dataMap, out);
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Servlet,填数据发送客户端处理:
package org.javasun.servlet;
import java.io.IOException;
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 org.javasun.createDoc.ToCreateDoc;
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
public DownloadServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 设置response类型
String fileName = "test.doc";
// 设置响应正文的MIME类型
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Disposition", "attachment;" + " filename=" + fileName);
// 获取数据,设置数据
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("company", "XXX百货公司");
dataMap.put("companyname", "XXX批发商");
dataMap.put("addr", "太原市XXXX");
dataMap.put("contact", "张文先生");
dataMap.put("phone", "12345678");
List<Map<String, String>> payList = new ArrayList<>();
for (int i = 1; i < 8; i++) {
Map<String, String> iMap = new HashMap<>();
iMap.put("proName", "智能手机" + i + "0");
iMap.put("pay", i * 1000 + "");
iMap.put("num", "105");
iMap.put("total", "100333");
payList.add(iMap);
}
dataMap.put("itemlist", payList);
// 把本地文件发送给客户端
Writer out = response.getWriter();
ToCreateDoc tcd = new ToCreateDoc();
tcd.createDoc(out, dataMap, "demo.ftl");
out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
Jsp页面测试效果:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!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></title>
<script type="text/javascript">
function download_file(url){
if (typeof (download_file.iframe) == "undefined")
{
var iframe = document.createElement("iframe");
download_file.iframe = iframe;
document.body.appendChild(download_file.iframe);
}
download_file.iframe.src = url;
download_file.iframe.style.display = "none";
}
</script>
</head>
<body>
<button οnclick="download_file('download');" >单击生成Word文档</button>
</body>
</html>
点击按钮,Word文档就会自动下载,下载的文件如图:
我们可以看到,很方便,只要定义好文件模版,就可以将数据库数据导入成文档格式保存或者打印。
那么如何定义模版呢?
将需要的Word文档做好之后(一般是没有数据的一种文档模版格式),选择另存为XML文件,存为XML的目的是方便检查,看看${}占位符的内容是否被分开了(分开之后会导致很多问题,所以要调整格式,修改一下XML文件),之后另存为.ftl模版文件就OK了,在项目中引用就可以实现内容按所想的格式输出。
如何引用?
Freemarker提供了3种加载模板目录的方法。 它使用Configuration类加载模板
3种方法分别是:
public voidsetClassForTemplateLoading(Class clazz, String pathPrefix);
public voidsetDirectoryForTemplateLoading(File dir) throws IOException;
public voidsetServletContextForTemplateLoading(Object servletContext, String path);
分别基于类路径、文件系统以及Servlet Context路径。
注意事项(导出的Word文档很容易出现乱码)如何解决?
我们在做模板导出时需要注意以下三处编码集的设置,有一处没有设置就会导致到处uWord文档出现中文乱码。
(1)configuration.setDefaultEncoding("UTF-8");
(2)Template t =configuration.getTemplate("模板文件","UTF-8");
(3)Writer out = newBufferedWriter(new OutputStreamWriter(文件输出流 fos, "UTF-8"))。
Demo下载地址:https://github.com/guodalin8/ToWordTest