Commit 9579a45b3cd35f432f3b0f8dc2ec97b8d2201603

Authored by Wit〆苗大
Committed by GitHub
1 parent 302afe58

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

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

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

---------

Co-authored-by: 苗大 <caoshengmiao@hypergryph.com>
src/components/Excel/src/Export2Excel.ts
1 1 import * as xlsx from 'xlsx';
2 2 import type { WorkBook } from 'xlsx';
3 3 import type { JsonToSheet, AoAToSheet } from './typing';
  4 +import { AoaToMultipleSheet, JsonToMultipleSheet } from './typing';
4 5  
5 6 const { utils, writeFile } = xlsx;
6 7  
7 8 const DEF_FILE_NAME = 'excel-list.xlsx';
  9 +const DEF_SHEET_NAME = 'sheet';
8 10  
9 11 /**
10 12 * @param data source data
... ... @@ -32,6 +34,7 @@ export function jsonToSheetXlsx&lt;T = any&gt;({
32 34 data,
33 35 header,
34 36 filename = DEF_FILE_NAME,
  37 + sheetName = DEF_SHEET_NAME,
35 38 json2sheetOpts = {},
36 39 write2excelOpts = { bookType: 'xlsx' },
37 40 }: JsonToSheet<T>) {
... ... @@ -45,9 +48,9 @@ export function jsonToSheetXlsx&lt;T = any&gt;({
45 48 setColumnWidth(arrData, worksheet);
46 49 /* add worksheet to workbook */
47 50 const workbook: WorkBook = {
48   - SheetNames: [filename],
  51 + SheetNames: [sheetName],
49 52 Sheets: {
50   - [filename]: worksheet,
  53 + [sheetName]: worksheet,
51 54 },
52 55 };
53 56 /* output format determined by filename */
... ... @@ -79,3 +82,67 @@ export function aoaToSheetXlsx&lt;T = any&gt;({
79 82 writeFile(workbook, filename, write2excelOpts);
80 83 /* at this point, out.xlsb will have been downloaded */
81 84 }
  85 +
  86 +/**
  87 + * json导出多Sheet的Xlsx
  88 + * @param sheetList 多sheet配置
  89 + * @param filename 文件名(包含后缀)
  90 + * @param write2excelOpts 文件配置
  91 + */
  92 +export function jsonToMultipleSheetXlsx<T = any>({
  93 + sheetList,
  94 + filename = DEF_FILE_NAME,
  95 + write2excelOpts = { bookType: 'xlsx' },
  96 +}: JsonToMultipleSheet<T>) {
  97 + const workbook: WorkBook = {
  98 + SheetNames: [],
  99 + Sheets: {},
  100 + };
  101 + sheetList.forEach((p, index) => {
  102 + const arrData = [...p.data];
  103 + if (p.header) {
  104 + arrData.unshift(p.header);
  105 + p.json2sheetOpts = p.json2sheetOpts || {};
  106 + p.json2sheetOpts.skipHeader = true;
  107 + }
  108 +
  109 + const worksheet = utils.json_to_sheet(arrData, p.json2sheetOpts);
  110 + setColumnWidth(arrData, worksheet);
  111 +
  112 + p.sheetName = p.sheetName || `${DEF_SHEET_NAME}${index}`;
  113 + workbook.SheetNames.push(p.sheetName);
  114 + workbook.Sheets[p.sheetName] = worksheet;
  115 + });
  116 + writeFile(workbook, filename, write2excelOpts);
  117 +}
  118 +
  119 +/**
  120 + * aoa导出多Sheet的Xlsx
  121 + * @param sheetList 多sheet配置
  122 + * @param filename 文件名(包含后缀)
  123 + * @param write2excelOpts 文件配置
  124 + */
  125 +export function aoaToMultipleSheetXlsx<T = any>({
  126 + sheetList,
  127 + filename = DEF_FILE_NAME,
  128 + write2excelOpts = { bookType: 'xlsx' },
  129 +}: AoaToMultipleSheet<T>) {
  130 + const workbook: WorkBook = {
  131 + SheetNames: [],
  132 + Sheets: {},
  133 + };
  134 + sheetList.forEach((p, index) => {
  135 + const arrData = [...p.data];
  136 + if (p.header) {
  137 + arrData.unshift(p.header);
  138 + }
  139 + const worksheet = utils.aoa_to_sheet(arrData);
  140 +
  141 + p.sheetName = p.sheetName || `${DEF_SHEET_NAME}${index}`;
  142 + workbook.SheetNames.push(p.sheetName);
  143 + workbook.Sheets[p.sheetName] = worksheet;
  144 + });
  145 + /* output format determined by filename */
  146 + writeFile(workbook, filename, write2excelOpts);
  147 + /* at this point, out.xlsb will have been downloaded */
  148 +}
... ...
src/components/Excel/src/typing.ts
... ... @@ -10,6 +10,7 @@ export interface JsonToSheet&lt;T = any&gt; {
10 10 data: T[];
11 11 header?: T;
12 12 filename?: string;
  13 + sheetName?: string;
13 14 json2sheetOpts?: JSON2SheetOpts;
14 15 write2excelOpts?: WritingOptions;
15 16 }
... ... @@ -18,6 +19,7 @@ export interface AoAToSheet&lt;T = any&gt; {
18 19 data: T[][];
19 20 header?: T[];
20 21 filename?: string;
  22 + sheetName?: string;
21 23 write2excelOpts?: WritingOptions;
22 24 }
23 25  
... ... @@ -25,3 +27,15 @@ export interface ExportModalResult {
25 27 filename: string;
26 28 bookType: BookType;
27 29 }
  30 +
  31 +export interface JsonToMultipleSheet<T = any> {
  32 + sheetList: JsonToSheet<T>[];
  33 + filename?: string;
  34 + write2excelOpts?: WritingOptions;
  35 +}
  36 +
  37 +export interface AoaToMultipleSheet<T = any> {
  38 + sheetList: AoAToSheet<T>[];
  39 + filename?: string;
  40 + write2excelOpts?: WritingOptions;
  41 +}
... ...
src/views/demo/excel/ArrayExport.vue
... ... @@ -3,6 +3,7 @@
3 3 <BasicTable title="基础表格" :columns="columns" :dataSource="data">
4 4 <template #toolbar>
5 5 <a-button @click="aoaToExcel"> 导出 </a-button>
  6 + <a-button @click="aoaToMultipleSheet" danger> 导出多Sheet </a-button>
6 7 </template>
7 8 </BasicTable>
8 9 </PageWrapper>
... ... @@ -14,6 +15,7 @@
14 15 import { aoaToSheetXlsx } from '/@/components/Excel';
15 16 import { arrHeader, arrData, columns, data } from './data';
16 17 import { PageWrapper } from '/@/components/Page';
  18 + import { aoaToMultipleSheetXlsx } from '/@/components/Excel/src/Export2Excel';
17 19  
18 20 export default defineComponent({
19 21 components: { BasicTable, PageWrapper },
... ... @@ -26,9 +28,28 @@
26 28 filename: '二维数组方式导出excel.xlsx',
27 29 });
28 30 }
  31 + function aoaToMultipleSheet() {
  32 + // 保证data顺序与header一致
  33 + aoaToMultipleSheetXlsx({
  34 + sheetList: [
  35 + {
  36 + data: arrData,
  37 + header: arrHeader,
  38 + sheetName: 'Sheet1',
  39 + },
  40 + {
  41 + data: arrData,
  42 + header: arrHeader,
  43 + sheetName: 'Sheet2',
  44 + },
  45 + ],
  46 + filename: '二维数组方式导出excel-多Sheet示例.xlsx',
  47 + });
  48 + }
29 49  
30 50 return {
31 51 aoaToExcel,
  52 + aoaToMultipleSheet,
32 53 columns,
33 54 data,
34 55 };
... ...
src/views/demo/excel/JsonExport.vue
... ... @@ -4,6 +4,7 @@
4 4 <template #toolbar>
5 5 <a-button @click="defaultHeader"> 导出:默认头部 </a-button>
6 6 <a-button @click="customHeader"> 导出:自定义头部 </a-button>
  7 + <a-button @click="handleMultipleSheet" danger> 导出多Sheet </a-button>
7 8 </template>
8 9 </BasicTable>
9 10 </PageWrapper>
... ... @@ -15,6 +16,7 @@
15 16 import { jsonToSheetXlsx } from '/@/components/Excel';
16 17 import { columns, data } from './data';
17 18 import { PageWrapper } from '/@/components/Page';
  19 + import { jsonToMultipleSheetXlsx } from '/@/components/Excel/src/Export2Excel';
18 20  
19 21 export default defineComponent({
20 22 components: { BasicTable, PageWrapper },
... ... @@ -47,9 +49,38 @@
47 49 });
48 50 }
49 51  
  52 + function handleMultipleSheet() {
  53 + jsonToMultipleSheetXlsx({
  54 + sheetList: [
  55 + {
  56 + data,
  57 + sheetName: '使用key作为默认头部',
  58 + },
  59 + {
  60 + data,
  61 + header: {
  62 + id: 'ID',
  63 + name: '姓名',
  64 + age: '年龄',
  65 + no: '编号',
  66 + address: '地址',
  67 + beginTime: '开始时间',
  68 + endTime: '结束时间',
  69 + },
  70 + json2sheetOpts: {
  71 + // 指定顺序
  72 + header: ['name', 'id'],
  73 + },
  74 + sheetName: '自定义头部',
  75 + },
  76 + ],
  77 + filename: '多Sheet导出示例.xlsx',
  78 + });
  79 + }
50 80 return {
51 81 defaultHeader,
52 82 customHeader,
  83 + handleMultipleSheet,
53 84 columns,
54 85 data,
55 86 };
... ...