点击导出按钮,提交请求,下载excel大文件(超过500M),该文件没有预生成在后端,
直接以文件流的形式返回给前端。前端
在Vue项目中经常使用的方式是经过axios配置请求,读取后端返回的文件流,经常使用代码以下:ios
axios({ method: 'post', url: 'api/file', responseType: 'blob' }).then(res=> { if (res.data){ filename = 'filename'; let blob = new Blob([res.data],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"}); if (window.navigator.msSaveOrOpenBlob){ // IE10+下载 navigator.msSaveOrBlob(blob, filename); }else{ // 非IE10+下载 let link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = filename; document.body.appendChild(link); var evt = document.createEvent("MouseEvents"); evt.initEvent("click", false, false); link.dispatchEvent(evt);//释放URL 对象 document.body.removeChild(link); } }).catch((error) => { console.log(error) })
这种方式是把文件流读取到浏览器内存中,再下载,可是今天在这种大文件场景下它不香了,
因为内存过大,直接把网页给搞崩了,喔豁😂git
怎么办呢,终于在Github上找到了一个大神的库,用起来真香,Github地址github
根据介绍,在chrome浏览器2G如下的文件下载能够获得很好的支持chrome
npm install file-saver --save
npm
+ import { saveAs } from 'file-saver'; ... + saveAs(blob, fileName );
+ import { saveAs } from 'file-saver'; axios({ method: 'post', url: 'api/file', responseType: 'blob' }).then(res=> { if (res.data){ fileName = this.fileName; // 有文件名就用自定义的,没有就从header获取 if (!fileName) { fileName = fileNameFromHeader( res.headers["content-disposition"] || "" ); } let blob = new Blob([res.data],{ type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"}); + saveAs(blob, fileName ); } }).catch((error) => { console.log(error) }) function fileNameFromHeader(disposition) { let result = null; disposition = disposition.split(";")[1]; if (disposition && /filename=.*/gi.test(disposition)) { result = disposition.match(/filename=.*/gi); return decodeURIComponent((result[0].split("=")[1]).replace(/\+/g, '%20')); } return "null"; }
下载大文件过程当中遇到的其余问题axios