首先说一下做这个功能出现的问题:
1:一开始我将需要下载的内容写到jsp里面,然后在jsp 顶部加入
<%@ page contentType= "application/vnd.ms-word; charset=utf-8" %>
这种方法可以将jsp 生成word 并提示下载,但是样式,图片都下载不了;
2:选择用模版实现(velocity)
出现的问题:
1: 直接使用模版生成word并使用流输出下载,会出下word打开空白但大小不为0 ,并提示文件已损坏,
解决办法: 使用一个临时文件,将流写入,再下载该文件;
2: 找不到velocity 模版的路径(web)
解决办法: String vmTemPath=request.getSession().getServletContext().getRealPath("/")+ "/velocity/; //前面一截是webapp路径
ps.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH,vmTemPath);
如果是java 项目:
ps.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, "./src/"); //直接放在src下可以了
3: 完整实现步骤(已测试成功下载)
代码:
//前端调用的方法
public String toDownload() { createDoc(); String vmTemPath = request.getSession().getServletContext().getRealPath("/")+ "/velocity/"; String temp = vmTemPath + "temp.doc"; File srcFile = new File(temp); try { wordStream = new FileInputStream(srcFile); } catch (FileNotFoundException e) { e.printStackTrace(); } return "worlReport"; } private void createDoc() { VelocityContext velocityContext = new VelocityContext();
Properties ps = new Properties();velocityContext.put("certificateSum", 9090); //需要替换到模版中的数据
String vmTemPath = request.getSession().getServletContext().getRealPath("/")+ "/velocity/";
ps.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, vmTemPath);
String temp = vmTemPath + "temp.doc";
VelocityEngine ve = new VelocityEngine();
Template template = null;
try {
ve.init(ps);
template = ve.getTemplate("simple.vm", "utf-8");
File srcFile = new File(temp);
FileOutputStream fos = new FileOutputStream(srcFile);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"));
template.merge(velocityContext, writer);
writer.flush();
writer.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
struts2 配置文件:
<result name="worlReport" type="stream">
<param name="contentType">application/vnd.ms-word</param>
<param name="contentDisposition">attachment;filename="${fileName}"</param> // fileName 下载的文件名
<param name="bufferSize">2048</param>
<param name="inputName">wordStream</param> // wordStream Action中的属性名
</result>