需求
前端传递一个参数,后台通过该参数查询数据库数据(文件路径),然后找到该文件通过流的形式返回给浏览器,浏览器直接触发下载。
前端参考代码
downloadFile(params, url) {
var form = document.createElement("form");
form.style = "display:none;";
form.action = url;
form.method = "post";
form.target = "form_iframe"
document.body.appendChild(form);
if(!document.getElementById("form_iframe")){
var ifreame = document.createElement("iframe")
ifreame.id = "form_iframe";
ifreame.name = "form_iframe";
ifreame.style ="display:none;"
document.body.appendChild(ifreame);
}
// 动态创建input并给value赋值
for (var key in params) {
var input = document.createElement("input");
input.type = "hidden";
input.name = key;
input.value = params[key];
form.appendChild(input);
}
form.submit();
form.remove();
}
}
后台代码
//前台只传一个参数doctype
@RequestMapping(value="/downloadTemp.do")
public void downloadTemp(HttpServletResponse response, @RequestParam("doctype") String doctype) {
OutputStream out = null;
InputStream in=null;
try {
//获取数据
TempInfoBean temp = doctypeDBService.getTmpInfo(doctype);
// String fileName = "Excel-" + String.valueOf(System.currentTimeMillis()).substring(4, 13) + ".xls";
//文件路径
String fileName = temp.getFileName();
String headStr = "attachment; filename=\"" + fileName + "\"";
// response.setContentType("APPLICATION/vnd.ms_excel;charset=utf-8");
response.setContentType("APPLICATION/force-download;charset=utf-8");
response.setHeader("Content-Disposition", headStr);
in = new FileInputStream(temp.getFilePath());
int len=0;
byte buffer[]=new byte[1024];
out=response.getOutputStream();
while((len=in.read(buffer))!=-1){
out.write(buffer,0,len);
}
} catch (Exception e) {
// e.printStackTrace();
log.error(e.getMessage());
}finally {
if(in!=null){
try {
in.close();
} catch (IOException e) {
// e.printStackTrace();
log.error(e.getMessage());
}
}
}
}
所遇问题
- 原本是使用ajax请求,但是因为ajax的返回值类型是json,text,html,xml类型,不能流类型,返回全是乱码,所以无法实现文件下载,故使用动态生成表单形式
- 因为表单默认数据编码类型为application/x-www-form-urlencoded,所以后台使用@RequestParam注解而不能使用@RequestBody(该注解对应application/json类型)
参考博文 - 因本需求只有一个参数,所以后台接口只接收一个明确参数doctype,如果有多个参数,可在前台把数据转为一个json字符串,然后以一个参数的形式传给接口,后台接收该字符串然后解析json转为Map或者实体对象。
参考博文