亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

公共Hooks封裝報表導出useExportExcel實現詳解

 更新時間:2022年12月01日 14:55:27   作者:JasonSubmara  
這篇文章主要為大家介紹了公共Hooks封裝報表導出useExportExcel實現詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

寫在前面

對于經常需要開發(fā)企業(yè)管理后臺的前端開發(fā)來說,必不可少的需要使用表格對于數據進行操作,在對于現有項目進行代碼優(yōu)化時,封裝一些公共的Hooks.

本篇文章為useExportExcel.js

基于個人項目環(huán)境進行封裝的Hooks,僅以本文介紹封裝Hooks思想心得,故相關代碼可能不適用他人

項目環(huán)境

Vue3.x + Ant Design Vue3.x + Vite3.x

對于企業(yè)管理后臺最大的作用來說,用以管理企業(yè)內各種數據狀況,同時,基于實際業(yè)務過程中,客戶每逢年終(中)時都有大型匯報的需求,因此,數據報表形式的文檔產出必不可少,本文則基于該常見需求場景進行封裝的Hooks -- 導出數據報表

封裝思考:報表數據來源

  • 后端接口返回數據

后端返回二進制Blob文件,前端利用Blob進行下載,即參考系列文章公共Hooks封裝之文件下載useDownloadFile的方式。

  • 前端導出界面數據

前端導出界面數據的方式在企業(yè)管理后臺中占比相對較少,一般用以數據量較少的特殊情況,以自己項目舉例則是 用戶在導入Excel時部分數據失敗后,展示的失敗數據報表及失敗原因統(tǒng)計的表格,使用前端導出數據的方式進行導出。

封裝分解:前端生成報表

接收options配置對象,包括data(源數據)、key(用來生成表格的行數據唯一標識)、title(表格標題)、fileName(導出文件名稱)

// 通過數組數據前端導出excel
const exportByArray = options => {
  if (!options.data || !options.key || !options.title || !options.fileName)
  return new Error('缺少必需參數');
  const arr = options.data.map(v =>
    options.key.map(j => {
      return v[j];
    }),
  );
  arr.unshift(options.title);
  const ws = utils.aoa_to_sheet(arr);
  const colWidth = arr.map(row =>
    row.map(val => {
      if (val == null) {
        return { wch: 10 };
      } else if (val.toString().charCodeAt(0) > 255) {
        return { wch: val.toString().length * 2 };
      } else {
        return { wch: val.toString().length };
      }
    }),
  );
  const result = colWidth[0];
  for (let i = 1; i < colWidth.length; i++) {
    for (let j = 0; j < colWidth[i].length; j++) {
      if (result[j]['wch'] < colWidth[i][j]['wch']) {
        result[j]['wch'] = colWidth[i][j]['wch'];
      }
    }
  }
  ws['!cols'] = result;
  const wb = utils.book_new();
  utils.book_append_sheet(wb, ws, options.fileName);
  writeFile(wb, options.fileName + '.xlsx');
};

前端生成報表方法Sheet.js

前端生成報表方法中用到的utils.aoa_to_sheet,utils.book_newutils.book_append_sheet,writeFile,都來源于 SheetJS。

Step1: 項目安裝依賴yarn add xlsx

Step2: 在Hooks文件中引入 import { utils, writeFile } from 'xlsx'

Step3: 參考官方API,完善Hooks中前端導出方法 SheetJS - Utility Functions

  • utils.aoa_to_sheet

將一個二維數組轉成sheet,會自動處理number、string、boolean、boolean、date 等類型數據

  • utils.table_to_sheet

將一個table的dom直接轉成sheet,會自動識別colspan和rowspan并將其轉成對應的單元格合并

  • utils.json_to_sheet

將一個由對象key-value組成的數組轉成sheet,可以設置header

這三種方法都是SheetJS的導出方法,存在差異,考慮實際數據,最后選擇的是utils.aoa_to_sheet,其余方法可以在官方文檔中找到對應的示例

以上是一個完整的導出報表流程
utils.book_new => 創(chuàng)建一個工作簿 utils.aoa_to_sheet => 源數據轉成工作表 utils.book_append_sheet => 將工作表插入到工作簿中 writeFile => 調用下載

封裝分解:后端接口返回數據導出優(yōu)化

因為需要請求后端接口導出,即下載返回的二進制文件,依舊考慮用戶體驗設計,增加二次確認彈窗,并從store里拿接口必須的token

// 打開導出文件確認彈窗
const exportByResBlob = options => {
  Modal.confirm({
    title: options.title ? options.title : '導出確認',
    content: options.content ? options.content : '確認導出報表嗎?',
    onOk() {
      downloadFile(options);
      return Promise.resolve();
    },
  });
};

useExportExcel.js完整代碼

import { onBeforeUnmount } from 'vue';
import { utils, writeFile } from 'xlsx';
import { stringify } from 'qs';
import { Modal } from 'ant-design-vue';
import { useUserStore } from '@/store/userStore';
export function useExportExcel() {
  const userStore = useUserStore();
  let xhr = null;
  let downloading = false; // 限制同一文件同時觸發(fā)多次下載
  onBeforeUnmount(() => {
    xhr && xhr.abort();
  });
  // 打開導出文件確認彈窗
  const exportByResBlob = options => {
    Modal.confirm({
      title: options.title ? options.title : '導出確認',
      content: options.content ? options.content : '確認導出報表嗎?',
      onOk() {
        downloadFile(options);
        return Promise.resolve();
      },
    });
  };
  // 通過請求后端接口文件流導出excel
  const downloadFile = options => {
    try {
      if (downloading || !options.url || !options.fileName)
      return new Error('缺少必需參數');
      downloading = true;
      const paramsStr = stringify(options.params || {});
      xhr = new XMLHttpRequest();
      xhr.responseType = 'blob';
      if (paramsStr) {
        xhr.open('get', `${options.url}?${paramsStr}`, true);
      } else {
        xhr.open('get', options.url, true);
      }
      xhr.setRequestHeader('token', userStore.userToken);
      xhr.onloadend = function (e) {
        if (e.target.status === 200) {
          const aElement = document.createElement('a');
          const blob = e.target.response;
          const url = window.URL.createObjectURL(blob);
          aElement.style.display = 'none';
          aElement.href = url;
          aElement.download = `${options.fileName}.xlsx`;
          document.body.appendChild(aElement);
          aElement.click();
          if (window.URL) {
            window.URL.revokeObjectURL(blob);
          } else {
            window.webkitURL.revokeObjectURL(blob);
          }
          document.body.removeChild(aElement);
          downloading = false;
        }
      };
      xhr.send();
    } catch (e) {
      console.error(e);
      downloading = false;
      Modal.error({
        title: '提示',
        content: '導出發(fā)生異常,請重試',
      });
    }
  };
  // 通過數組數據前端導出excel
  const exportByArray = options => {
    if (!options.data || !options.key || !options.title || !options.fileName) return new Error('缺少必需參數');
      const arr = options.data.map(v =>
        options.key.map(j => {
          return v[j];
        }),
      );
      arr.unshift(options.title);
      const ws = utils.aoa_to_sheet(arr);
      const colWidth = arr.map(row =>
      row.map(val => {
        if (val == null) {
          return { wch: 10 };
        } else if (val.toString().charCodeAt(0) > 255) {
          return { wch: val.toString().length * 2 };
        } else {
          return { wch: val.toString().length };
        }
      }),
    );
    const result = colWidth[0];
    for (let i = 1; i < colWidth.length; i++) {
      for (let j = 0; j < colWidth[i].length; j++) {
        if (result[j]['wch'] < colWidth[i][j]['wch']) {
          result[j]['wch'] = colWidth[i][j]['wch'];
        }
      }
    }
    ws['!cols'] = result;
    const wb = utils.book_new();
    utils.book_append_sheet(wb, ws, options.fileName);
    writeFile(wb, options.fileName + '.xlsx');
  };
  return {
    exportByResBlob,
    exportByArray,
  };
}

以上就是公共Hooks封裝報表導出useExportExcel實現詳解的詳細內容,更多關于Hooks封裝useExportExcel的資料請關注腳本之家其它相關文章!

相關文章

  • vue下跨域設置的相關介紹

    vue下跨域設置的相關介紹

    本篇文章主要介紹了vue下跨域設置的相關介紹,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • 詳解ESLint在Vue中的使用小結

    詳解ESLint在Vue中的使用小結

    ESLint是一個QA工具,這篇文章主要介紹了詳解ESLint在Vue中的使用小結,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-10-10
  • Vue如何解決兄弟組件之間傳值問題

    Vue如何解決兄弟組件之間傳值問題

    這篇文章主要介紹了Vue如何解決兄弟組件之間傳值問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 解決axios發(fā)送post請求返回400狀態(tài)碼的問題

    解決axios發(fā)送post請求返回400狀態(tài)碼的問題

    今天小編就為大家分享一篇解決axios發(fā)送post請求返回400狀態(tài)碼的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • Vue按時間段查詢數據組件使用詳解

    Vue按時間段查詢數據組件使用詳解

    這篇文章主要為大家詳細介紹了Vue按時間段查詢數據組件的使用方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • 快速解決Vue項目在IE瀏覽器中顯示空白的問題

    快速解決Vue項目在IE瀏覽器中顯示空白的問題

    今天小編就為大家分享一篇快速解決Vue項目在IE瀏覽器中顯示空白的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • Vue 3.0 全家桶搶先體驗

    Vue 3.0 全家桶搶先體驗

    這篇文章主要介紹了Vue 3.0 全家桶搶先體驗,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • webpack+vue.js快速入門教程

    webpack+vue.js快速入門教程

    隨著前端的快速發(fā)展,非常多的js框架被應用到項目中。Vue.js本身支持對組件的異步加載,配合Webpack的分塊打包功能,可以極其輕松地實現組件的異步按需加載。 這篇文章是webpack+vue.j的入門教程,有需要的可以參考借鑒。
    2016-10-10
  • vuex頁面刷新后數據丟失的方法

    vuex頁面刷新后數據丟失的方法

    這篇文章主要介紹了vuex頁面刷新后數據丟失的方法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • npm run dev報錯信息及解決方法

    npm run dev報錯信息及解決方法

    這篇文章主要為大家介紹了npm run dev報錯信息及解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09

最新評論