版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sunct/article/details/90106429
查阅网上关于JavaScript实现下载文件功能,主要有几种方式:
1. window.open(url) 这是最差劲最不负责任的做法,因为会下载会弹出白页面
2. 构造form表单,form.submit() 这种方式有一个问题:不能加入等待对话框
3. 使用XMLHttpRequest,获取response 实现下载, 但是有一个小问题:后台header中filename不能直接使用
以下针对第三种进行改进:
1. 前端代码
download: function(url, params, fileName) {
var len, i = 0,
temp, input, form, key;
//处理参数
var urlParams = [];
if (isA(params)) {
for (len = params.length; i < len; i++) {
temp = params[i];
urlParams.push(temp.key + "=" + temp.value);
}
} else if (isO(params)) {
for (key in params) {
temp = params[key];
urlParams.push(key + "=" + temp);
}
} else if(isS(params)) {
params = Utilities.parseQuery(params);
for (key in params) {
temp = params[key];
urlParams.push(key + "=" + temp);
}
}
//显示等待
Dialogs.showWait('正在下载中,请稍候...');
var xmlRequest = new XMLHttpRequest();
xmlRequest.open("POST", url, true);
xmlRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlRequest.responseType = "blob";
xmlRequest.onload = function (oEvent) {
if((xmlRequest.status >= 200 && xmlRequest.status < 300) || xmlRequest.status === 304) {
if(!fileName) {
//从header中获取
fileName = decodeURI(xmlRequest.getResponseHeader('filename'));
}
console.log(fileName);
//校验是否下载参数
var content = xmlRequest.response;
if(!fileName || fileName === 'null') {
var myReader = new FileReader();
myReader.addEventListener("loadend", function(e){
var msg = e.srcElement.result;
Dialogs.showWarn(msg);
});
myReader.readAsText(content);
return;
}
//数据转换为文件下载
var elink = document.createElement('a');
elink.download = fileName || 'demo.xlsx';
elink.style.display = 'none';
var blob = new Blob([content]);
elink.href = URL.createObjectURL(blob);
document.body.appendChild(elink);
elink.click();
document.body.removeChild(elink);
//关闭等待
Dialogs.hide();
} else {
Dialogs.showWarn('下载失败');
}
};
try {
//发送参数字符串, 但是formData需要后台支持
xmlRequest.send(urlParams.join('&'));
} catch (e) {
Dialogs.showWarn('发送下载请求失败');
console.error('发送失败',e);
}
},
后台代码:
需要设置response.addHeader("filename", StringUtils.urlEncode(fileName + ".xlsx"));
@RequestMapping(value = "/download.json", method = {RequestMethod.GET, RequestMethod.POST})
@ResponseBody
public String downloadList(
RequestParamRequest requestParamRequest,
HttpServletRequest request,
HttpServletResponse response
) {
其他逻辑省略....
response.setContentType("application/octet-stream");
response.addHeader("Content-disposition", "attachment; filename=" + new String((fileName + ".xlxs").getBytes("utf-8"), "ISO8859-1"));
//在header中设置中文文件名,需要编码,前端需要获取
response.addHeader("filename", StringUtils.urlEncode(fileName + ".xlsx"));
OutputStream out = null;
try {
out = response.getOutputStream();
workbook.write(out);
} finally {
IOUtils.closeQuietly(out);
}
}