vue+axios封装已文件流的形式导出文件

在项目当中会经常遇到一些导出文件的需求,对于普通导出的话直接用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()})。官方说法

原文地址:https://www.cnblogs.com/little-baby/p/14296851.html