** 需要jar包 freemarker-2.3.8.jar
1、创建word模板:
首先使用 offic或wps(我用的就是wps) 创建一个 word.docx 文件
在文件中输入 ${test} 并将文件保存为 xml 格式,其中 ${test} 就是我们在程序中要替换的目标,重点是 ${} 这个符号,里面的字内容可以自己定义。
2、保存为 ftl 格式
将word.xml 直接重命名为 word.ftl,并放到项目目录下
3、写代码(直接下载版):
package com.soft.out_word;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
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 freemarker.template.Configuration;
import freemarker.template.Template;
@WebServlet("/OutWord")
public class OutWord extends HttpServlet {
private Configuration configuration = null;
private static final long serialVersionUID = -8933774728508351159L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
configuration = new Configuration(Configuration.VERSION_2_3_28);
configuration.setDefaultEncoding("UTF-8");
Map<String,Object> dataMap=new HashMap<String,Object>();
dataMap.put("test", "测试");
configuration.setClassForTemplateLoading(this.getClass(), "/"); //FTL文件所存在的位置
Template template = null;
try {
template = configuration.getTemplate("word.ftl"); //文件名
response.setHeader("Content-disposition","attachment;filename="+UUID.randomUUID().toString()+".doc");
response.setContentType("application/msword;charset=UTF-8");
PrintWriter writer = response.getWriter();
template.process(dataMap, writer);
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
从代码中可以看出,只需要将目标位置和需要加入的数据存在 dataMap 中即可,程序会将数据替换到目标位置。
4、导出word(写成文件版)
package com.soft.out_word;
import java.io.BufferedWriter;
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 javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import freemarker.template.Configuration;
import freemarker.template.Template;
/**
* Servlet implementation class outWord2
*/
@WebServlet("/outWord2")
public class outWord2 extends HttpServlet {
private static final long serialVersionUID = 1L;
private Configuration configuration = null;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
configuration = new Configuration(Configuration.VERSION_2_3_28);
configuration.setDefaultEncoding("UTF-8");
Map<String, Object> dataMap = new HashMap<String, Object>();
dataMap.put("test", "测试");
configuration.setClassForTemplateLoading(this.getClass(), "/"); // FTL文件所存在的位置
Template template = null;
try {
template = configuration.getTemplate("word.ftl"); // 文件名
File outFile = new File("D:\\demo.docx");
FileOutputStream fos = new FileOutputStream(outFile);
OutputStreamWriter oWriter = new OutputStreamWriter(fos, "UTF-8");
Writer out = new BufferedWriter(oWriter);
template.process(dataMap, out);
out.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
合并单元格:
参考链接:https://www.cnblogs.com/10158wsj/p/11211471.html
freemarker 无法实现合并单元格,因为其本省只是替换数据,但是我们可以通过word本身的标签做到合并,
使用的标签是 <w:vMerge w:val='restart'/> 和 <w:vMerge/>
原则一、第一行数据只放"<w:vMerge w:val='restart'/>",从第二行开始,所有要合并的单元格放"<w:vMerge/>"。
public List<Map<String, String>> checkList(List<Map<String, String>> list) {
String start = "<w:vMerge w:val='restart'/>";
String end = "<w:vMerge/>";
list.get(0).put("start", start);
for (int i = 1; i < list.size(); i++) {
list.get(i).put("end", end);
}
return list;
}