Pārlūkot izejas kodu

feat(excel导出): 增加批量导出功能, 增加demo示例 (#2657)

* feat(excel导出): 批量导出功能

* feat(excel导出): 批量导出功能, 增加参数类型定义;增加demo示例

---------

Co-authored-by: 苗大 <caoshengmiao@hypergryph.com>
Wit〆苗大 1 gadu atpakaļ
vecāks
revīzija
9579a45b3c

+ 69 - 2
src/components/Excel/src/Export2Excel.ts

@@ -1,10 +1,12 @@
 import * as xlsx from 'xlsx';
 import type { WorkBook } from 'xlsx';
 import type { JsonToSheet, AoAToSheet } from './typing';
+import { AoaToMultipleSheet, JsonToMultipleSheet } from './typing';
 
 const { utils, writeFile } = xlsx;
 
 const DEF_FILE_NAME = 'excel-list.xlsx';
+const DEF_SHEET_NAME = 'sheet';
 
 /**
  * @param data source data
@@ -32,6 +34,7 @@ export function jsonToSheetXlsx<T = any>({
   data,
   header,
   filename = DEF_FILE_NAME,
+  sheetName = DEF_SHEET_NAME,
   json2sheetOpts = {},
   write2excelOpts = { bookType: 'xlsx' },
 }: JsonToSheet<T>) {
@@ -45,9 +48,9 @@ export function jsonToSheetXlsx<T = any>({
   setColumnWidth(arrData, worksheet);
   /* add worksheet to workbook */
   const workbook: WorkBook = {
-    SheetNames: [filename],
+    SheetNames: [sheetName],
     Sheets: {
-      [filename]: worksheet,
+      [sheetName]: worksheet,
     },
   };
   /* output format determined by filename */
@@ -79,3 +82,67 @@ export function aoaToSheetXlsx<T = any>({
   writeFile(workbook, filename, write2excelOpts);
   /* at this point, out.xlsb will have been downloaded */
 }
+
+/**
+ * json导出多Sheet的Xlsx
+ * @param sheetList 多sheet配置
+ * @param filename 文件名(包含后缀)
+ * @param write2excelOpts 文件配置
+ */
+export function jsonToMultipleSheetXlsx<T = any>({
+  sheetList,
+  filename = DEF_FILE_NAME,
+  write2excelOpts = { bookType: 'xlsx' },
+}: JsonToMultipleSheet<T>) {
+  const workbook: WorkBook = {
+    SheetNames: [],
+    Sheets: {},
+  };
+  sheetList.forEach((p, index) => {
+    const arrData = [...p.data];
+    if (p.header) {
+      arrData.unshift(p.header);
+      p.json2sheetOpts = p.json2sheetOpts || {};
+      p.json2sheetOpts.skipHeader = true;
+    }
+
+    const worksheet = utils.json_to_sheet(arrData, p.json2sheetOpts);
+    setColumnWidth(arrData, worksheet);
+
+    p.sheetName = p.sheetName || `${DEF_SHEET_NAME}${index}`;
+    workbook.SheetNames.push(p.sheetName);
+    workbook.Sheets[p.sheetName] = worksheet;
+  });
+  writeFile(workbook, filename, write2excelOpts);
+}
+
+/**
+ * aoa导出多Sheet的Xlsx
+ * @param sheetList 多sheet配置
+ * @param filename 文件名(包含后缀)
+ * @param write2excelOpts 文件配置
+ */
+export function aoaToMultipleSheetXlsx<T = any>({
+  sheetList,
+  filename = DEF_FILE_NAME,
+  write2excelOpts = { bookType: 'xlsx' },
+}: AoaToMultipleSheet<T>) {
+  const workbook: WorkBook = {
+    SheetNames: [],
+    Sheets: {},
+  };
+  sheetList.forEach((p, index) => {
+    const arrData = [...p.data];
+    if (p.header) {
+      arrData.unshift(p.header);
+    }
+    const worksheet = utils.aoa_to_sheet(arrData);
+
+    p.sheetName = p.sheetName || `${DEF_SHEET_NAME}${index}`;
+    workbook.SheetNames.push(p.sheetName);
+    workbook.Sheets[p.sheetName] = worksheet;
+  });
+  /* output format determined by filename */
+  writeFile(workbook, filename, write2excelOpts);
+  /* at this point, out.xlsb will have been downloaded */
+}

+ 14 - 0
src/components/Excel/src/typing.ts

@@ -10,6 +10,7 @@ export interface JsonToSheet<T = any> {
   data: T[];
   header?: T;
   filename?: string;
+  sheetName?: string;
   json2sheetOpts?: JSON2SheetOpts;
   write2excelOpts?: WritingOptions;
 }
@@ -18,6 +19,7 @@ export interface AoAToSheet<T = any> {
   data: T[][];
   header?: T[];
   filename?: string;
+  sheetName?: string;
   write2excelOpts?: WritingOptions;
 }
 
@@ -25,3 +27,15 @@ export interface ExportModalResult {
   filename: string;
   bookType: BookType;
 }
+
+export interface JsonToMultipleSheet<T = any> {
+  sheetList: JsonToSheet<T>[];
+  filename?: string;
+  write2excelOpts?: WritingOptions;
+}
+
+export interface AoaToMultipleSheet<T = any> {
+  sheetList: AoAToSheet<T>[];
+  filename?: string;
+  write2excelOpts?: WritingOptions;
+}

+ 21 - 0
src/views/demo/excel/ArrayExport.vue

@@ -3,6 +3,7 @@
     <BasicTable title="基础表格" :columns="columns" :dataSource="data">
       <template #toolbar>
         <a-button @click="aoaToExcel"> 导出 </a-button>
+        <a-button @click="aoaToMultipleSheet" danger> 导出多Sheet </a-button>
       </template>
     </BasicTable>
   </PageWrapper>
@@ -14,6 +15,7 @@
   import { aoaToSheetXlsx } from '/@/components/Excel';
   import { arrHeader, arrData, columns, data } from './data';
   import { PageWrapper } from '/@/components/Page';
+  import { aoaToMultipleSheetXlsx } from '/@/components/Excel/src/Export2Excel';
 
   export default defineComponent({
     components: { BasicTable, PageWrapper },
@@ -26,9 +28,28 @@
           filename: '二维数组方式导出excel.xlsx',
         });
       }
+      function aoaToMultipleSheet() {
+        // 保证data顺序与header一致
+        aoaToMultipleSheetXlsx({
+          sheetList: [
+            {
+              data: arrData,
+              header: arrHeader,
+              sheetName: 'Sheet1',
+            },
+            {
+              data: arrData,
+              header: arrHeader,
+              sheetName: 'Sheet2',
+            },
+          ],
+          filename: '二维数组方式导出excel-多Sheet示例.xlsx',
+        });
+      }
 
       return {
         aoaToExcel,
+        aoaToMultipleSheet,
         columns,
         data,
       };

+ 31 - 0
src/views/demo/excel/JsonExport.vue

@@ -4,6 +4,7 @@
       <template #toolbar>
         <a-button @click="defaultHeader"> 导出:默认头部 </a-button>
         <a-button @click="customHeader"> 导出:自定义头部 </a-button>
+        <a-button @click="handleMultipleSheet" danger> 导出多Sheet </a-button>
       </template>
     </BasicTable>
   </PageWrapper>
@@ -15,6 +16,7 @@
   import { jsonToSheetXlsx } from '/@/components/Excel';
   import { columns, data } from './data';
   import { PageWrapper } from '/@/components/Page';
+  import { jsonToMultipleSheetXlsx } from '/@/components/Excel/src/Export2Excel';
 
   export default defineComponent({
     components: { BasicTable, PageWrapper },
@@ -47,9 +49,38 @@
         });
       }
 
+      function handleMultipleSheet() {
+        jsonToMultipleSheetXlsx({
+          sheetList: [
+            {
+              data,
+              sheetName: '使用key作为默认头部',
+            },
+            {
+              data,
+              header: {
+                id: 'ID',
+                name: '姓名',
+                age: '年龄',
+                no: '编号',
+                address: '地址',
+                beginTime: '开始时间',
+                endTime: '结束时间',
+              },
+              json2sheetOpts: {
+                // 指定顺序
+                header: ['name', 'id'],
+              },
+              sheetName: '自定义头部',
+            },
+          ],
+          filename: '多Sheet导出示例.xlsx',
+        });
+      }
       return {
         defaultHeader,
         customHeader,
+        handleMultipleSheet,
         columns,
         data,
       };