1、 步骤
1、 用word编辑好模板
1、 普通字符串替换为 ${string}
2、 表格循环用标签
姓名:${user.userName} , 性别:${user.sex}#list>
word模板原型如下图:
最终生成的结果如下:
2、 将word模板另存为xml格式
选中 [ 仅保存数据 ]
选择 [ 保持wordML(K) ]
3、 将xml模板文件后缀名改为.ftl
4、 编辑ftl文件
搜索关键字,补入 #list>或其它freemarker标签
如下图:
2、 Java代码
packagecom.lun.utils;importjava.io.BufferedWriter;importjava.io.File;importjava.io.FileOutputStream;importjava.io.OutputStreamWriter;importjava.io.Writer;importjava.util.Map;importfreemarker.template.Configuration;importfreemarker.template.Template;/*** @Desc:word操作工具类
* @Author:张轮
* @Date:2014-1-22下午05:03:19*/
public classWordUtil {/*** @Desc:生成word文件
* @Author:张轮
* @Date:2014-1-22下午05:33:42
*@paramdataMap word中需要展示的动态数据,用map集合来保存
*@paramtemplateName word模板名称,例如:test.ftl
*@paramfilePath 文件生成的目标路径,例如:D:/wordFile/
*@paramfileName 生成的文件名称,例如:test.doc*/@SuppressWarnings("unchecked")public static voidcreateWord(Map dataMap, String templateName,
String filePath, String fileName) {try{//创建配置实例
Configuration configuration = newConfiguration();//设置编码
configuration.setDefaultEncoding("UTF-8");//ftl模板文件统一放至 com.lun.template 包下面
configuration.setClassForTemplateLoading(WordUtil.class,"/com/lun/template/");//获取模板
Template template =configuration.getTemplate(templateName);//输出文件
File outFile = new File(filePath + File.separator +fileName);//如果输出目标文件夹不存在,则创建
if (!outFile.getParentFile().exists()) {
outFile.getParentFile().mkdirs();
}//将模板和数据模型合并生成文件
Writer out = new BufferedWriter(newOutputStreamWriter(new FileOutputStream(outFile), "UTF-8"));//生成文件
template.process(dataMap, out);//关闭流
out.flush();
out.close();
}catch(Exception e) {
e.printStackTrace();
}
}
}
packagecom.lun.action;importjava.io.File;importjava.io.FileInputStream;importjava.io.InputStream;importjava.net.URLDecoder;importjava.text.SimpleDateFormat;importjava.util.ArrayList;importjava.util.Date;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importjava.util.Random;importorg.apache.struts2.ServletActionContext;importcom.lun.utils.WordUtil;importcom.opensymphony.xwork2.ActionSupport;/*** @Desc:生成word
* @Author:张轮
* @Date:2014-1-22下午04:52:03*/@SuppressWarnings("serial")public class WordAction extendsActionSupport{private String filePath; //文件路径
private String fileName; //文件名称
private String fileOnlyName; //文件唯一名称
/*** @Desc:生成word文档
* @Author:张轮
* @Date:2014-1-22下午07:29:58
*@return
*/
publicString createWord() {/**用于组装word页面需要的数据*/Map dataMap = new HashMap();/**组装数据*/dataMap.put("userName","张三");
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日");
dataMap.put("currDate",sdf.format(newDate()));
dataMap.put("content","这是其它内容这是其它内容这是其它内容这是其它内容这是其它内容这是其它内容这是其它内容这是其它内容这是其它内容这是其它内容这是其它内容这是其它内容这是其它内容");
List> newsList=new ArrayList>();for(int i=1;i<=10;i++){
Map map=new HashMap();
map.put("title", "标题"+i);
map.put("content", "内容"+(i*2));
map.put("author", "作者"+(i*3));
newsList.add(map);
}
dataMap.put("newsList",newsList);/**文件名称,唯一字符串*/Random r=newRandom();
SimpleDateFormat sdf1=new SimpleDateFormat("yyyyMMdd_HHmmss_SSS");
StringBuffer sb=newStringBuffer();
sb.append(sdf1.format(newDate()));
sb.append("_");
sb.append(r.nextInt(100));//文件路径
filePath=ServletActionContext.getServletContext().getRealPath("/")+"upload";//文件唯一名称
fileOnlyName = "用freemarker导出的Word文档_"+sb+".doc";//文件名称
fileName="用freemarker导出的Word文档.doc";/**生成word*/WordUtil.createWord(dataMap,"news.ftl", filePath, fileOnlyName);return "createWordSuccess";
}
/*** @Desc:下载生成的word文档,入口,用来跳转至struts XML配置
* @Author:张轮
* @Date:2014-1-22下午07:36:29
*@return
*/
publicString dowloadWord() {/**先判断文件是否已生成*/
try{//解决中文乱码
filePath = URLDecoder.decode(filePath, "UTF-8");
fileOnlyName= URLDecoder.decode(fileOnlyName, "UTF-8");
fileName= URLDecoder.decode(fileName, "UTF-8");//如果文件不存在,则会跳入异常,然后可以进行异常处理
new FileInputStream(filePath + File.separator +fileOnlyName);
}catch(Exception e) {
e.printStackTrace();return "error";
}return "dowloadWord";
}
/*** @Desc:下载生成的word文档
* 该方法是struts.xml文件中的: wordFile 中自动对应的get方法,该方法自动调用
* @Author:张轮
* @Date:2014-1-22下午07:36:29
*@return返回最终生成的word文档 文件流*/
publicInputStream getWordFile(){try{//解决中文乱码
fileName = URLDecoder.decode(fileName, "UTF-8");/**返回最终生成的word文件流*/
return new FileInputStream(filePath + File.separator +fileOnlyName);
}catch(Exception e) {
e.printStackTrace();return null;
}
}publicString getFilePath() {returnfilePath;
}public voidsetFilePath(String filePath) {this.filePath =filePath;
}publicString getFileName() {returnfileName;
}public voidsetFileName(String fileName) {this.fileName =fileName;
}publicString getFileOnlyName() {returnfileOnlyName;
}public voidsetFileOnlyName(String fileOnlyName) {this.fileOnlyName =fileOnlyName;
}
}
struts2配置文件如下:
/p>
"http://struts.apache.org/dtds/struts-2.0.dtd">
dowloadWord
${filePath}
${fileOnlyName}
${fileName}
true
attachment;filename="${fileName}"
wordFile
true
/error.jsp
页面调用如下:
3、注意
1、编辑word模板时,${string} 标签最好是手动一次性输入完毕,或者使用记事本统一将整个${string}编辑好之后,粘贴至word里边。
也就是说,不要在word里首先打完 ${ } 之后,又从其它地方把 string 字符串粘贴至 { } 之间,这样在 word 转化为 xml时,解析会有问题,freemarker解析时,会报错。
将${} 和 string 分开录入word,另存为xml后,后果将如下:
2、如果word里有需要循环表格列,也就是横向循环表格时,建议尽量改为循环行,纵向循环,这样可以减少对 ftl 文件的 list标签插入,缩减工作量。
本文转自:http://blog.csdn.net/lun379292733/article/details/18673081