vue 后台接口返回文件流 前端实现文件下载

179 阅读1分钟

html文件 绑定点击事件

<el-tag @click="downloadCsv">
        <i class="el-icon-download" />
        <span>点击下载模版</span>
</el-tag>

VUE > methods里定义方法

  // 下载模版
 downloadCsv() {
      this.$axios.get('/api/company', { responseType: 'blob' }).then(data => {
        // data.data 就是返回的 Blob类型的数据,如下图
        const url = URL.createObjectURL(data.data)
        const link = document.createElement('a')
        document.body.appendChild(link)
        link.download = '公司ID表' + '.csv'
        link.href = url
        link.click()
        URL.revokeObjectURL(url)
        document.body.removeChild(link)
      }).catch((error) => {
        this.$message({ message: error.message, type: 'error' })
      })
   }

代码优化及多内核浏览器适配

downLoadCsv(data, filename) {
      if (typeof window.chrome !== 'undefined') {
        // Chrome version
        this.$message.success("下载成功!")
        console.log("chrome");
        var link = document.createElement('a');
        link.href = URL.createObjectURL(data.data);
        link.download = filename+'.csv';
        link.click();
        URL.revokeObjectURL(link.href)
      } else if (typeof window.navigator.msSaveBlob !== 'undefined') {
        // IE version
        var blob = new Blob([data], { type: 'application/force-download' });
        window.navigator.msSaveBlob(blob, filename+'.csv');
      } else {
        // Firefox version
        var file = new File([data], filename+'.csv', { type: 'application/force-download' });
        window.open(URL.createObjectURL(file));
      }
    }

知识重点总结

后端返回文件流,前端需要对返回的文件流处理进行文件下载 axios 发送文件类型请求时,声明返回blob格式 { responseType: 'blob' }
URL.createObjectURL(data) data参数可以是 File 对象、Blob 对象或者 MediaSource 对象 此方法是把data的内容转换成url 绑定到a标签上, 然后调用click() 来模拟点击调用, 最初创建的DOM a元素只是为了使用下载,所有使用完,用removeChild 将DOM接点删除,后面做了优化 URL.revokeObjectURL(url) 作用是释放一个之前已经存在的、通过调用 URL.createObjectURL() 创建的 URL 对象 link.download 为下载文件知道文件名, 如果不指定后缀,默认是xlsx 指定后缀如: .csv 或者 .rar 等等 PS:指定后缀记得一定要加点 !!! 要不然会当成文件名,不会变更文件类型 只创建元素,不把元素加到body里面.这样就不用删除,也算是代码量优化, 理论上应该不会有什么影响. 如果有疑问 欢迎留言指正批评!