1. 程式人生 > 程式設計 >vue中後端做Excel匯出功能返回資料流前端的處理操作

vue中後端做Excel匯出功能返回資料流前端的處理操作

專案中有一個匯出功能的實現,用部落格來記錄一下。因為需求對匯出表格的資料格式和樣式有要求,所以這個匯出功能放到後端來做,而且後端返回的是資料流,所以需要處理成想要的表格並匯出來。

先看下效果圖:

頁面效果:

vue中後端做Excel匯出功能返回資料流前端的處理操作

點選 匯出Excel 呼叫匯出介面成功了:

vue中後端做Excel匯出功能返回資料流前端的處理操作

後臺返回的資料流,一堆看不懂的亂碼:

vue中後端做Excel匯出功能返回資料流前端的處理操作

接下來要處理這堆亂碼,因為用到的地方多,所以在util.js檔案裡封裝了一個公共方法並丟擲:

雖然vue裡有封裝好的請求介面的方法,但這裡要單獨用axios,所以先在util.js裡引入axios

import axios from 'axios'

// 匯出Excel公用方法
export function exportMethod(data) {
  axios({
    method: data.method,url: `${data.url}${data.params ? '?' + data.params : ''}`,responseType: 'blob'
  }).then((res) => {
    const link = document.createElement('a')
    let blob = new Blob([res.data],{type: 'application/vnd.ms-excel'})
    link.style.display = 'none'
    link.href = URL.createObjectURL(blob)
 
    // link.download = res.headers['content-disposition'] //下載後文件名
    link.download = data.fileName //下載的檔名
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  }).catch(error => {
    this.$Notice.error({
      title: '錯誤',desc: '網路連線錯誤'
    })
    console.log(error)
  })
}

在使用的頁面中引入方法:

import { exportMethod } from '@/libs/util'

在methods匯出的方法裡,呼叫共用匯出方法。

注意:因為我們後臺用的是get方法,所以傳遞get請求並且拼接要傳的引數,如果是post請求,就把傳遞的get改成post,傳遞資料改成傳data資料物件,params去掉,公共方法裡把url上拼接的引數也去掉,直接 接收url路徑即可,再接收一個data就行了

// 匯出會診接診量統計表
    exportDepReceRank() {
      let myObj = {
        method: 'get',url: exportDepartmentRankUrl,fileName: 'XX醫院—各科室會診接診量統計',params: `startDate=${changeDate(this.dateValue[0])}&endDate=${changeDate(this.dateValue[1])}`
      }
      exportMethod(myObj)
    },

最後成功匯出Excel的效果圖:

vue中後端做Excel匯出功能返回資料流前端的處理操作

補充知識:Vue專案利用axios請求介面下載excel(附前後端程式碼)

據我瞭解的前端的下載方式有三種,第一種是通過a標籤來進行下載,第二種時候通過window.location來下載,第三種是通過請求後臺的介面來下載,今天就來記錄一下這三種下載方式。

方法一:通過a標籤

// href為檔案的儲存路徑或者地址,download為問檔名

<a href="/images/logo.jpg" rel="external nofollow" download="logo" />

優點:簡單方便。

缺點:這種下載方式只支援Firefox和Chrome不支援IE和Safari,相容性不夠好。

方法二:通過window.location

window.location = 'http://127.0.0.1:8080/api/download?name=xxx&type=xxx'

優點:簡單方便。

缺點:只能進行get請求,當有token校驗的時候不方便。

方法三:通過請求後臺介面

// download.js
import axios from 'axios'

export function download(type,name) {
 axios({
  method: 'post',url: 'http://127.0.0.1:8080/api/download',// headers裡面設定token
  headers: {
   loginCode: 'xxx',authorization: 'xxx'
  },data: {
   name: name,type: type
  },// 二進位制流檔案,一定要設定成blob,預設是json
  responseType: 'blob'
 }).then(res => {
  const link = document.createElement('a')
  const blob = new Blob([res.data],{ type: 'application/vnd.ms-excel' })
  link.style.display = 'none'
  link.href = URL.createObjectURL(blob)
  link.setAttribute('download',`${name}.xlsx`)
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
 })
}
// download.java
@RequestMapping(value = "/api/download",produces = "application/octet-stream",method = RequestMethod.POST)
public void downloadTemplate(@RequestBody Map<String,Object> paramsMap,HttpServletResponse response) {
  try {
    if (paramsMap.get("type").equals("xxx") && paramsMap.get("name").equals("xxx")) {
      String[] str = new String[]{"區縣","所屬省份","所屬地市"};
      Workbook workbook = ExportExcel.exportExcel("行政區劃表模版",str,null,"yyyy-MM-dd");
      download(response,workbook,"CityDict");
    }
  } catch (Exception e) {
    e.printStackTrace();
  }
}

private void download(HttpServletResponse response,Workbook workbook,String fileName) {
  try {
    response.setContentType("application/octet-stream;charset=UTF-8;");
    response.addHeader("Content-Disposition","attachment;fileName=" + fileName + ".xlsx");
    ByteArrayOutputStream by = new ByteArrayOutputStream();
    OutputStream osOut = response.getOutputStream();
    // 將指定的位元組寫入此輸出流
    workbook.write(osOut);
    // 重新整理此輸出流並強制將所有緩衝的輸出位元組被寫出
    osOut.flush();
    // 關閉流
    osOut.close();
  } catch (IOException e) {
    LogUtils.getExceptionLogger().info("下載模板錯誤:{}",e.getMessage());
  }
}

優點:可以在headers裡面設定token,檔案是java程式碼中生成的,生成的檔案比較靈活。

缺點:實現起來比較複雜。

以上這篇vue中後端做Excel匯出功能返回資料流前端的處理操作就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。