前端下载 excel 文件(后端返回文件流)等等...

发布于:2022-10-17 ⋅ 阅读:(468) ⋅ 点赞:(0)

前端下载 excel 文件流

1.业务需求

将后端接口返回的excel文件流进行下载

2.代码实现

  1. 封装将二进制的数据导出为 excel 的方法 @/utils/exportExcel.js
    /**
    * 将二进制的数据导出为 excel
    * @param {string} data 数据
    * @param contentType
    * @param {string} fileName 文件名称
    */
    export function exportResponseData(data, contentType, fileName) {
      	const downloadLink = window.document.createElement('a')
      	downloadLink.href = window.URL.createObjectURL(new Blob([data], { type: contentType }))
      	downloadLink.download = fileName
      	document.body.appendChild(downloadLink)
      	downloadLink.click()
      	document.body.removeChild(downloadLink)
    }
    
  2. 封装导出二进制文件请求 @/utils/request.js
    import axios from 'axios'
    import { getToken, removeToken } from '@/utils/auth'
    import dayjs from 'dayjs'
    import { exportResponseData } from './exportExcel'  // 【主要代码】
    
    let apiHost = require('../setting/api-host').apiHost
    
    // create an axios instance
    const service = axios.create({
      baseURL: apiHost, // api 的 base_url
      timeout: 300000 // request timeout
    })
    
    let loadingInstance
    
    // request 请求 拦截器
    service.interceptors.request.use(config => {
      if (config.responseType === 'blob') {
        config.headers['responseType'] ='blob'
      }
      loadingInstance = Loading.service({
        text: '加载中...',
        background: 'rgba(0, 0, 0, 0.5)',
      })
      config.headers['X-Token'] = getToken() 
      return config
    }, error => {
      // Do something with request error
      // console.log(error) // for debug
      Promise.reject(error)
    })
    
    // respone 响应 拦截器
    service.interceptors.response.use(
      response => {
        /**
         * 判断是否为excel文件【主要代码】
         */
        if (response.config.isExportExcel) {
          const data = response.data
          const contentType = response.headers['content-type']
          let fileName
          if (response.headers['content-disposition']) {
            fileName = decodeURI(
              response.headers['content-disposition'].match(/filename=(.*)/)[1]
            )
          } else {
            fileName = dayjs().format('YYYYMMDD')
          }
          exportResponseData(data, contentType, fileName)
          loadingInstance.close()
          return
        }
        /**
        * code为非20000是抛错 可结合自己业务进行修改
        */
        loadingInstance.close()
        return response.data
      },
      error => {
        loadingInstance.close()
        ...
      }
    )
    
    /**
     * 导出 excel 数据【主要代码】
     */
    export const exportExcel = config => {
      return service({
        method: 'post',
        isExportExcel: true,
        responseType: 'blob',
        ...config
      })
    }
    
    export default service
    
  3. 封装接口请求 @/api/api.js
    import request, { exportExcel } from '@/utils/request'
    // 导出接口
    export function exportList(data) {
      return exportExcel({
        url: '...',
        data
      })
    }
    
  4. 调用接口进行excel文件下载
    import { exportList } from '@/api/api.js'
    methods: {
    	exportHandelr(){
    		let params = { ... }
    		exportList(params).then(res=>{
    			console.log('导出成功')
    		})
    	}
    }
    

3.页面展示

  1. 点击“结果导出”按钮
    在这里插入图片描述

  2. 后端接口返回文件流
    在这里插入图片描述

  3. 弹出另存文件选择路径,进行下载
    在这里插入图片描述

【补充】下载

1.根据接口返回服务器文件路径下载文件

// 下载文件
downloadFile(val) {
  const url = '服务器文件地址前缀' + val.wjlj // 文件路径
  const downloadLink = window.document.createElement('a')
  downloadLink.href = url
  downloadLink.download = val.wjmc
  document.body.appendChild(downloadLink)
  downloadLink.click()
  document.body.removeChild(downloadLink)
},

2.将页面转为图片下载下来

handleDownload() {
  this.downloadLoading = true;
  html2canvas(this.$refs.downLoad).then((canvas) => {
    const imgUrl = canvas.toDataURL('image/png')
    console.log('imgUrl----',imgUrl)
    let image = document.createElement('img')
    image.src = imgUrl
    let a = document.createElement('a')
    a.href = imgUrl
    a.download = this.title
    a.click()
    a = null
    image = null
  }).finally(()=>{
    this.downloadLoading = false;
  });
},

3.下载文件的两种方法

// 操作栏
operationHandleDialog(type, data) {
  if (type === 'editDialog') {
    this.$refs.EditDialogRef.open(type, data)
  } else if (type === 'download') {
    // 【下载文件-方法1】当前页直接下载(不会打开新窗口闪一下,直接下载)
    const downloadLink = window.document.createElement('a') // 创建一个 a 标签
    let suffix = data.mblj.split('.') // 将文件路径通过 . 分隔转为数组
    suffix = suffix[suffix.length - 1] // 取出文件名
// downloadLink.href = `${this.sysConfigData.mon_oss_filepath +
    //   data.mblj}?Download=true&fileName=${data.bmbt}.${suffix}` // 多了一个文件类型(不需要)
    downloadLink.href = `${this.sysConfigData.mon_oss_filepath +
      data.mblj}?Download=true&fileName=${data.bmbt}` // 拼接 a 链接的 href 地址
    document.body.appendChild(downloadLink) // 将 a 标签添加到 body 中
    downloadLink.click() // a 标签触发点击事件
    document.body.removeChild(downloadLink) // 将 a 标签移除

    // 【下载文件-方法2】打开新窗口下载文件(但是不会出现选择文件路径弹框,默认下载到浏览器下载文件位置)(打开新窗口下载文件只是闪一下新窗口,立即又关闭了,不好)
    // window.open(
    //   `${this.sysConfigData.mon_oss_filepath + data.mblj}?Download=true&fileName=${data.bmbt}`
    // )
  }
}

网站公告

今日签到

点亮在社区的每一天
去签到