第一步
使用office新建一个word文档,加入图片,排好版。将需要替换的字段使用占位符替换过后,然后保存为word2003xml,刚开始保存为word xml图片没有解析出来。
第二步
使用格式化工具http://tool.oschina.net/codeformat/xml/进行格式化,修改后缀为ftl。需要自己先打开看一下是否有格式错乱问题。
第三步
导入freemarker-2.3.22.jar commons-lang-2.4.jar
工具类
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.WordUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
public class FreeMakerUtils {
private static Configuration configuration = null;
//这里注意的是利用WordUtils的类加载器动态获得模板文件的位置
private static final String templateFolder = WordUtils.class.getClassLoader().getResource("../../").getPath() + "WEB-INF/classes/templates/modules/gen";
static {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
try {
configuration.setDirectoryForTemplateLoading(new File(templateFolder));
} catch (IOException e) {
e.printStackTrace();
}
}
private FreeMakerUtils() {
throw new AssertionError();
}
/**
*
* @Title: exportMillCertificateWord
* @Description:
* @param request
* @param response
* @param map 替换参数集合
* @throws IOException void
* @author wyp
* @date 2018年6月26日上午10:11:06
*/
public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map) throws IOException {
String flag = (String) map.get("flag");
Template freemarkerTemplate=null;
if("阴性".equals(flag)){
freemarkerTemplate = configuration.getTemplate("neg.ftl");
}else{
freemarkerTemplate = configuration.getTemplate("positive.ftl");
}
File file = null;
InputStream fin = null;
ServletOutputStream out = null;
try {
// 调用工具类的createDoc方法生成Word文档
file = createDoc(map,freemarkerTemplate);
fin = new FileInputStream(file);
response.setCharacterEncoding("utf-8");
response.setContentType("application/msword; charset=UTF-8");
// 设置浏览器以下载的方式处理该文件名
String fileName = map.get("name")+"检验单.doc";
response.setHeader("Content-Disposition", "attachment;filename="
.concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
out = response.getOutputStream();
byte[] buffer = new byte[1024]; // 缓冲区
int bytesToRead = -1;
// 通过循环将读入的Word文件的内容输出到浏览器中
while((bytesToRead = fin.read(buffer)) != -1) {
out.write(buffer, 0, bytesToRead);
}
} finally {
out.flush();
if(fin != null) fin.close();
if(out != null) out.close();
if(file != null) file.delete(); // 删除临时文件
}
}
private static File createDoc(Map<?, ?> dataMap, Template template) {
String name = "test.doc";
File f = new File(name);
Template t = template;
try {
// 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
t.process(dataMap, w);
w.close();
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
return f;
}
}
第四步
页面直接使用 window.open("${ctx}/core/experiment/replaceWord?id="+id); 或者 window.location.href
WordUtils.class.getClassLoader().getResource("../../").getPath() + "WEB-INF/classes/templates/modules/gen";
路径正确,但是会抛异常。路径编码格式问题
java.io.FileNotFoundException: D:\Program%20Files\Apache%20Software%20Foundation\Tomcat%208.0\wtpwebapps\mgzl1\WEB-INF\classes\templates\modules\gen does not exist.
可修改为
private static final String templateFolder = PathUtils.getClassResources()+"templates/modules/gen";
public class PathUtils {
public static String getClassResources(){
String path = (String.valueOf(Thread.currentThread().getContextClassLoader().getResource(""))).replaceAll("file:/", "").replaceAll("%20", " ").trim();
if(path.indexOf(":") != 1){
path = File.separator + path;
}
return path;
}}
也可以直接将上面直接注释掉,使用构造方法进行获取模板位置
WordUtils的类加载器
将其修改为
public FreeMakerUtils() {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
configuration.setClassForTemplateLoading(this.getClass(),
"/templates/modules/gen");
// throw new AssertionError();
}
同时页面调用时必须先创建实体类,进行初始化。若直接调用静态方法会报空指针异常
FreeMakerUtils freeMakerUtils = new FreeMakerUtils();
freeMakerUtils.exportMillCertificateWord(request, response, map);