前端导出excel代码总结

774 阅读2分钟

前言

在项目开发中会经常出现导出文件的需求,这里总结下代码函数以及遇到的问题。

代码展示

主要是接收后端返回的文件流,转换成blob对象(需要设置responseType: 'blob'),前端渲染a标签添加点击下载事件。

await new Promise((resolve, reject) => {
  axios({
    method: 'post',
    url: 'url',//url自己填写
    data,
    options: {
      responseType: 'blob'//responseType设为blob的话,返回的文件流将会被转成blob对象。很多导出失败的可以关注下这里
    }
  }).then(res => {
    if (res.data) {
      const blob = new Blob([res.data], {
        type: 'application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      })//设置type类型,这里是excel
      const downloadElement = document.createElement('a')
      const href = window.URL.createObjectURL(blob)
      downloadElement.style.display = 'none'
      downloadElement.href = href
      downloadElement.download = decodeURI('' + this.reportName) // 下载后文件名
      document.body.appendChild(downloadElement)
      downloadElement.click() // 点击下载
      document.body.removeChild(downloadElement) // 下载完成移除元素
      window.URL.revokeObjectURL(href) // 释放掉blob对象
    } else {
      resolve(res.data.status)
    }
  })
})

以上即可适用大多数文件下载(这里以excel文件为例),但是实际场景中,客户反馈了有时候会出现没有文件后缀名的情况。
QQ图片20220328111533.png
我进入客户账号,一开始以为是文件太大(正好这个文件比其他的大很多),查询资料无果后,发现这个文件名带了个小数点,猜想可能因为小数点导致的,测试后果然如此,但是没有找到更好的办法,我选择遇到小数点时手动加上xlsx文件后缀。如下:

await new Promise((resolve, reject) => {
  axios({
    method: 'post',
    url: 'url',//url自己填写
    data,
    options: {
      responseType: 'blob'//responseType设为blob的话,返回的文件流将会被转成blob对象。很多导出失败的可以关注下这里
    }
  }).then(res => {
    if (res.data) {
      const blob = new Blob([res.data], {
        type: 'application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      })//设置type类型,这里是excel
      const downloadElement = document.createElement('a')
      const href = window.URL.createObjectURL(blob)
      downloadElement.style.display = 'none'
      downloadElement.href = href
      let reportName = this.reportName//文件名看情况处理,我这里是前端有存,一般后端会返回
      if (this.reportName.indexOf('.') !== -1) {
        //处理文件名带有小数点的,文件名会被截断,手动加上后缀
        reportName += '.xlsx'
      }
      downloadElement.download = decodeURI('' + reportName) // 下载后文件名
      document.body.appendChild(downloadElement)
      downloadElement.click() // 点击下载
      document.body.removeChild(downloadElement) // 下载完成移除元素
      window.URL.revokeObjectURL(href) // 释放掉blob对象
    } else {
      resolve(res.data.status)
    }
  })
})

如有更合理的方式,请留言谢谢