当前位置: 首页 > Web前端 > vue.js

vue导出excel表格-后端返回blob流文件,前端接收导出(处理导出后文件损坏问题)

时间:2023-03-31 14:37:46 vue.js

问题描述我们在日常项目中经常需要导出excel文件,尤其是后台管理系统.实现方式有以下三种。1(后端处理)后端直接返回一个excel表格地址,前端点击下载。但是这种方式会导致后端excel存储的越来越多,造成冗余。但是,如果固定模板表的内容不会发生变化,这种方法还是不错的。当然解决办法是在后端写一个定时器,根据情况每隔一段时间清理一次。如果是固定表格,一两年不换的excel表格也可以用这个方法。后端是固定和硬编码的,只将这个固定表传递给前端。这种情况下,后端也可以使用方法2(后端处理)返回一个blob流文件。在这种情况下,它是一次性流文件,不会导致后台excel越存越多。这个方法很好。目前这种方法用的会多一些。方法三(前端处理)前端保存需要导出的表格内容,然后下载使用excel插件轮导出。但是众所周知,前端只是获取数据,展示数据。如果表格内容比较大,或者用户对前端速度有要求,或者主管不希望我们在项目中下载安装太多的轮子,导致最终打包后的文件过大,这个方法不是很好。流文件导出不推荐步骤流文件导出注意事项需要添加responseType:'blob',否则会损坏文件注意excel流文件在请求的时候一定要添加responsetype字段,即:responseType:'blob'或者,responseType:'arraybuffer',否则下载的excel文件会损坏,无法打开。损坏的文件如下图所示:ArrayBuffer和Blob一样,是二进制数据的容器,而ArrayBuffer是下层的,可以通过操作修改这些二进制值,同时两者也可以相互转化的。如何添加responseType:'blob'我是用axios发送请求的,所以在请求的时候需要添加,而且由于axios的二次封装,使用了请求拦截器和对应的拦截器。以及wrapper函数export,(请求拦截器和对应的拦截器就不写了,主要看wrapper函数export)代码是这样写的:exportdefault(method,url,data=null,headers='application/json;charset=UTF-8',responseType=null)=>{if(method=="post"){returnhttp({method:'post',url:rootUrl+url,//url:url,data:data,headers:{'Content-Type':headers,},responseType:responseType//如果有对应的类型,则使用该接口,如果没有,则默认为null});}elseif(method=="get"){returnhttp({method:'get',url:rootUrl+url,//url:url,params:data,headers:{'Content-Type':headers},responseType:responseType//对应的类型,如果有,就用接口里的,如果没有,默认为null});}else{返回;}}这里包裹的返回的http函数接收的参数除了method请求方法,url请求地址,除了数据请求参数和请求头(编码方式为UTF-8)之外,还有一个对应类型的responseType,默认为null,所以写的时候只需要附上最后一个position参数即可界面。查看我们添加的responseType,打印对应拦截器的结果,可以看到http.interceptors.response.use((res)=>{console.log('responseinterceptorview',res);//打印这个结果,可以看到responseTypereturnres.data},(error)=>{returnPromise.reject(error);})没有添加的responseType是null,添加是blob或者ArrayBufferStep1在exported中添加语句interface接收参数的最后一个参数是指定类型为blob或arraybufferexportconstexport=(params)=>http("get",`api/export`,params,'application/json;charset=UTF-8','arraybuffer')Step2假设我们点击导出excel表格的按钮//asyncoutExcelData(){//在导出按钮的回调函数中准备参数letparams=xxxconstres=awaitthis.$api.export(参数);constblob=newBlob([res]);//将得到的结果转为流对象vara=document.createElement("a");//创建一个标签a.href=URL.createObjectURL(blob);//将流文件写入a标签的href属性值a.download="Basicprocessdata.xlsx";//设置文件名a.style.display="none";//隐藏标签文档。body.appendChild(a);//将a标签附加到文档对象a.click();//模拟点击a标签,会触发读取a标签的href,浏览器会自动下载a。消除();//一次性,用完就把a标签删掉},总结注意,一定要声明流文件,用流文件转换结果,这样excel文件才不会损坏乱码