Commit c0692b0f43b50be56e399c4aa07c0c4244080e9f
Committed by
GitHub
1 parent
0a2e417b
feat(excel): import/export (#40)
Showing
12 changed files
with
617 additions
and
0 deletions
package.json
@@ -35,6 +35,7 @@ | @@ -35,6 +35,7 @@ | ||
35 | "vue-router": "^4.0.0-beta.13", | 35 | "vue-router": "^4.0.0-beta.13", |
36 | "vuex": "^4.0.0-beta.4", | 36 | "vuex": "^4.0.0-beta.4", |
37 | "vuex-module-decorators": "^1.0.1", | 37 | "vuex-module-decorators": "^1.0.1", |
38 | + "xlsx": "^0.16.8", | ||
38 | "zxcvbn": "^4.4.2" | 39 | "zxcvbn": "^4.4.2" |
39 | }, | 40 | }, |
40 | "devDependencies": { | 41 | "devDependencies": { |
src/components/Excel/index.ts
0 → 100644
src/components/Excel/src/Export2Excel.ts
0 → 100644
1 | +import xlsx from 'xlsx'; | ||
2 | +import type { WorkBook } from 'xlsx'; | ||
3 | +import type { JsonToSheet, AoAToSheet } from './types'; | ||
4 | +// import { isObject } from '@/src/utils/is'; | ||
5 | + | ||
6 | +const { utils, writeFile } = xlsx; | ||
7 | + | ||
8 | +export function jsonToSheetXlsx<T = any>({ | ||
9 | + data, | ||
10 | + header, | ||
11 | + filename = 'excel-list.xlsx', | ||
12 | + json2sheetOpts = {}, | ||
13 | + write2excelOpts = { bookType: 'xlsx' }, | ||
14 | +}: JsonToSheet<T>) { | ||
15 | + const arrData = [...data]; | ||
16 | + if (header) { | ||
17 | + arrData.unshift(header); | ||
18 | + json2sheetOpts.skipHeader = true; | ||
19 | + } | ||
20 | + | ||
21 | + const worksheet = utils.json_to_sheet(arrData, json2sheetOpts); | ||
22 | + | ||
23 | + /* add worksheet to workbook */ | ||
24 | + const workbook: WorkBook = { | ||
25 | + SheetNames: [filename], | ||
26 | + Sheets: { | ||
27 | + [filename]: worksheet, | ||
28 | + }, | ||
29 | + }; | ||
30 | + /* output format determined by filename */ | ||
31 | + writeFile(workbook, filename, write2excelOpts); | ||
32 | + /* at this point, out.xlsb will have been downloaded */ | ||
33 | +} | ||
34 | +export function aoaToSheetXlsx<T = any>({ | ||
35 | + data, | ||
36 | + header, | ||
37 | + filename = 'excel-list.xlsx', | ||
38 | + write2excelOpts = { bookType: 'xlsx' }, | ||
39 | +}: AoAToSheet<T>) { | ||
40 | + const arrData = [...data]; | ||
41 | + if (header) { | ||
42 | + arrData.unshift(header); | ||
43 | + } | ||
44 | + | ||
45 | + const worksheet = utils.aoa_to_sheet(arrData); | ||
46 | + | ||
47 | + /* add worksheet to workbook */ | ||
48 | + const workbook: WorkBook = { | ||
49 | + SheetNames: [filename], | ||
50 | + Sheets: { | ||
51 | + [filename]: worksheet, | ||
52 | + }, | ||
53 | + }; | ||
54 | + /* output format determined by filename */ | ||
55 | + writeFile(workbook, filename, write2excelOpts); | ||
56 | + /* at this point, out.xlsb will have been downloaded */ | ||
57 | +} |
src/components/Excel/src/ExportExcelModel.vue
0 → 100644
1 | +<template> | ||
2 | + <BasicModal v-bind="$attrs" title="导出数据" @ok="handleOk" @register="registerModal"> | ||
3 | + <BasicForm | ||
4 | + :labelWidth="100" | ||
5 | + :schemas="schemas" | ||
6 | + :showActionButtonGroup="false" | ||
7 | + @register="registerForm" | ||
8 | + /> | ||
9 | + </BasicModal> | ||
10 | +</template> | ||
11 | +<script lang="ts"> | ||
12 | + import { defineComponent } from 'vue'; | ||
13 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | ||
14 | + import { BasicForm, FormSchema, useForm } from '/@/components/Form/index'; | ||
15 | + | ||
16 | + const schemas: FormSchema[] = [ | ||
17 | + { | ||
18 | + field: 'filename', | ||
19 | + component: 'Input', | ||
20 | + label: '文件名', | ||
21 | + rules: [{ required: true }], | ||
22 | + }, | ||
23 | + { | ||
24 | + field: 'bookType', | ||
25 | + component: 'Select', | ||
26 | + label: '文件类型', | ||
27 | + defaultValue: 'xlsx', | ||
28 | + rules: [{ required: true }], | ||
29 | + componentProps: { | ||
30 | + options: [ | ||
31 | + { | ||
32 | + label: 'xlsx', | ||
33 | + value: 'xlsx', | ||
34 | + key: 'xlsx', | ||
35 | + }, | ||
36 | + { | ||
37 | + label: 'html', | ||
38 | + value: 'html', | ||
39 | + key: 'html', | ||
40 | + }, | ||
41 | + { | ||
42 | + label: 'csv', | ||
43 | + value: 'csv', | ||
44 | + key: 'csv', | ||
45 | + }, | ||
46 | + { | ||
47 | + label: 'txt', | ||
48 | + value: 'txt', | ||
49 | + key: 'txt', | ||
50 | + }, | ||
51 | + ], | ||
52 | + }, | ||
53 | + }, | ||
54 | + ]; | ||
55 | + export default defineComponent({ | ||
56 | + components: { BasicModal, BasicForm }, | ||
57 | + setup(_, { emit }) { | ||
58 | + const [registerForm, { validateFields }] = useForm(); | ||
59 | + const [registerModal, { closeModal }] = useModalInner(); | ||
60 | + | ||
61 | + async function handleOk() { | ||
62 | + const res = await validateFields(); | ||
63 | + const { filename, bookType } = res; | ||
64 | + | ||
65 | + emit('success', { | ||
66 | + filename: `${filename.split('.').shift()}.${bookType}`, | ||
67 | + bookType, | ||
68 | + }); | ||
69 | + closeModal(); | ||
70 | + } | ||
71 | + return { | ||
72 | + schemas, | ||
73 | + handleOk, | ||
74 | + registerForm, | ||
75 | + registerModal, | ||
76 | + }; | ||
77 | + }, | ||
78 | + }); | ||
79 | +</script> |
src/components/Excel/src/ImportExcel.tsx
0 → 100644
1 | +import { defineComponent, ref, unref } from 'vue'; | ||
2 | +import XLSX from 'xlsx'; | ||
3 | +import { getSlot } from '/@/utils/helper/tsxHelper'; | ||
4 | + | ||
5 | +import type { ExcelData } from './types'; | ||
6 | +export default defineComponent({ | ||
7 | + name: 'ImportExcel', | ||
8 | + setup(_, { slots, emit }) { | ||
9 | + const inputRef = ref<HTMLInputElement | null>(null); | ||
10 | + const loadingRef = ref<Boolean>(false); | ||
11 | + | ||
12 | + /** | ||
13 | + * @description: 第一行作为头部 | ||
14 | + */ | ||
15 | + function getHeaderRow(sheet: XLSX.WorkSheet) { | ||
16 | + if (!sheet || !sheet['!ref']) return []; | ||
17 | + const headers: string[] = []; | ||
18 | + // A3:B7=>{s:{c:0, r:2}, e:{c:1, r:6}} | ||
19 | + const range = XLSX.utils.decode_range(sheet['!ref']); | ||
20 | + | ||
21 | + const R = range.s.r; | ||
22 | + /* start in the first row */ | ||
23 | + for (let C = range.s.c; C <= range.e.c; ++C) { | ||
24 | + /* walk every column in the range */ | ||
25 | + const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]; | ||
26 | + /* find the cell in the first row */ | ||
27 | + let hdr = 'UNKNOWN ' + C; // <-- replace with your desired default | ||
28 | + if (cell && cell.t) hdr = XLSX.utils.format_cell(cell); | ||
29 | + headers.push(hdr); | ||
30 | + } | ||
31 | + return headers; | ||
32 | + } | ||
33 | + | ||
34 | + /** | ||
35 | + * @description: 获得excel数据 | ||
36 | + */ | ||
37 | + function getExcelData(workbook: XLSX.WorkBook) { | ||
38 | + const excelData: ExcelData[] = []; | ||
39 | + for (const sheetName of workbook.SheetNames) { | ||
40 | + const worksheet = workbook.Sheets[sheetName]; | ||
41 | + const header: string[] = getHeaderRow(worksheet); | ||
42 | + const results = XLSX.utils.sheet_to_json(worksheet); | ||
43 | + excelData.push({ | ||
44 | + header, | ||
45 | + results, | ||
46 | + meta: { | ||
47 | + sheetName, | ||
48 | + }, | ||
49 | + }); | ||
50 | + } | ||
51 | + return excelData; | ||
52 | + } | ||
53 | + | ||
54 | + /** | ||
55 | + * @description: 读取excel数据 | ||
56 | + */ | ||
57 | + function readerData(rawFile: File) { | ||
58 | + loadingRef.value = true; | ||
59 | + return new Promise((resolve, reject) => { | ||
60 | + const reader = new FileReader(); | ||
61 | + reader.onload = async (e) => { | ||
62 | + try { | ||
63 | + const data = e.target && e.target.result; | ||
64 | + const workbook = XLSX.read(data, { type: 'array' }); | ||
65 | + // console.log(workbook); | ||
66 | + /* DO SOMETHING WITH workbook HERE */ | ||
67 | + const excelData = getExcelData(workbook); | ||
68 | + emit('success', excelData); | ||
69 | + resolve(); | ||
70 | + } catch (error) { | ||
71 | + reject(error); | ||
72 | + } finally { | ||
73 | + loadingRef.value = false; | ||
74 | + } | ||
75 | + }; | ||
76 | + reader.readAsArrayBuffer(rawFile); | ||
77 | + }); | ||
78 | + } | ||
79 | + | ||
80 | + async function upload(rawFile: File) { | ||
81 | + const inputRefDom = unref(inputRef); | ||
82 | + if (inputRefDom) { | ||
83 | + // fix can't select the same excel | ||
84 | + inputRefDom.value = ''; | ||
85 | + } | ||
86 | + readerData(rawFile); | ||
87 | + } | ||
88 | + /** | ||
89 | + * @description: 触发选择文件管理器 | ||
90 | + */ | ||
91 | + function handleInputClick(e: Event) { | ||
92 | + const files = e && (e.target as HTMLInputElement).files; | ||
93 | + const rawFile = files && files[0]; // only use files[0] | ||
94 | + if (!rawFile) return; | ||
95 | + upload(rawFile); | ||
96 | + } | ||
97 | + /** | ||
98 | + * @description: 点击上传按钮 | ||
99 | + */ | ||
100 | + function handleUpload() { | ||
101 | + const inputRefDom = unref(inputRef); | ||
102 | + inputRefDom && inputRefDom.click(); | ||
103 | + } | ||
104 | + | ||
105 | + return () => { | ||
106 | + return ( | ||
107 | + <div> | ||
108 | + <input | ||
109 | + ref={inputRef} | ||
110 | + type="file" | ||
111 | + accept=".xlsx, .xls" | ||
112 | + style=" z-index: -9999; display: none;" | ||
113 | + onChange={handleInputClick} | ||
114 | + /> | ||
115 | + <div onClick={handleUpload}>{getSlot(slots)}</div> | ||
116 | + </div> | ||
117 | + ); | ||
118 | + }; | ||
119 | + }, | ||
120 | +}); |
src/components/Excel/src/types.ts
0 → 100644
1 | +import type { JSON2SheetOpts, WritingOptions, BookType } from 'xlsx'; | ||
2 | + | ||
3 | +export interface ExcelData<T = any> { | ||
4 | + header: string[]; | ||
5 | + results: T[]; | ||
6 | + meta: { sheetName: string }; | ||
7 | +} | ||
8 | + | ||
9 | +// export interface ImportProps { | ||
10 | +// beforeUpload: (file: File) => boolean; | ||
11 | +// } | ||
12 | + | ||
13 | +export interface JsonToSheet<T = any> { | ||
14 | + data: T[]; | ||
15 | + header?: T; | ||
16 | + filename?: string; | ||
17 | + json2sheetOpts?: JSON2SheetOpts; | ||
18 | + write2excelOpts?: WritingOptions; | ||
19 | +} | ||
20 | +export interface AoAToSheet<T = any> { | ||
21 | + data: T[][]; | ||
22 | + header?: T[]; | ||
23 | + filename?: string; | ||
24 | + write2excelOpts?: WritingOptions; | ||
25 | +} | ||
26 | + | ||
27 | +export interface ExportModalResult { | ||
28 | + filename: string; | ||
29 | + bookType: BookType; | ||
30 | +} |
src/router/menus/modules/demo/comp.ts
@@ -66,6 +66,20 @@ const menu: MenuModule = { | @@ -66,6 +66,20 @@ const menu: MenuModule = { | ||
66 | path: '/strength-meter', | 66 | path: '/strength-meter', |
67 | name: '密码强度组件', | 67 | name: '密码强度组件', |
68 | }, | 68 | }, |
69 | + { | ||
70 | + path: '/excel', | ||
71 | + name: 'excel', | ||
72 | + children: [ | ||
73 | + { | ||
74 | + path: '/export', | ||
75 | + name: 'Export', | ||
76 | + }, | ||
77 | + { | ||
78 | + path: '/import', | ||
79 | + name: 'Import', | ||
80 | + }, | ||
81 | + ], | ||
82 | + }, | ||
69 | ], | 83 | ], |
70 | }, | 84 | }, |
71 | }; | 85 | }; |
src/router/routes/modules/demo/comp.ts
@@ -136,5 +136,31 @@ export default { | @@ -136,5 +136,31 @@ export default { | ||
136 | title: '密码强度组件', | 136 | title: '密码强度组件', |
137 | }, | 137 | }, |
138 | }, | 138 | }, |
139 | + { | ||
140 | + path: '/excel', | ||
141 | + name: 'ExcelDemo', | ||
142 | + redirect: '/comp/excel/export', | ||
143 | + meta: { | ||
144 | + title: 'excel', | ||
145 | + }, | ||
146 | + children: [ | ||
147 | + { | ||
148 | + path: 'export', | ||
149 | + name: 'Export2Excel', | ||
150 | + component: () => import('/@/views/demo/comp/excel/ExportToExcel.vue'), | ||
151 | + meta: { | ||
152 | + title: 'Export2Excel', | ||
153 | + }, | ||
154 | + }, | ||
155 | + { | ||
156 | + path: 'import', | ||
157 | + name: 'ImportExcel', | ||
158 | + component: () => import('/@/views/demo/comp/excel/ImportExcel.vue'), | ||
159 | + meta: { | ||
160 | + title: 'ImportExcel', | ||
161 | + }, | ||
162 | + }, | ||
163 | + ], | ||
164 | + }, | ||
139 | ], | 165 | ], |
140 | } as AppRouteModule; | 166 | } as AppRouteModule; |
src/views/demo/comp/excel/ExportToExcel.vue
0 → 100644
1 | +<template> | ||
2 | + <div> | ||
3 | + <BasicTable title="基础表格" :columns="columns" :dataSource="data"> | ||
4 | + <template #toolbar> | ||
5 | + <a-button @click="openModal">JSON格式导出:默认头部</a-button> | ||
6 | + <a-button @click="customHeader">JSON格式导出:自定义头部</a-button> | ||
7 | + <a-button @click="aoaToExcel">二维数组格式导出</a-button> | ||
8 | + </template> | ||
9 | + </BasicTable> | ||
10 | + <ExportExcelModel @register="register" @success="defaultHeader" /> | ||
11 | + </div> | ||
12 | +</template> | ||
13 | + | ||
14 | +<script lang="ts"> | ||
15 | + import { defineComponent } from 'vue'; | ||
16 | + import { BasicTable } from '/@/components/Table'; | ||
17 | + import { | ||
18 | + jsonToSheetXlsx, | ||
19 | + aoaToSheetXlsx, | ||
20 | + ExportExcelModel, | ||
21 | + ExportModalResult, | ||
22 | + } from '/@/components/Excel'; | ||
23 | + import { columns, data, arrHeader, arrData } from './data'; | ||
24 | + import { useModal } from '/@/components/Modal'; | ||
25 | + | ||
26 | + export default defineComponent({ | ||
27 | + components: { BasicTable, ExportExcelModel }, | ||
28 | + setup() { | ||
29 | + function defaultHeader({ filename, bookType }: ExportModalResult) { | ||
30 | + // 默认Object.keys(data[0])作为header | ||
31 | + jsonToSheetXlsx({ | ||
32 | + data, | ||
33 | + filename, | ||
34 | + write2excelOpts: { | ||
35 | + bookType, | ||
36 | + }, | ||
37 | + }); | ||
38 | + } | ||
39 | + function customHeader() { | ||
40 | + jsonToSheetXlsx({ | ||
41 | + data, | ||
42 | + header: { | ||
43 | + id: 'ID', | ||
44 | + name: '姓名', | ||
45 | + age: '年龄', | ||
46 | + no: '编号', | ||
47 | + address: '地址', | ||
48 | + beginTime: '开始时间', | ||
49 | + endTime: '结束时间', | ||
50 | + }, | ||
51 | + filename: '文件名头部修改.xlsx', | ||
52 | + json2sheetOpts: { | ||
53 | + // 指定顺序 | ||
54 | + header: ['name', 'id'], | ||
55 | + }, | ||
56 | + }); | ||
57 | + } | ||
58 | + function aoaToExcel() { | ||
59 | + // 保证data顺序与header一致 | ||
60 | + aoaToSheetXlsx({ | ||
61 | + data: arrData, | ||
62 | + header: arrHeader, | ||
63 | + filename: '数组方式导出excel.xlsx', | ||
64 | + }); | ||
65 | + } | ||
66 | + const [register, { openModal }] = useModal(); | ||
67 | + | ||
68 | + return { | ||
69 | + defaultHeader, | ||
70 | + customHeader, | ||
71 | + aoaToExcel, | ||
72 | + columns, | ||
73 | + data, | ||
74 | + register, | ||
75 | + openModal, | ||
76 | + }; | ||
77 | + }, | ||
78 | + }); | ||
79 | +</script> |
src/views/demo/comp/excel/ImportExcel.vue
0 → 100644
1 | +<template> | ||
2 | + <div> | ||
3 | + <ImportExcel @success="loadDataSuccess"> | ||
4 | + <a-button class="m-3">导入Excel</a-button> | ||
5 | + </ImportExcel> | ||
6 | + <BasicTable | ||
7 | + v-for="(table, index) in tableListRef" | ||
8 | + :key="index" | ||
9 | + :title="table.title" | ||
10 | + :columns="table.columns" | ||
11 | + :dataSource="table.dataSource" | ||
12 | + ></BasicTable> | ||
13 | + </div> | ||
14 | +</template> | ||
15 | +<script lang="ts"> | ||
16 | + import { defineComponent, ref } from 'vue'; | ||
17 | + | ||
18 | + import { ImportExcel, ExcelData } from '/@/components/Excel'; | ||
19 | + import { BasicTable, BasicColumn } from '/@/components/Table'; | ||
20 | + | ||
21 | + export default defineComponent({ | ||
22 | + components: { BasicTable, ImportExcel }, | ||
23 | + | ||
24 | + setup() { | ||
25 | + const tableListRef = ref< | ||
26 | + { | ||
27 | + title: string; | ||
28 | + columns?: any[]; | ||
29 | + dataSource?: any[]; | ||
30 | + }[] | ||
31 | + >([]); | ||
32 | + | ||
33 | + function loadDataSuccess(excelDataList: ExcelData[]) { | ||
34 | + tableListRef.value = []; | ||
35 | + console.log(excelDataList); | ||
36 | + for (const excelData of excelDataList) { | ||
37 | + const { | ||
38 | + header, | ||
39 | + results, | ||
40 | + meta: { sheetName }, | ||
41 | + } = excelData; | ||
42 | + const columns: BasicColumn[] = []; | ||
43 | + for (const title of header) { | ||
44 | + columns.push({ title, dataIndex: title }); | ||
45 | + } | ||
46 | + tableListRef.value.push({ title: sheetName, dataSource: results, columns }); | ||
47 | + } | ||
48 | + } | ||
49 | + | ||
50 | + return { | ||
51 | + loadDataSuccess, | ||
52 | + tableListRef, | ||
53 | + }; | ||
54 | + }, | ||
55 | + }); | ||
56 | +</script> |
src/views/demo/comp/excel/data.ts
0 → 100644
1 | +import { BasicColumn } from '/@/components/Table'; | ||
2 | + | ||
3 | +export const columns: BasicColumn[] = [ | ||
4 | + { | ||
5 | + title: 'ID', | ||
6 | + dataIndex: 'id', | ||
7 | + width: 80, | ||
8 | + }, | ||
9 | + { | ||
10 | + title: '姓名', | ||
11 | + dataIndex: 'name', | ||
12 | + width: 120, | ||
13 | + }, | ||
14 | + { | ||
15 | + title: '年龄', | ||
16 | + dataIndex: 'age', | ||
17 | + width: 80, | ||
18 | + }, | ||
19 | + { | ||
20 | + title: '编号', | ||
21 | + dataIndex: 'no', | ||
22 | + width: 80, | ||
23 | + }, | ||
24 | + { | ||
25 | + title: '地址', | ||
26 | + dataIndex: 'address', | ||
27 | + }, | ||
28 | + { | ||
29 | + title: '开始时间', | ||
30 | + dataIndex: 'beginTime', | ||
31 | + }, | ||
32 | + { | ||
33 | + title: '结束时间', | ||
34 | + dataIndex: 'endTime', | ||
35 | + }, | ||
36 | +]; | ||
37 | + | ||
38 | +export const data: any[] = (() => { | ||
39 | + const arr: any[] = []; | ||
40 | + for (let index = 0; index < 40; index++) { | ||
41 | + arr.push({ | ||
42 | + id: `${index}`, | ||
43 | + name: `${index} John Brown`, | ||
44 | + age: `${index + 10}`, | ||
45 | + no: `${index}98678`, | ||
46 | + address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park', | ||
47 | + beginTime: new Date().toLocaleString(), | ||
48 | + endTime: new Date().toLocaleString(), | ||
49 | + }); | ||
50 | + } | ||
51 | + return arr; | ||
52 | +})(); | ||
53 | + | ||
54 | +// ["ID", "姓名", "年龄", "编号", "地址", "开始时间", "结束时间"] | ||
55 | +export const arrHeader = columns.map((column) => column.title); | ||
56 | +// [["ID", "姓名", "年龄", "编号", "地址", "开始时间", "结束时间"],["0", "0 John Brown", "10", "098678"]] | ||
57 | +export const arrData = data.map((item) => { | ||
58 | + return Object.keys(item).map((key) => item[key]); | ||
59 | +}); |
yarn.lock
@@ -1081,6 +1081,14 @@ add-stream@^1.0.0: | @@ -1081,6 +1081,14 @@ add-stream@^1.0.0: | ||
1081 | resolved "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" | 1081 | resolved "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" |
1082 | integrity sha1-anmQQ3ynNtXhKI25K9MmbV9csqo= | 1082 | integrity sha1-anmQQ3ynNtXhKI25K9MmbV9csqo= |
1083 | 1083 | ||
1084 | +adler-32@~1.2.0: | ||
1085 | + version "1.2.0" | ||
1086 | + resolved "https://registry.yarnpkg.com/adler-32/-/adler-32-1.2.0.tgz#6a3e6bf0a63900ba15652808cb15c6813d1a5f25" | ||
1087 | + integrity sha1-aj5r8KY5ALoVZSgIyxXGgT0aXyU= | ||
1088 | + dependencies: | ||
1089 | + exit-on-epipe "~1.0.1" | ||
1090 | + printj "~1.1.0" | ||
1091 | + | ||
1084 | aggregate-error@^3.0.0: | 1092 | aggregate-error@^3.0.0: |
1085 | version "3.1.0" | 1093 | version "3.1.0" |
1086 | resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" | 1094 | resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" |
@@ -1570,6 +1578,15 @@ ccount@^1.0.0: | @@ -1570,6 +1578,15 @@ ccount@^1.0.0: | ||
1570 | resolved "https://registry.npmjs.org/ccount/-/ccount-1.0.5.tgz#ac82a944905a65ce204eb03023157edf29425c17" | 1578 | resolved "https://registry.npmjs.org/ccount/-/ccount-1.0.5.tgz#ac82a944905a65ce204eb03023157edf29425c17" |
1571 | integrity sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw== | 1579 | integrity sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw== |
1572 | 1580 | ||
1581 | +cfb@^1.1.4: | ||
1582 | + version "1.2.0" | ||
1583 | + resolved "https://registry.yarnpkg.com/cfb/-/cfb-1.2.0.tgz#6a4d0872b525ed60349e1ef51fb4b0bf73eca9a8" | ||
1584 | + integrity sha512-sXMvHsKCICVR3Naq+J556K+ExBo9n50iKl6LGarlnvuA2035uMlGA/qVrc0wQtow5P1vJEw9UyrKLCbtIKz+TQ== | ||
1585 | + dependencies: | ||
1586 | + adler-32 "~1.2.0" | ||
1587 | + crc-32 "~1.2.0" | ||
1588 | + printj "~1.1.2" | ||
1589 | + | ||
1573 | chalk@2.3.0: | 1590 | chalk@2.3.0: |
1574 | version "2.3.0" | 1591 | version "2.3.0" |
1575 | resolved "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" | 1592 | resolved "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" |
@@ -1754,6 +1771,14 @@ co@^4.6.0: | @@ -1754,6 +1771,14 @@ co@^4.6.0: | ||
1754 | resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" | 1771 | resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" |
1755 | integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= | 1772 | integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= |
1756 | 1773 | ||
1774 | +codepage@~1.14.0: | ||
1775 | + version "1.14.0" | ||
1776 | + resolved "https://registry.yarnpkg.com/codepage/-/codepage-1.14.0.tgz#8cbe25481323559d7d307571b0fff91e7a1d2f99" | ||
1777 | + integrity sha1-jL4lSBMjVZ19MHVxsP/5HnodL5k= | ||
1778 | + dependencies: | ||
1779 | + commander "~2.14.1" | ||
1780 | + exit-on-epipe "~1.0.1" | ||
1781 | + | ||
1757 | collapse-white-space@^1.0.2: | 1782 | collapse-white-space@^1.0.2: |
1758 | version "1.0.6" | 1783 | version "1.0.6" |
1759 | resolved "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" | 1784 | resolved "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" |
@@ -1806,6 +1831,16 @@ commander@^2.19.0, commander@^2.20.0: | @@ -1806,6 +1831,16 @@ commander@^2.19.0, commander@^2.20.0: | ||
1806 | resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" | 1831 | resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" |
1807 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== | 1832 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== |
1808 | 1833 | ||
1834 | +commander@~2.14.1: | ||
1835 | + version "2.14.1" | ||
1836 | + resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa" | ||
1837 | + integrity sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw== | ||
1838 | + | ||
1839 | +commander@~2.17.1: | ||
1840 | + version "2.17.1" | ||
1841 | + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" | ||
1842 | + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== | ||
1843 | + | ||
1809 | commitizen@^4.0.3, commitizen@^4.2.1: | 1844 | commitizen@^4.0.3, commitizen@^4.2.1: |
1810 | version "4.2.1" | 1845 | version "4.2.1" |
1811 | resolved "https://registry.npmjs.org/commitizen/-/commitizen-4.2.1.tgz#3b098b16c6b1a37f0d129018dff6751b20cd3103" | 1846 | resolved "https://registry.npmjs.org/commitizen/-/commitizen-4.2.1.tgz#3b098b16c6b1a37f0d129018dff6751b20cd3103" |
@@ -2114,6 +2149,14 @@ cosmiconfig@^7.0.0: | @@ -2114,6 +2149,14 @@ cosmiconfig@^7.0.0: | ||
2114 | path-type "^4.0.0" | 2149 | path-type "^4.0.0" |
2115 | yaml "^1.10.0" | 2150 | yaml "^1.10.0" |
2116 | 2151 | ||
2152 | +crc-32@~1.2.0: | ||
2153 | + version "1.2.0" | ||
2154 | + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" | ||
2155 | + integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA== | ||
2156 | + dependencies: | ||
2157 | + exit-on-epipe "~1.0.1" | ||
2158 | + printj "~1.1.0" | ||
2159 | + | ||
2117 | cross-env@^7.0.2: | 2160 | cross-env@^7.0.2: |
2118 | version "7.0.2" | 2161 | version "7.0.2" |
2119 | resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9" | 2162 | resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9" |
@@ -2705,6 +2748,11 @@ execall@^2.0.0: | @@ -2705,6 +2748,11 @@ execall@^2.0.0: | ||
2705 | dependencies: | 2748 | dependencies: |
2706 | clone-regexp "^2.1.0" | 2749 | clone-regexp "^2.1.0" |
2707 | 2750 | ||
2751 | +exit-on-epipe@~1.0.1: | ||
2752 | + version "1.0.1" | ||
2753 | + resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" | ||
2754 | + integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== | ||
2755 | + | ||
2708 | expand-brackets@^2.1.4: | 2756 | expand-brackets@^2.1.4: |
2709 | version "2.1.4" | 2757 | version "2.1.4" |
2710 | resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" | 2758 | resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" |
@@ -2942,6 +2990,11 @@ for-in@^1.0.2: | @@ -2942,6 +2990,11 @@ for-in@^1.0.2: | ||
2942 | resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" | 2990 | resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" |
2943 | integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= | 2991 | integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= |
2944 | 2992 | ||
2993 | +frac@~1.1.2: | ||
2994 | + version "1.1.2" | ||
2995 | + resolved "https://registry.yarnpkg.com/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b" | ||
2996 | + integrity sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA== | ||
2997 | + | ||
2945 | fragment-cache@^0.2.1: | 2998 | fragment-cache@^0.2.1: |
2946 | version "0.2.1" | 2999 | version "0.2.1" |
2947 | resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" | 3000 | resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" |
@@ -5337,6 +5390,11 @@ prettier@^2.1.2: | @@ -5337,6 +5390,11 @@ prettier@^2.1.2: | ||
5337 | resolved "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz#3050700dae2e4c8b67c4c3f666cdb8af405e1ce5" | 5390 | resolved "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz#3050700dae2e4c8b67c4c3f666cdb8af405e1ce5" |
5338 | integrity sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg== | 5391 | integrity sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg== |
5339 | 5392 | ||
5393 | +printj@~1.1.0, printj@~1.1.2: | ||
5394 | + version "1.1.2" | ||
5395 | + resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" | ||
5396 | + integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== | ||
5397 | + | ||
5340 | process-nextick-args@~2.0.0: | 5398 | process-nextick-args@~2.0.0: |
5341 | version "2.0.1" | 5399 | version "2.0.1" |
5342 | resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" | 5400 | resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" |
@@ -6158,6 +6216,13 @@ sprintf-js@~1.0.2: | @@ -6158,6 +6216,13 @@ sprintf-js@~1.0.2: | ||
6158 | resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" | 6216 | resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" |
6159 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= | 6217 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= |
6160 | 6218 | ||
6219 | +ssf@~0.11.2: | ||
6220 | + version "0.11.2" | ||
6221 | + resolved "https://registry.yarnpkg.com/ssf/-/ssf-0.11.2.tgz#0b99698b237548d088fc43cdf2b70c1a7512c06c" | ||
6222 | + integrity sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g== | ||
6223 | + dependencies: | ||
6224 | + frac "~1.1.2" | ||
6225 | + | ||
6161 | state-toggle@^1.0.0: | 6226 | state-toggle@^1.0.0: |
6162 | version "1.0.3" | 6227 | version "1.0.3" |
6163 | resolved "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" | 6228 | resolved "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" |
@@ -7104,11 +7169,21 @@ which@^2.0.1: | @@ -7104,11 +7169,21 @@ which@^2.0.1: | ||
7104 | dependencies: | 7169 | dependencies: |
7105 | isexe "^2.0.0" | 7170 | isexe "^2.0.0" |
7106 | 7171 | ||
7172 | +wmf@~1.0.1: | ||
7173 | + version "1.0.2" | ||
7174 | + resolved "https://registry.yarnpkg.com/wmf/-/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da" | ||
7175 | + integrity sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw== | ||
7176 | + | ||
7107 | word-wrap@^1.0.3, word-wrap@^1.2.3: | 7177 | word-wrap@^1.0.3, word-wrap@^1.2.3: |
7108 | version "1.2.3" | 7178 | version "1.2.3" |
7109 | resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" | 7179 | resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" |
7110 | integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== | 7180 | integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== |
7111 | 7181 | ||
7182 | +word@~0.3.0: | ||
7183 | + version "0.3.0" | ||
7184 | + resolved "https://registry.yarnpkg.com/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961" | ||
7185 | + integrity sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA== | ||
7186 | + | ||
7112 | wordwrap@^1.0.0: | 7187 | wordwrap@^1.0.0: |
7113 | version "1.0.0" | 7188 | version "1.0.0" |
7114 | resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" | 7189 | resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" |
@@ -7168,6 +7243,21 @@ ws@^7.3.1: | @@ -7168,6 +7243,21 @@ ws@^7.3.1: | ||
7168 | resolved "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" | 7243 | resolved "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" |
7169 | integrity sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA== | 7244 | integrity sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA== |
7170 | 7245 | ||
7246 | +xlsx@^0.16.8: | ||
7247 | + version "0.16.8" | ||
7248 | + resolved "https://registry.yarnpkg.com/xlsx/-/xlsx-0.16.8.tgz#5546de9b0ba15169b36770d4e43b24790d3ff1b8" | ||
7249 | + integrity sha512-qWub4YCn0xLEGHI7WWhk6IJ73MDu7sPSJQImxN6/LiI8wsHi0hUhICEDbyqBT+jgFgORZxrii0HvhNSwBNAPoQ== | ||
7250 | + dependencies: | ||
7251 | + adler-32 "~1.2.0" | ||
7252 | + cfb "^1.1.4" | ||
7253 | + codepage "~1.14.0" | ||
7254 | + commander "~2.17.1" | ||
7255 | + crc-32 "~1.2.0" | ||
7256 | + exit-on-epipe "~1.0.1" | ||
7257 | + ssf "~0.11.2" | ||
7258 | + wmf "~1.0.1" | ||
7259 | + word "~0.3.0" | ||
7260 | + | ||
7171 | xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: | 7261 | xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: |
7172 | version "4.0.2" | 7262 | version "4.0.2" |
7173 | resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" | 7263 | resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" |