在项目当中会经常遇到一些导出文件的需求,对于普通导出的话直接用a标签即可,但是有些导出a标签是满足不了的。也就是a标签是有局限性的。
一、以a标签导出的形式,添加download属性
<a href="文件下载地址" downloa="downloa">下载</a>
以a标签的形式导出局限性:
1、利用a标签导出需要服务器提前将文件生成好,通过href导出;
2、利用a标签导出如果文件较大、导出时间长无法加loading;
3、利用a标签导出download在chrome、firefox、safari中有兼容性(download=“download”在safari会改变文件名称);
由于a标签的局限性所以建议用第二种方式导出
二、通过axios发送请求的形式导出
1、html 部分(此处引入了element ui)
<el-button type="primary" icon="el-icon-share" size="mini" @click="export">导出</el-button>
2、js 部分
import { Loading } from "element-ui"; import axios from ‘axios‘; export() { const that = this; const loading = Loading.service({ lock: true, text: ‘拼命下载中...‘, spinner: ‘el-icon-loading‘, background: ‘rgba(0, 0, 0, 0.7)‘ }) axios({ method: ‘get‘, url: `自己服务器导出地址`, // 此处一定要为blob对象,将文件流转为blob, // 前端对于文件流无法操作 responseType: ‘blob‘, baseURL: ‘服务器ip或域名‘, }).then((res) => { let blob = new Blob([res.data]); let fileName = "自定义文件名称"; if(blob.size>0){ const elink = document.createElement(‘a‘); elink.style.display = ‘none‘; elink.href = URL.createObjectURL(blob); // 类似a标签下载 // 自定义文件名称和导出类型。最好和后台保持一致 elink.download = `${fileName}.xlsx`; document.body.appendChild(elink); elink.click(); // 释放URL 对象 URL.revokeObjectURL(elink.href); // 删除创建的 a 标签 document.body.removeChild(elink); } that.$nextTick(() => { loading.close()}); }).catch(function(error){ that.$nextTick(() => { loading.close()}); }) }
利用axios导出其实本质还是a标签导出,但是有几个地方一定要注意:
1、responseType一定要为blob对象
2、对于a标签的href也就是说URL.createObjectURL()一定要是blob对象,这样返回的url才相当于blob生成的临时url。
对于第二条补充两点:
1、URL.createObjectURL()
静态方法会创建一个 DOMString
,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document
绑定。这个新的URL 对象表示指定的 File
对象或 Blob
对象。
2、此处a标签的href切记不能写成服务器的地址,即 elink.href="服务器地址"(错误写法),如果这样写了那么用axios不但毫无意义,还对服务器请求了两次
3、对于用到了element ui 的 loading来说(上边的写法)以服务的形式调用, 需要异步关闭 即 this.$nextTick(() => {loading.close()})。官方说法