1.首先需要借助office将需要的word模板转成xml文件
在此操作之前需要将需要填入内容的地方用${name}进行占位,其中name为属性值,可以为map的key。
如下图:
其中keycode和unitname为我接下来需要填入的相应框中的一个查询结果的类中的两个属性,当然为了处理的方便我也将它们存入了一个map
设计好模板后然后用word(ps:WPS不行)的另存为功能,存为xml文件。
2.将xml文件转为ftl文件
接下来我们需要处理一下转成的xml文件,因为有时这些占位符的内容会被一对格式分开,这样的话freemarker引擎就无法正常解析了
需要成为如下的样子,也就是保持占位符还是书写时的样子
修改完毕后保存,然后将其另存为ftl格式的文件
3.引入freemarkerjar包
可去如下地址下载:
http://freemarker.org/freemarkerdownload.html
4.主要代码
上图是我的web程序有关导出word的主要部分,jar放在lib下
这里我用的
struts2
当然servlet springmvc也是可以的
/**
* 将新增的查封出一个审批表
* @throws IOException
*/
public void exportCFw() throws IOException {
Session session = SessionHelper.currentSession();
HttpServletRequest req = ServletActionContext.getRequest();
HttpServletResponse response=ServletActionContext.getResponse();
Map<String, Object> map = new HashMap<String, Object>();
File file = null;
InputStream fin = null;
ServletOutputStream out = null;
try {
cfkId="0000C3C1-DC90-4A3A-A5B3-3104623C64C5";
req.setCharacterEncoding("utf-8");
Query query = session.createQuery("from Cfk c where c.proid='" + cfkId + "'");
Cfk cfk = (Cfk) query.list().get(0);
// 为了通用性将model类存储为map
map = ConvertModel2Map(map, cfk);
// 调用工具类WordGenerator的createDoc方法生成Word文档
file=WordGenerator.createDoc(map, "cfk");
fin=new FileInputStream(file);
response.setCharacterEncoding("utf-8");
response.setContentType("application/msword");
response.setHeader("Content-Disposition", "attachment;filename=cfk.doc");
out=response.getOutputStream();
byte[] buffer=new byte[512];
int byteToRead=-1;
while((byteToRead=fin.read(buffer))!=-1){
out.write(buffer, 0, byteToRead);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(fin != null) fin.close();
if(out != null) out.close();
if(file != null) file.delete(); // 删除临时文件
}
}
private Map<String, Object> ConvertModel2Map(Map<String, Object> map, Object model) {
Field[] fields = model.getClass().getDeclaredFields();// 获取实体类的所有属性,返回Field数组
try {
for (Field field : fields) { // 遍历所有属性
String name = field.getName(); // 获取属性的名字
field.setAccessible(true);// 设置当前对象对model私有属性的访问权限
Object value = field.get(model);// 获取属性值
if(value==null){
value="";
}
map.put(name, value);
}
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return map;
}
package com.fquery.util;
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 freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateNotFoundException;
public class WordGenerator {
private static Configuration configuration=null;
private static Map<String, Template> allTemplates = null;
static{
configuration=new Configuration();
configuration.setDefaultEncoding("utf-8");
configuration.setClassForTemplateLoading(WordGenerator.class, "/com/fquery/ftl");
allTemplates=new HashMap<String, Template>();
try {
allTemplates.put("cfk", configuration.getTemplate("cfk.ftl"));
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
private WordGenerator() {
throw new AssertionError();
}
public static File createDoc(Map<?, ?> dataMap, String type) {
String name = "temp" + (int) (Math.random() * 100000) + ".doc";
File f = new File(name);
Template t = allTemplates.get(type);
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;
}
}
struts2
<action name="exportCFw" class="com.fquery.action.Export" method="exportCFw">
</action>
前端调用action
这里为了测试方便,直接给了查询指定的条件,实际中应该是从前台传过去
function exportCF3(){
location.href="exportCFw.action";
}
本文参考如下文章,特此感谢作者:http://blog.csdn.net/jackfrued/article/details/39449021