/**
* 下载服务器上文件的方法
* @param {String} stream 数据流
* @param {String} name 文件名称
* @param {String} suffix 文件后缀名
*/
export function fileDownload(stream, name, suffix = '.xls') {
if (stream && name) {
const blob = new Blob([stream])
const fullName = `${name + suffix}`
// IE10+ 浏览器特殊处理
if (window.navigator.msSaveBlob) {
window.navigator.msSaveBlob(blob, fullName)
} else {
const href = window.URL.createObjectURL(blob)
let a = document.createElement('a')
a.href = href
a.download = fullName
document.body.appendChild(a)
a.click()
window.URL.revokeObjectURL(href)
document.body.removeChild(a)
}
}
}
后续
- 兼容
IE
浏览器无法正常下载的问题
经过反复的实验,发现上面的函数在后端设置数据流格式为
msexcel
就是可以正常使用的,但是如果后缀格式为vnd.ms-excel
的话,在IE
浏览器就无法正常下载。下面两张是IE
浏览器控制台的截图,图一是可以正常下载的,但是图二就是不可以的。
image.png
image.png
- 解决方法
针对于上述这样怪异的问题,最开始我是建议后端修改文件格式的,也就是下图这样。
image.png
- 后来又考虑到改动量其实还是不小的,而且前端获取数据流的方式也需要修改,之前也就是上面函数的调用是
fileDownload(res.data, reportName)
,如果后端修改的话,前端需要改成fileDownload(res, reportName)
,所以觉得还是需要找到更优解才行,于是就有了下面的终极解决方案。(经过反复测试,如下所写是可以完美解决兼容问题的,只是需要在获取数据流时增加一个三元运算)
const { data } = res
// IE 浏览器需要的是 res,非 IE 需要的是 data
fileDownload(data ? data : res, reportName)