目前使用

handleExport () {
      this.exportName = `通讯录`
      let params = tools.deepClone(this.searchParams)
      params.search.size = this.total
      接口请求地址(params).then(res => {
        const href = window.URL.createObjectURL(new Blob([res]))
        const link = document.createElement('a')
        link.style.display = 'none'
        link.href = href
        link.setAttribute('download', this.exportName + '.xls')
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link) // 下载完成移除元素
        window.URL.revokeObjectURL(href) // 释放掉blob对象
      }).catch(err => {
        this.$message.error(err)
      })
    },

需求说明

通过vue实现导出有两种方式:
(1)后端返回的是一个地址,直接拼接打开下载就行
(2)后端返回的是文件流的形式,这个时候就需要在请求头还有返回值的地方设置一下

一、后端返回的是地址

// 页面代码
<el-button
       type="primary"
       size="mini"
       class="filter-item"
       icon="el-icon-download"
       style="margin: 12px 20px 0 0; float: right"
       @click="onExportClick"
       >
       导出
</el-button>

 onExportClick() {//导出方法
     exportDevices(this.listQuery) //导出接口
      .then(result => {
         const url = result.data
         window.open(url)    //通过这个打开网页就可下载导出
      })
       .catch(err => console.log(err))
}

二、后端返回的是文件流

(1)设置请求头

/**
* 按照部门人员导出(包括事件类型)
* @param {*} pType
* @returns
*/
export function exportDetailOrder(pType) {
  return request({
      url: '/exportEventDetailByDepart',
      method: 'get',
      responseType: 'blob',  //需要在此处设置请求头,设置请求的类型为blob文件流的形式
      params: {
          pType
      }
  })
}

(2)设置返回结果,处理返回我文件流

onExportClick() {  //导出的方法
            exportDetailOrder(this.pType)  //导出的接口
                .then(result => {
                    console.log(result)
                    const link = document.createElement('a')  //创建a标签
                    const blob = new Blob([result], { type: 'application/vnd.ms-excel' }) //设置文件流
                    link.style.display = 'none'
                    // 设置连接
                    link.href = URL.createObjectURL(blob)  //将文件流转化为blob地址
                    link.download = '处理人员维修工单统计报表'
                    document.body.appendChild(link)
                    // 模拟点击事件
                    link.click()  //设置点击事件
                })
                .catch(err => {
                    console.log(err)
                })
        }

(3)附加说明
有的时候做到上述几步还是不能导出,debugger之后,发现接口调用的时候直接走的.catch,没走.then,
所以需要我们在全局响应拦截做一些判断。

//一般在utils下面的requext.js文件里面
export function validResponse(res, errorMessage) {
    if (res instanceof Blob) {  //如果返回的是文件流的形式,直接return res
        return res
    } else if (res.code !== 200 && res.code !== 201 && res.code !== 204) {
        return Promise.reject(new Error(res.message || '发生错误!'))
    } else {
        return res
    }
}

目前用的:

handleExport() {
              let me = this
              let url = '/fcst/gpcprevention/exportGpcSummary'
              let filename = me.reportname
              let exportparams = {
                taskyear: utils.formatDate(me.searchParams.taskyear, 'yyyy'),
                reportid: me.searchParams.reportid,
                  char1:me.searchParams.char1,
              }
              utils.onDownload(me, url, filename, exportparams);
            }

utils.onDownload方法:

utils.onDownload = function (vm,url,filename,searchParams) {
    let params = utils.addFormData(searchParams);
    vm.$axios(
        {
            method: 'post',
            url: url,
            data: params,
            responseType: 'blob'
        }
    ).then(function(res) {
        let href = window.URL.createObjectURL(new Blob([res]));
        let link = document.createElement('a');
        link.style.display = 'none';
        link.href = href;
        link.setAttribute('download', filename + '.xls');
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link); // 下载完成移除元素
        window.URL.revokeObjectURL(href); // 释放掉blob对象
    });
};

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐