实现步骤:
1.编辑word模板,并将需要显示数据的地方标注出来。
2.将word模板另存为xml文件(为了兼容,最好使用Word 2003 XML文档)
3.替换标记。
使用xml编辑工具(我用的NotePad++)打开该xml文件,将标记的部分改为${tagName},如上文的number改为${number}。
注意:1.xml文件样式可能比较乱,为方便查看,可以使用xml在线格式化工具格式化。
2.图片占位的地方,会看到一片base64编码后的代码,把base64替换成${image}。
4.更改文件后缀为.ftl,注意:不要使用word代开ftl文件
5.代码实现:
index.jsp
framemarker导出wordframemarker导出word
我自己的端口号为9080
编辑导出Word 的Servlet:
packagecom.framemarker.word.test;importjava.io.File;importjava.io.FileInputStream;importjava.io.IOException;importjava.io.InputStream;importjava.util.HashMap;importjava.util.Map;importjavax.servlet.ServletException;importjavax.servlet.ServletOutputStream;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importsun.misc.BASE64Encoder;
@SuppressWarnings("serial")public class WordExport extendsHttpServlet {
@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse res) throwsServletException, IOException {
Map dataMap = new HashMap();//存放成绩
Map reportMap = new HashMap();
reportMap.put("yuwen", "100");
reportMap.put("shuxue", "99");
reportMap.put("yingyu", "86");
reportMap.put("wuli", "75");
reportMap.put("huaxue", "80");
reportMap.put("shengwu", "90");//存放个人信息及reportMap
dataMap.put("number", "111222331");
dataMap.put("roomNo", "110");
dataMap.put("name", "张三");
dataMap.put("score", "100");
dataMap.put("image", WordUtils.imgEncode("C:/Users/HOME/Desktop/image.jpg"));
dataMap.put("reportMap", reportMap);//生成word并下载
File file = null;
InputStream inputStream= null;
ServletOutputStream out= null;
String fileName= "test.doc";
String ftlName= "test1.ftl";try{
file=WordUtils.wordCreate(dataMap, fileName, ftlName);
inputStream= newFileInputStream(file);
res.setCharacterEncoding("UTF-8");
res.setContentType("application/msword");
res.addHeader("Content-Disposition", "attachment;filename = export.doc");
out=res.getOutputStream();byte[] buffer = new byte[1024]; //缓冲区
int bytesToRead = -1;//通过循环将读入的Word文件的内容输出到浏览器中
while ((bytesToRead = inputStream.read(buffer)) != -1) {
out.write(buffer,0, bytesToRead);
}
}catch(Exception e) {//TODO: handle exception
} finally{if (inputStream != null)
inputStream.close();if (out != null)
out.close();if (file != null)
file.delete();
}
}
}
工具类:
packagecom.framemarker.word.test;importjava.io.BufferedWriter;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStreamWriter;importjava.io.Writer;importjava.util.Map;importfreemarker.template.Configuration;importfreemarker.template.Template;importsun.misc.BASE64Encoder;public classWordUtils {/***@paramdataMap 存放标记和对应的值
*@paramfileName 生成的临时word文件名
*@paramftlName 模板文件名
*@return生成的临时word文件
*@throwsIOException*/
public static File wordCreate(Map dataMap, String fileName, String ftlName) throwsIOException {
Configuration configuration= newConfiguration();
configuration.setDefaultEncoding("UTF-8");//使用包路径加载模板
configuration.setClassForTemplateLoading(WordUtils.class, "/com/framemarker/word/template");
File outFile= newFile(fileName);
Template template= null;try{
template=configuration.getTemplate(ftlName);
Writer writer= new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8"));
template.process(dataMap, writer);
writer.flush();
writer.close();
}catch(Exception e) {//TODO: handle exception
}returnoutFile;
}/*** 根据绝对路径获取该图片的编码
*
*@paramabsolutePath
*@return*@throwsIOException*/
public static String imgEncode(String absolutePath) throwsIOException {if (absolutePath == null || absolutePath == "")return "";
File file= newFile(absolutePath);if (!file.exists())return "";
InputStream in= null;byte[] data = null;try{
in= newFileInputStream(file);
data= new byte[in.available()];
in.read(data);
}catch(IOException e) {//TODO Auto-generated catch block
e.printStackTrace();
}finally{
in.close();
}
BASE64Encoder encoder= newBASE64Encoder();returnencoder.encode(data);
}
}
6.结果实现
注意:有些标记不是简单替换就可以的,需要进行非空判断等操作,具体的需要去了解framemarker中标签的使用。