Vue2.x从后端获取流数据并保存为Excel、CSV或其它格式下载

Vue2.x从后端获取流数据并保存为Excel、CSV或其它格式下载

一、问题

  • 后端返回的是数据流,前端需要将数据导出成为Excel文件进行下载

在这里插入图片描述

二、解决

  • 首先判断请求类型,以post请求为例,需要在二次封装axios中设置responseType值的类型为blob,之后将封装好的请求挂载到Vue实例对象身上,我在man.js中进行的挂载,挂载后的请求方式名称也就是后文的$postExcel

    export async function $_post_excel(url, obj = {}) {
      /* request payload */
      return await axios({
        method: "post",
        url: url,
        responseType: 'blob', // 请求为blob类型
        headers: {
          'session': "",
          "Content-Type": "application/json; charset=UTF-8"
        },
        transformRequest: [
          function (data) {
            return data;
          }
        ],
        data: obj
      }).then(res => {
        return res.data
      })
    }
    
    • 其中responseType的取值范围如下:
      在这里插入图片描述
  • 配置好取值后,请求后端接口,发现此时接收到的值是一个blob对象,blob对象可以看作是存放二进制数据的容器,可以看到后端已经将该文件类型的type进行了配置,限制为excel的形式;

在这里插入图片描述

  • 最后通过创建a标签的形式进行文件的下载即可,代码如下:

    // 导出excel表
    async putoutTeam() {
        const res = await this.$postExcel(`${this.$url}/src/request_url_in_here`)
        let fileName = 'Excel表模板.xlsx' // xlsx和xls都是支持的
        // 通过创建a标签实现文件下载
        let link = document.createElement('a')
        link.download = fileName
        link.style.display = 'none'
        link.href = URL.createObjectURL(res)
        document.body.appendChild(link)
        link.click()
        URL.revokeObjectURL(link.href) // 释放URL 对象
        document.body.removeChild(link)
    }
    
  • 注意:因为文件类型type后端进行了配置,所以前端不需要过多处理,如果没有配置需要进行转换,以上代码基础上进行增加和更改:

    const blob = new Blob([res], { type: 'application/x-excel,charset=UTF-8' }) // 配置blob的type
    const blob = new Blob([接收的blob对象], { type: 'text/csv,charset=UTF-8'}); // 如果是csv文件使用这个配置,上述的文件名fileName也需要修改,加上UTF-8防止中文乱码
    link.href = URL.createObjectURL(blob) // 此处也需要更换为新建的blob实例对象
    

三、扩展(文件名携带在响应头中)

  • 如果文件名由后端规定,并且将文件名携带在响应头中传递过来,前端需要对响应头进行处理后对文件进行命名,修改上述的axios请求如下,也就是将响应的res.data改为resres中包含有响应头的信息:

    export async function $_post_excel(url, obj = {}) {
      /* request payload */
      return await axios({
        method: "post",
        url: url,
        responseType: 'blob', // 请求为blob类型
        headers: {
          'session': "",
          "Content-Type": "application/json"
        },
        transformRequest: [
          function (data) {
            return data;
          }
        ],
        data: obj
      }).then(res => {
        return res
      })
    }
    
  • 之后打印出响应的res信息,所需要的文件名信息包含在res.headerscontent-disposition中,存在filename也就是文件名,这里只需要截取文件名展示即可:

    // 导出excel表
    async putoutTeam() {
        const res = await this.$postExcel(`${this.$url}/src`)
        // 做一层防护,防止没有不存在content-disposition导致报错
        if (res.headers["content-disposition"]) {
            // 截取名字,这里中文会乱码
            let temp = res.headers["content-disposition"].split(";")[1].split("filename=")[1]
            // 解码URI中被转义的字符,解决中文乱码
        	let fileName = decodeURIComponent(temp)
            // 通过创建a标签实现文件下载
            let link = document.createElement('a')
            link.download = fileName
            link.style.display = 'none'
            // 这里改为res.data,流数据存在data中
            link.href = URL.createObjectURL(res.data)
            document.body.appendChild(link)
            link.click()
            URL.revokeObjectURL(link.href) // 释放URL 对象
            document.body.removeChild(link)
        } else{
            return
        }
    }
    

    到这里问题就解决了,有更好的方法欢迎留言评论🌈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值