zmdms-webui 1.8.2 → 1.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/_virtual/_commonjs-dynamic-modules.js +5 -0
- package/dist/es/_virtual/_commonjsHelpers.js +3 -1
- package/dist/es/_virtual/cpexcel.js +3 -0
- package/dist/es/_virtual/xlsx.min.js +3 -0
- package/dist/es/dynamicsetting/dynamicDrawer.js +0 -1
- package/dist/es/node_modules/xlsx-js-style/dist/cpexcel.js +1518 -0
- package/dist/es/node_modules/xlsx-js-style/dist/xlsx.min.js +16 -0
- package/dist/es/table/excel.js +273 -0
- package/dist/es/table/hooks.js +2 -3
- package/dist/es/table/interface.d.ts +4 -0
- package/dist/es/table/table.js +8 -0
- package/dist/es/table/utils.js +3 -1
- package/package.json +7 -5
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { __spreadArray, __assign } from '../_virtual/_tslib.js';
|
|
2
|
+
import { x as xlsx_minExports } from '../node_modules/xlsx-js-style/dist/xlsx.min.js';
|
|
3
|
+
import { useMergeKeys } from './hooks.js';
|
|
4
|
+
import { useMemo } from 'react';
|
|
5
|
+
import { useMemoizedFn } from 'ahooks';
|
|
6
|
+
import { MERGE_ROW_SPANS } from './constant.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 导出Excel,支持维度合并和小计
|
|
10
|
+
*/
|
|
11
|
+
function exportToExcelWithMerge(records, columns, mergeKeys, summaryKeys, fileName, sheetName, columnHeaders) {
|
|
12
|
+
if (fileName === void 0) { fileName = "export.xlsx"; }
|
|
13
|
+
if (sheetName === void 0) { sheetName = "Sheet1"; }
|
|
14
|
+
if (!records || records.length === 0) {
|
|
15
|
+
throw new Error("没有数据可导出");
|
|
16
|
+
}
|
|
17
|
+
var processedData = records;
|
|
18
|
+
// 2. 准备Excel数据
|
|
19
|
+
var excelData = prepareExcelData(processedData, columns, columnHeaders);
|
|
20
|
+
// 3. 创建工作簿
|
|
21
|
+
var workbook = xlsx_minExports.utils.book_new();
|
|
22
|
+
// 4. 创建工作表
|
|
23
|
+
var worksheet = createWorksheetWithMerge(excelData, mergeKeys);
|
|
24
|
+
// 5. 添加样式(合计行高亮)
|
|
25
|
+
applyExcelStyles(worksheet, excelData.data, mergeKeys, summaryKeys, excelData.columns);
|
|
26
|
+
// 6. 添加工作表到工作簿
|
|
27
|
+
xlsx_minExports.utils.book_append_sheet(workbook, worksheet, sheetName);
|
|
28
|
+
// 7. 导出文件
|
|
29
|
+
xlsx_minExports.writeFile(workbook, fileName, { bookType: "xlsx" });
|
|
30
|
+
return {
|
|
31
|
+
totalRows: excelData.data.length,
|
|
32
|
+
summaryRows: excelData.data.filter(function (row) { return row.__is_summary__; }).length,
|
|
33
|
+
fileName: fileName,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 准备Excel数据
|
|
38
|
+
*/
|
|
39
|
+
function prepareExcelData(processedData, columns, columnHeaders) {
|
|
40
|
+
// 过滤有效的列配置
|
|
41
|
+
var validColumns = columns.filter(function (item) {
|
|
42
|
+
return typeof item.dataIndex === "string" &&
|
|
43
|
+
typeof (item.dynamicTitle || item.title) === "string";
|
|
44
|
+
});
|
|
45
|
+
// 准备表头
|
|
46
|
+
var headers = validColumns.map(function (item) {
|
|
47
|
+
if (typeof item.dataIndex === "string") {
|
|
48
|
+
if (columnHeaders === null || columnHeaders === void 0 ? void 0 : columnHeaders[item.dataIndex]) {
|
|
49
|
+
return columnHeaders[item.dataIndex];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return (item.dynamicTitle || item.title);
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
headers: headers,
|
|
56
|
+
data: processedData,
|
|
57
|
+
columns: validColumns,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 创建带合并单元格的工作表
|
|
62
|
+
*/
|
|
63
|
+
function createWorksheetWithMerge(excelData, mergeKeys) {
|
|
64
|
+
var _a;
|
|
65
|
+
var headers = excelData.headers, data = excelData.data, columns = excelData.columns;
|
|
66
|
+
// 创建工作表数据(包含表头)
|
|
67
|
+
var worksheetData = __spreadArray([
|
|
68
|
+
headers
|
|
69
|
+
], data.map(function (row) {
|
|
70
|
+
return columns.map(function (item) {
|
|
71
|
+
var value = row[item.dataIndex];
|
|
72
|
+
// 处理数值类型
|
|
73
|
+
if (typeof value === "number") {
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
// 处理字符串类型,避免空值
|
|
77
|
+
return value != null ? String(value) : "";
|
|
78
|
+
});
|
|
79
|
+
}), true);
|
|
80
|
+
// 创建工作表
|
|
81
|
+
var worksheet = xlsx_minExports.utils.aoa_to_sheet(worksheetData);
|
|
82
|
+
// 设置列宽
|
|
83
|
+
var columnWidths = columns.map(function (col) {
|
|
84
|
+
var _a;
|
|
85
|
+
return ({
|
|
86
|
+
wch: Math.max(15, ((_a = ((col.dynamicTitle || col.title))) === null || _a === void 0 ? void 0 : _a.length) * 2),
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
worksheet["!cols"] = columnWidths;
|
|
90
|
+
// 添加合并单元格
|
|
91
|
+
var merges = [];
|
|
92
|
+
if (mergeKeys && mergeKeys.length > 0) {
|
|
93
|
+
var _loop_1 = function (colIndex) {
|
|
94
|
+
var mergeKey = mergeKeys[colIndex];
|
|
95
|
+
var excelColIndex = columns.findIndex(function (item) { return item.dataIndex === mergeKey; });
|
|
96
|
+
if (excelColIndex === -1) {
|
|
97
|
+
return "continue";
|
|
98
|
+
}
|
|
99
|
+
for (var rowIndex = 0; rowIndex < data.length; rowIndex++) {
|
|
100
|
+
var rowData = data[rowIndex];
|
|
101
|
+
var spanCount = (_a = rowData[MERGE_ROW_SPANS]) === null || _a === void 0 ? void 0 : _a[mergeKey];
|
|
102
|
+
// 如果合并数量大于1,添加合并单元格
|
|
103
|
+
if (spanCount && spanCount > 1) {
|
|
104
|
+
var mergeRange = {
|
|
105
|
+
s: { r: rowIndex + 1, c: excelColIndex },
|
|
106
|
+
e: { r: rowIndex + spanCount, c: excelColIndex }, // 修复合并范围
|
|
107
|
+
};
|
|
108
|
+
merges.push(mergeRange);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
// 处理每个合并字段
|
|
113
|
+
for (var colIndex = 0; colIndex < mergeKeys.length; colIndex++) {
|
|
114
|
+
_loop_1(colIndex);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
worksheet["!merges"] = merges;
|
|
118
|
+
return worksheet;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 应用Excel样式 - 修复版本
|
|
122
|
+
*/
|
|
123
|
+
function applyExcelStyles(worksheet, data, mergeKeys, summaryKeys, columns) {
|
|
124
|
+
var _a;
|
|
125
|
+
// 修复1:定义样式对象,确保格式正确
|
|
126
|
+
var headerStyle = {
|
|
127
|
+
font: { bold: true, color: { rgb: "FFFFFF" } },
|
|
128
|
+
fill: { patternType: "solid", fgColor: { rgb: "4F81BD" } },
|
|
129
|
+
alignment: { horizontal: "center", vertical: "center" },
|
|
130
|
+
border: {
|
|
131
|
+
top: { style: "thin", color: { rgb: "000000" } },
|
|
132
|
+
bottom: { style: "thin", color: { rgb: "000000" } },
|
|
133
|
+
left: { style: "thin", color: { rgb: "000000" } },
|
|
134
|
+
right: { style: "thin", color: { rgb: "000000" } },
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
var summaryStyle = {
|
|
138
|
+
font: { bold: true, color: { rgb: "000000" } },
|
|
139
|
+
fill: { patternType: "solid", fgColor: { rgb: "E6F3FF" } },
|
|
140
|
+
alignment: { horizontal: "center", vertical: "center" },
|
|
141
|
+
border: {
|
|
142
|
+
top: { style: "thin", color: { rgb: "000000" } },
|
|
143
|
+
bottom: { style: "thin", color: { rgb: "000000" } },
|
|
144
|
+
left: { style: "thin", color: { rgb: "000000" } },
|
|
145
|
+
right: { style: "thin", color: { rgb: "000000" } },
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
var normalStyle = {
|
|
149
|
+
alignment: { horizontal: "center", vertical: "center" },
|
|
150
|
+
border: {
|
|
151
|
+
top: { style: "thin", color: { rgb: "000000" } },
|
|
152
|
+
bottom: { style: "thin", color: { rgb: "000000" } },
|
|
153
|
+
left: { style: "thin", color: { rgb: "000000" } },
|
|
154
|
+
right: { style: "thin", color: { rgb: "000000" } },
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
// 修复2:获取工作表范围,添加默认范围处理
|
|
158
|
+
var range;
|
|
159
|
+
try {
|
|
160
|
+
range = xlsx_minExports.utils.decode_range(worksheet["!ref"] || "A1");
|
|
161
|
+
}
|
|
162
|
+
catch (e) {
|
|
163
|
+
// 如果没有!ref,手动计算范围
|
|
164
|
+
var maxCol = columns ? columns.length - 1 : 0;
|
|
165
|
+
var maxRow = data.length; // +1 for header, but 0-indexed
|
|
166
|
+
range = { s: { r: 0, c: 0 }, e: { r: maxRow, c: maxCol } };
|
|
167
|
+
}
|
|
168
|
+
// 修复3:应用表头样式,确保单元格存在
|
|
169
|
+
for (var col = range.s.c; col <= range.e.c; col++) {
|
|
170
|
+
var cellAddress = xlsx_minExports.utils.encode_cell({ r: 0, c: col });
|
|
171
|
+
// 确保单元格存在
|
|
172
|
+
if (!worksheet[cellAddress]) {
|
|
173
|
+
worksheet[cellAddress] = { v: "", t: "s" };
|
|
174
|
+
}
|
|
175
|
+
// 应用样式
|
|
176
|
+
worksheet[cellAddress].s = headerStyle;
|
|
177
|
+
}
|
|
178
|
+
// 修复4:应用数据行样式
|
|
179
|
+
for (var rowIndex = 0; rowIndex < data.length; rowIndex++) {
|
|
180
|
+
var rowData = data[rowIndex];
|
|
181
|
+
var isSubtotal = rowData.__is_summary__;
|
|
182
|
+
for (var col = range.s.c; col <= range.e.c; col++) {
|
|
183
|
+
var cellAddress = xlsx_minExports.utils.encode_cell({ r: rowIndex + 1, c: col });
|
|
184
|
+
// 确保单元格存在
|
|
185
|
+
if (!worksheet[cellAddress]) {
|
|
186
|
+
worksheet[cellAddress] = { v: "", t: "s" };
|
|
187
|
+
}
|
|
188
|
+
// 应用对应的样式,并根据列配置的对齐方式覆盖水平对齐
|
|
189
|
+
var baseStyle = isSubtotal ? summaryStyle : normalStyle;
|
|
190
|
+
var columnAlign = columns && Array.isArray(columns)
|
|
191
|
+
? (_a = columns[col]) === null || _a === void 0 ? void 0 : _a.align
|
|
192
|
+
: undefined;
|
|
193
|
+
if (columnAlign === "left" ||
|
|
194
|
+
columnAlign === "right" ||
|
|
195
|
+
columnAlign === "center") {
|
|
196
|
+
worksheet[cellAddress].s = __assign(__assign({}, baseStyle), { alignment: __assign(__assign({}, baseStyle.alignment), { horizontal: columnAlign }) });
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
worksheet[cellAddress].s = baseStyle;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// 修复5:设置数值列的格式,确保数值类型正确处理
|
|
204
|
+
if (summaryKeys && summaryKeys.length > 0 && columns) {
|
|
205
|
+
for (var rowIndex = 0; rowIndex < data.length; rowIndex++) {
|
|
206
|
+
var rowData = data[rowIndex];
|
|
207
|
+
var _loop_2 = function (summaryKey) {
|
|
208
|
+
var colIndex = columns.findIndex(function (col) { return col.dataIndex === summaryKey; });
|
|
209
|
+
if (colIndex === -1)
|
|
210
|
+
return "continue";
|
|
211
|
+
var cellAddress = xlsx_minExports.utils.encode_cell({
|
|
212
|
+
r: rowIndex + 1,
|
|
213
|
+
c: colIndex,
|
|
214
|
+
});
|
|
215
|
+
var cellValue = rowData[summaryKey];
|
|
216
|
+
// 确保单元格存在并且值是数字
|
|
217
|
+
if (worksheet[cellAddress] &&
|
|
218
|
+
(typeof cellValue === "number" || !isNaN(Number(cellValue)))) {
|
|
219
|
+
// 确保单元格值是数字类型
|
|
220
|
+
worksheet[cellAddress].v = Number(cellValue);
|
|
221
|
+
worksheet[cellAddress].t = "n"; // 明确设置为数字类型
|
|
222
|
+
// 应用数字格式
|
|
223
|
+
worksheet[cellAddress].z = "#,##0.00"; // 千分位分隔符,保留两位小数
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
for (var _i = 0, summaryKeys_1 = summaryKeys; _i < summaryKeys_1.length; _i++) {
|
|
227
|
+
var summaryKey = summaryKeys_1[_i];
|
|
228
|
+
_loop_2(summaryKey);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// 修复6:确保工作表引用正确
|
|
233
|
+
if (!worksheet["!ref"]) {
|
|
234
|
+
var lastCol = Math.max(0, ((columns === null || columns === void 0 ? void 0 : columns.length) || 1) - 1);
|
|
235
|
+
var lastRow = data.length; // header + data rows
|
|
236
|
+
worksheet["!ref"] = xlsx_minExports.utils.encode_range({
|
|
237
|
+
s: { r: 0, c: 0 },
|
|
238
|
+
e: { r: lastRow, c: lastCol },
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* 导出Excel的简化版本(只提供必要参数)
|
|
244
|
+
*/
|
|
245
|
+
function exportToExcelSimple(records, config) {
|
|
246
|
+
return exportToExcelWithMerge(records, config.columns || [], config.mergeKeys, config.summaryKeys || [], config.fileName || "export.xlsx", config.sheetName || "Sheet1", config.columnHeaders);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* excel导出
|
|
250
|
+
*/
|
|
251
|
+
function useExcelExport(records, config) {
|
|
252
|
+
var columns = config.columns, fileName = config.fileName, isAutoMerge = config.isAutoMerge, columnHeaders = config.columnHeaders;
|
|
253
|
+
// 计算需要合并的字段key集合
|
|
254
|
+
var mergeKeys = useMergeKeys(columns, isAutoMerge);
|
|
255
|
+
// 需要合计的字段
|
|
256
|
+
var summaryKeys = useMemo(function () {
|
|
257
|
+
return columns
|
|
258
|
+
.filter(function (item) { return item.isSummary; })
|
|
259
|
+
.map(function (item) { return item.dataIndex; });
|
|
260
|
+
}, [columns]);
|
|
261
|
+
var exportFunction = useMemoizedFn(function () {
|
|
262
|
+
exportToExcelSimple(records, {
|
|
263
|
+
columns: columns,
|
|
264
|
+
mergeKeys: mergeKeys,
|
|
265
|
+
summaryKeys: summaryKeys,
|
|
266
|
+
fileName: fileName,
|
|
267
|
+
columnHeaders: columnHeaders,
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
return exportFunction;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export { exportToExcelSimple, exportToExcelWithMerge, useExcelExport };
|
package/dist/es/table/hooks.js
CHANGED
|
@@ -337,7 +337,7 @@ var useMergeKeys = function (columns, isAutoMerge) {
|
|
|
337
337
|
if (isAutoMerge) {
|
|
338
338
|
return Array.from(new Set(columns
|
|
339
339
|
.filter(function (item) { return item.isMerge && item.key !== MERGE_INDEX; })
|
|
340
|
-
.map(function (item) { return item.mergeKey || item.key; })));
|
|
340
|
+
.map(function (item) { return (item.mergeKey || item.key); })));
|
|
341
341
|
}
|
|
342
342
|
return undefined;
|
|
343
343
|
}, [isAutoMerge, columns]);
|
|
@@ -469,7 +469,6 @@ function useMergeAddAndDel(_a) {
|
|
|
469
469
|
if (isAutoMerge) {
|
|
470
470
|
return __assign(__assign({}, addAndDelProps), { onCell: function (record) {
|
|
471
471
|
var _a;
|
|
472
|
-
console.log(record, firstMergeKey, "record");
|
|
473
472
|
return {
|
|
474
473
|
rowSpan: (_a = record === null || record === void 0 ? void 0 : record[MERGE_ROW_SPANS]) === null || _a === void 0 ? void 0 : _a[firstMergeKey],
|
|
475
474
|
};
|
|
@@ -480,4 +479,4 @@ function useMergeAddAndDel(_a) {
|
|
|
480
479
|
return [newRowSelection, newAddAndDelProps];
|
|
481
480
|
}
|
|
482
481
|
|
|
483
|
-
export { useAddAndDelChange, useAutoMerge, useCalcScrollY, useCustomSort, useEditChange, useMergeAddAndDel, useMoveRowChange, useScuRfresh };
|
|
482
|
+
export { useAddAndDelChange, useAutoMerge, useCalcScrollY, useCustomSort, useEditChange, useMergeAddAndDel, useMergeKeys, useMoveRowChange, useScuRfresh };
|
package/dist/es/table/table.js
CHANGED
|
@@ -22,6 +22,7 @@ import { HTML5Backend } from '../node_modules/react-dnd-html5-backend/dist/index
|
|
|
22
22
|
import { VList, scrollTo } from '../node_modules/virtuallist-antd/dist/index.es.js';
|
|
23
23
|
import useTableValidate, { tableValidate } from './useTableValidate.js';
|
|
24
24
|
import TitleDirectionColumn from './components/TitleDirectionColumn.js';
|
|
25
|
+
import { useExcelExport } from './excel.js';
|
|
25
26
|
import DynamicSetting from '../dynamicsetting/dynamicSetting.js';
|
|
26
27
|
import { DndProvider } from '../node_modules/react-dnd/dist/core/DndProvider.js';
|
|
27
28
|
|
|
@@ -241,6 +242,12 @@ var Table = function (props) {
|
|
|
241
242
|
}
|
|
242
243
|
return undefined;
|
|
243
244
|
}, [differences]);
|
|
245
|
+
// 导出excel
|
|
246
|
+
var exportExcel = useExcelExport(newDataSource, {
|
|
247
|
+
columns: newColumns,
|
|
248
|
+
isAutoMerge: isAutoMerge,
|
|
249
|
+
fileName: "导出.xlsx",
|
|
250
|
+
});
|
|
244
251
|
// 暴露给外部一些方法
|
|
245
252
|
useImperativeHandle(tableRefHandle, function () {
|
|
246
253
|
return {
|
|
@@ -293,6 +300,7 @@ var Table = function (props) {
|
|
|
293
300
|
var _a, _b;
|
|
294
301
|
(_b = (_a = dynamicSettingRef.current) === null || _a === void 0 ? void 0 : _a.updateList) === null || _b === void 0 ? void 0 : _b.call(_a, list);
|
|
295
302
|
},
|
|
303
|
+
exportExcel: exportExcel,
|
|
296
304
|
};
|
|
297
305
|
});
|
|
298
306
|
// 表格
|
package/dist/es/table/utils.js
CHANGED
|
@@ -456,7 +456,9 @@ function flattenRecordsOptimized(records, mergeKeys, dimensionSummaryKeys, summa
|
|
|
456
456
|
return records;
|
|
457
457
|
}
|
|
458
458
|
// 0. 首先根据维度字段对数据进行排序
|
|
459
|
-
var result =
|
|
459
|
+
var result = (dimensionSummaryKeys === null || dimensionSummaryKeys === void 0 ? void 0 : dimensionSummaryKeys.length) > 0
|
|
460
|
+
? sortByDimensions(__spreadArray([], records, true), mergeKeys)
|
|
461
|
+
: __spreadArray([], records, true);
|
|
460
462
|
// 1. 首先插入维度合计行
|
|
461
463
|
if (dimensionSummaryKeys &&
|
|
462
464
|
dimensionSummaryKeys.length > 0 &&
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zmdms-webui",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "dist/index.es.js",
|
|
6
6
|
"module": "dist/index.es.js",
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
"type": "module",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"peerDependencies": {
|
|
12
|
+
"@tanstack/react-query": ">=5",
|
|
13
|
+
"@tanstack/react-query-devtools": ">=5",
|
|
12
14
|
"ahooks": ">=3.7.8",
|
|
13
15
|
"antd": ">=4.24.8",
|
|
14
16
|
"dayjs": ">=1.11.7",
|
|
@@ -20,9 +22,7 @@
|
|
|
20
22
|
"react-dom": ">=16.8.0",
|
|
21
23
|
"react-resizable": "^3.0.5",
|
|
22
24
|
"react-router-dom": ">=6",
|
|
23
|
-
"zmdms-utils": ">=0.0.1"
|
|
24
|
-
"@tanstack/react-query": ">=5",
|
|
25
|
-
"@tanstack/react-query-devtools": ">=5"
|
|
25
|
+
"zmdms-utils": ">=0.0.1"
|
|
26
26
|
},
|
|
27
27
|
"sideEffects": [
|
|
28
28
|
"dist/es/**/style/*",
|
|
@@ -144,6 +144,8 @@
|
|
|
144
144
|
"react-dnd": "^16.0.1",
|
|
145
145
|
"react-dnd-html5-backend": "^16.0.1",
|
|
146
146
|
"screenfull": "^6.0.2",
|
|
147
|
-
"virtuallist-antd": "^0.8.0-beta.1"
|
|
147
|
+
"virtuallist-antd": "^0.8.0-beta.1",
|
|
148
|
+
"xlsx": "^0.18.5",
|
|
149
|
+
"xlsx-js-style": "^1.2.0"
|
|
148
150
|
}
|
|
149
151
|
}
|