好久没有关注掘金了,因为这段时间特别忙,明天中秋了,提前祝大家中秋快乐!!!
这次是下载EXCEL文件的总结,有什么问题大家可以提出建议,我认为这样会使我们互相成长。
解决历程(一)
我在开发中偶遇到的下载EXCEL文件,我马上想到的就是用链接去下载,
例: <a href="https://www.juejin.com/测试.xls" download="测试.xls">EXCEL</a>
但是这样会有很大的缺陷,就是可能会有人攻击的服务器,因为没有建权,所以可以一直下载你的文件。
解决历程(二)
然后我又去改进,但是和这个大同小异,用JS去下载。
例:
function handleDownloadExcel () {
let a = document.createElement('a')
a.href = "https://www.juejin.com/测试.xls"
a.download = "测试.xls"
a.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}))
}
这段代码是为了兼容火狐
a.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}))
解决历程(三)
上边这种方法还不是最好的,因为我们的后台非要给我base64的,只能服从喽,因为我睡(说)不服他们
例:
function handleDownloadExcel () {
let base64 = 'data:application/vnd.ms-excel;base64,'
let a = document.createElement('a')
a.href = base64 + respone.data
a.download = "测试.xls"
a.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}))
}
但是这样下载下来是错误的,没有内容,所以我认为base64的excel无法下载,谁有什么好的下载base64的excel文件的方法可以评论一下,互相学习。
解决历程(四)
我在网上查找资料,试了好多种方法,最好我看到最好的就是让后台给你二进制数据Blob格式。 直接上代码
handleDownloadExcel () {
downloadExcel({
data: data
})
.then(res => {
this.isShowBtnLoading = false
this.isBtnDisabled = false
let blob = new Blob([res])
let a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = `测试.xls`
a.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}))
})
.catch(err => {
console.log(err)
})
}
我使用的是VUE框架 ,理所应当使用的插件是axios
请求的方法给大家一个示例, 为什么给大家这个示例呢?因为responseType: 'blob',这个必须要有,还有就是我还犯了一次错误,由下方代码可以见,我封装了这个axios,所以我一定会做返回拦截,后台给的这个二进制文件无法放在data中,只能用response直接返回,所以我在上边代码中没有做 if(code === 200){······},如果你也像我这样做的话记得在你的返回拦截中去过滤掉这个接口的返回, 比如这样
if (response.data.type === 'application/vnd.ms-excel') { return response.data }, 然后就可以直接下载了。
export let downloadExcel = function (data) {
return request({
method: 'get',
url: URL.DOWNLOAD_EXCEL,
responseType: 'blob',
params: data
})
}
后续 2019.11.28
由于以上的解决方案拿不到后台返回的code,然后我的后台还不想给我传二进制,还是要给我传base64,所以又开始优化,绞尽脑汁的想,其实很简单,把base64转为二进制文件流再下载。直接上代码
function parseExcel (b64Data, filename) {
var sliceSize = 512
var byteCharacters = window.atob(b64Data) // 解码base64
var byteArrays = []
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize)
var byteNumbers = new Array(slice.length)
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i)
}
var byteArray = new Uint8Array(byteNumbers)
byteArrays.push(byteArray)
}
let file = new File(byteArrays, filename, {type: 'application/vnd.ms-excel;charset=utf-8'})
let blob = new Blob([file])
let a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = `${filename}.xls`
a.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}))
}
export default parseExcel
总结
- 一定要加上
response:'blob' - 创建
new Blob([res]) - 用
URL.createObjectURL(blob)去创建地址 - 请关注本人博客Max