@visactor/vtable-plugins 1.22.8-alpha.13 → 1.22.8

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.
Files changed (75) hide show
  1. package/cjs/excel-import/excel.d.ts +23 -0
  2. package/cjs/excel-import/excel.js +204 -0
  3. package/cjs/excel-import/excel.js.map +1 -0
  4. package/cjs/excel-import/index.d.ts +3 -0
  5. package/cjs/excel-import/index.js +39 -0
  6. package/cjs/excel-import/index.js.map +1 -0
  7. package/cjs/excel-import/types.d.ts +44 -0
  8. package/cjs/excel-import/types.js +6 -0
  9. package/cjs/excel-import/types.js.map +1 -0
  10. package/cjs/excel-import/vtable-sheet.d.ts +2 -0
  11. package/cjs/excel-import/vtable-sheet.js +31 -0
  12. package/cjs/excel-import/vtable-sheet.js.map +1 -0
  13. package/cjs/excel-import.d.ts +12 -22
  14. package/cjs/excel-import.js +107 -40
  15. package/cjs/excel-import.js.map +1 -1
  16. package/cjs/filter/filter-toolbar.d.ts +1 -0
  17. package/cjs/filter/filter-toolbar.js +5 -4
  18. package/cjs/filter/filter-toolbar.js.map +1 -1
  19. package/cjs/filter/index.js +1 -2
  20. package/cjs/filter/value-filter.js +1 -1
  21. package/cjs/filter/value-filter.js.map +1 -1
  22. package/cjs/master-detail-plugin/checkbox.js +1 -0
  23. package/cjs/master-detail-plugin/index.js +1 -1
  24. package/cjs/master-detail-plugin/subtable.js +1 -1
  25. package/cjs/master-detail-plugin/table-api-extensions.js +1 -1
  26. package/cjs/master-detail-plugin/types.js +1 -1
  27. package/cjs/table-export/excel/index.d.ts +4 -0
  28. package/cjs/table-export/excel/index.js +72 -36
  29. package/cjs/table-export/excel/index.js.map +1 -1
  30. package/cjs/table-export/index.d.ts +2 -2
  31. package/cjs/table-export/index.js +6 -1
  32. package/cjs/table-export/index.js.map +1 -1
  33. package/cjs/table-export.js +4 -1
  34. package/cjs/table-export.js.map +1 -1
  35. package/cjs/table-series-number.js +1 -0
  36. package/cjs/table-series-number.js.map +1 -1
  37. package/dist/vtable-plugins.js +591 -122
  38. package/dist/vtable-plugins.min.js +3 -3
  39. package/es/excel-import/excel.d.ts +23 -0
  40. package/es/excel-import/excel.js +190 -0
  41. package/es/excel-import/excel.js.map +1 -0
  42. package/es/excel-import/index.d.ts +3 -0
  43. package/es/excel-import/index.js +4 -0
  44. package/es/excel-import/index.js.map +1 -0
  45. package/es/excel-import/types.d.ts +44 -0
  46. package/es/excel-import/types.js +2 -0
  47. package/es/excel-import/types.js.map +1 -0
  48. package/es/excel-import/vtable-sheet.d.ts +2 -0
  49. package/es/excel-import/vtable-sheet.js +25 -0
  50. package/es/excel-import/vtable-sheet.js.map +1 -0
  51. package/es/excel-import.d.ts +12 -22
  52. package/es/excel-import.js +110 -40
  53. package/es/excel-import.js.map +1 -1
  54. package/es/filter/filter-toolbar.d.ts +1 -0
  55. package/es/filter/filter-toolbar.js +6 -4
  56. package/es/filter/filter-toolbar.js.map +1 -1
  57. package/es/filter/index.js +1 -2
  58. package/es/filter/value-filter.js +1 -1
  59. package/es/filter/value-filter.js.map +1 -1
  60. package/es/master-detail-plugin/checkbox.js +2 -1
  61. package/es/master-detail-plugin/index.js +1 -1
  62. package/es/master-detail-plugin/subtable.js +1 -1
  63. package/es/master-detail-plugin/table-api-extensions.js +1 -1
  64. package/es/master-detail-plugin/types.js +1 -1
  65. package/es/table-export/excel/index.d.ts +4 -0
  66. package/es/table-export/excel/index.js +69 -33
  67. package/es/table-export/excel/index.js.map +1 -1
  68. package/es/table-export/index.d.ts +2 -2
  69. package/es/table-export/index.js +2 -2
  70. package/es/table-export/index.js.map +1 -1
  71. package/es/table-export.js +5 -2
  72. package/es/table-export.js.map +1 -1
  73. package/es/table-series-number.js +1 -0
  74. package/es/table-series-number.js.map +1 -1
  75. package/package.json +8 -8
@@ -0,0 +1,23 @@
1
+ import ExcelJS from 'exceljs';
2
+ import type { ExcelImportOptions, SheetData, MultiSheetImportResult } from './types';
3
+ export declare function importCsvFile(file: File, options?: ExcelImportOptions): Promise<MultiSheetImportResult>;
4
+ export declare function importExcelMultipleSheets(file: File, options?: ExcelImportOptions): Promise<MultiSheetImportResult>;
5
+ export declare function parseWorksheetToSheetData(worksheet: ExcelJS.Worksheet, sheetIndex: number, options?: ExcelImportOptions): Promise<SheetData>;
6
+ export declare function parseMergedCells(worksheet: ExcelJS.Worksheet, data: unknown[][]): Array<{
7
+ text?: string;
8
+ range: {
9
+ start: {
10
+ col: number;
11
+ row: number;
12
+ };
13
+ end: {
14
+ col: number;
15
+ row: number;
16
+ };
17
+ isCustom?: boolean;
18
+ };
19
+ }>;
20
+ export declare function parseCellAddress(address: string): {
21
+ col: number;
22
+ row: number;
23
+ } | null;
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+
3
+ var __awaiter = this && this.__awaiter || function(thisArg, _arguments, P, generator) {
4
+ return new (P || (P = Promise))((function(resolve, reject) {
5
+ function fulfilled(value) {
6
+ try {
7
+ step(generator.next(value));
8
+ } catch (e) {
9
+ reject(e);
10
+ }
11
+ }
12
+ function rejected(value) {
13
+ try {
14
+ step(generator.throw(value));
15
+ } catch (e) {
16
+ reject(e);
17
+ }
18
+ }
19
+ function step(result) {
20
+ var value;
21
+ result.done ? resolve(result.value) : (value = result.value, value instanceof P ? value : new P((function(resolve) {
22
+ resolve(value);
23
+ }))).then(fulfilled, rejected);
24
+ }
25
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
26
+ }));
27
+ }, __importDefault = this && this.__importDefault || function(mod) {
28
+ return mod && mod.__esModule ? mod : {
29
+ default: mod
30
+ };
31
+ };
32
+
33
+ Object.defineProperty(exports, "__esModule", {
34
+ value: !0
35
+ }), exports.parseCellAddress = exports.parseMergedCells = exports.parseWorksheetToSheetData = exports.importExcelMultipleSheets = exports.importCsvFile = void 0;
36
+
37
+ const exceljs_1 = __importDefault(require("exceljs"));
38
+
39
+ function importCsvFile(file, options) {
40
+ return __awaiter(this, void 0, void 0, (function*() {
41
+ const text = yield file.text(), delimiter = (null == options ? void 0 : options.delimiter) || ",", lines = text.split(/\r?\n/).filter((line => line.trim().length > 0));
42
+ if (0 === lines.length) throw new Error("CSV 文件为空");
43
+ const data = [];
44
+ for (const line of lines) {
45
+ const row = parseCsvLine(line, delimiter);
46
+ data.push(row);
47
+ }
48
+ const rowCount = data.length, columnCount = Math.max(...data.map((row => row.length)), 0);
49
+ return {
50
+ sheets: [ {
51
+ sheetTitle: file.name.replace(/\.(csv|txt)$/i, "") || "Sheet1",
52
+ sheetKey: `sheet_${Date.now()}_0`,
53
+ data: data,
54
+ columnCount: columnCount,
55
+ rowCount: rowCount
56
+ } ]
57
+ };
58
+ }));
59
+ }
60
+
61
+ function parseCsvLine(line, delimiter) {
62
+ const result = [];
63
+ let current = "", inQuotes = !1;
64
+ for (let i = 0; i < line.length; i++) {
65
+ const char = line[i], nextChar = line[i + 1];
66
+ '"' === char ? inQuotes && '"' === nextChar ? (current += '"', i++) : inQuotes = !inQuotes : char !== delimiter || inQuotes ? current += char : (result.push(current.trim()),
67
+ current = "");
68
+ }
69
+ return result.push(current.trim()), result;
70
+ }
71
+
72
+ function importExcelMultipleSheets(file, options) {
73
+ return __awaiter(this, void 0, void 0, (function*() {
74
+ const workbook = new exceljs_1.default.Workbook;
75
+ if (yield workbook.xlsx.load(yield file.arrayBuffer()), !workbook.worksheets || 0 === workbook.worksheets.length) throw new Error("Excel 文件无有效工作表");
76
+ let sheetIndices;
77
+ sheetIndices = (null == options ? void 0 : options.sheetIndices) && options.sheetIndices.length > 0 ? options.sheetIndices.filter((index => index >= 0 && index < workbook.worksheets.length)) : Array.from({
78
+ length: workbook.worksheets.length
79
+ }, ((_, i) => i));
80
+ const sheets = [];
81
+ for (const sheetIndex of sheetIndices) {
82
+ const worksheet = workbook.worksheets[sheetIndex];
83
+ if (worksheet) try {
84
+ const sheetData = yield parseWorksheetToSheetData(worksheet, sheetIndex, options);
85
+ sheets.push(sheetData);
86
+ } catch (error) {}
87
+ }
88
+ if (0 === sheets.length) throw new Error("没有成功解析任何工作表");
89
+ return {
90
+ sheets: sheets
91
+ };
92
+ }));
93
+ }
94
+
95
+ function parseWorksheetToSheetData(worksheet, sheetIndex, options) {
96
+ return __awaiter(this, void 0, void 0, (function*() {
97
+ const sheetTitle = worksheet.name || `Sheet${sheetIndex + 1}`, sheetKey = `sheet_${Date.now()}_${sheetIndex}`, rowCount = worksheet.actualRowCount || 0, columnCount = worksheet.actualColumnCount || 0;
98
+ if (0 === rowCount || 0 === columnCount) {
99
+ const cellMerge = parseMergedCells(worksheet, []);
100
+ return Object.assign({
101
+ sheetTitle: sheetTitle,
102
+ sheetKey: sheetKey,
103
+ data: [],
104
+ columnCount: 0,
105
+ rowCount: 0
106
+ }, cellMerge.length > 0 ? {
107
+ cellMerge: cellMerge
108
+ } : {});
109
+ }
110
+ const data = [];
111
+ for (let rowNumber = 1; rowNumber <= rowCount; rowNumber++) {
112
+ const row = worksheet.getRow(rowNumber), rowData = [];
113
+ for (let colNumber = 1; colNumber <= columnCount; colNumber++) {
114
+ let cellValue = row.getCell(colNumber).value;
115
+ cellValue && "object" == typeof cellValue && ("richText" in cellValue ? cellValue = cellValue.richText.map((rt => rt.text)).join("") : "result" in cellValue ? cellValue = cellValue.result : "text" in cellValue && "hyperlink" in cellValue ? cellValue = cellValue.text : cellValue instanceof Date && (cellValue = cellValue.toISOString())),
116
+ rowData.push(null != cellValue ? cellValue : null);
117
+ }
118
+ data.push(rowData);
119
+ }
120
+ const cellMerge = parseMergedCells(worksheet, data);
121
+ return Object.assign({
122
+ sheetTitle: sheetTitle,
123
+ sheetKey: sheetKey,
124
+ data: data,
125
+ columnCount: columnCount,
126
+ rowCount: rowCount
127
+ }, cellMerge.length > 0 ? {
128
+ cellMerge: cellMerge
129
+ } : {});
130
+ }));
131
+ }
132
+
133
+ function parseMergedCells(worksheet, data) {
134
+ var _a;
135
+ const cellMerge = [];
136
+ try {
137
+ const worksheetAny = worksheet, merges = (null === (_a = worksheetAny.model) || void 0 === _a ? void 0 : _a.merges) || worksheetAny._merges || {};
138
+ for (const [masterCell, range] of Object.entries(merges)) try {
139
+ let startCol, startRow, endCol, endRow, text;
140
+ if ("string" == typeof range) {
141
+ const rangeMatch = range.match(/^([A-Z]+\d+):([A-Z]+\d+)$/i);
142
+ if (!rangeMatch) continue;
143
+ const startAddr = parseCellAddress(rangeMatch[1]), endAddr = parseCellAddress(rangeMatch[2]);
144
+ if (!startAddr || !endAddr) continue;
145
+ startCol = startAddr.col, startRow = startAddr.row, endCol = endAddr.col, endRow = endAddr.row;
146
+ } else {
147
+ if ("object" != typeof range || null === range) continue;
148
+ {
149
+ const rangeObj = range;
150
+ if (rangeObj.tl && rangeObj.br) {
151
+ const startAddr = parseCellAddress(rangeObj.tl), endAddr = parseCellAddress(rangeObj.br);
152
+ if (!startAddr || !endAddr) continue;
153
+ startCol = startAddr.col, startRow = startAddr.row, endCol = endAddr.col, endRow = endAddr.row;
154
+ } else {
155
+ if ("number" != typeof rangeObj.top || "number" != typeof rangeObj.left || "number" != typeof rangeObj.bottom || "number" != typeof rangeObj.right) continue;
156
+ startRow = rangeObj.top - 1, startCol = rangeObj.left - 1, endRow = rangeObj.bottom - 1,
157
+ endCol = rangeObj.right - 1;
158
+ }
159
+ }
160
+ }
161
+ if (startRow >= 0 && startRow < data.length && startCol >= 0 && startCol < data[startRow].length) {
162
+ const cellValue = data[startRow][startCol];
163
+ null != cellValue && (text = String(cellValue));
164
+ }
165
+ cellMerge.push({
166
+ text: text,
167
+ range: {
168
+ start: {
169
+ col: startCol,
170
+ row: startRow
171
+ },
172
+ end: {
173
+ col: endCol,
174
+ row: endRow
175
+ },
176
+ isCustom: !0
177
+ }
178
+ });
179
+ } catch (error) {}
180
+ } catch (error) {}
181
+ return cellMerge;
182
+ }
183
+
184
+ function parseCellAddress(address) {
185
+ try {
186
+ const match = address.match(/^([A-Z]+)(\d+)$/i);
187
+ if (!match) return null;
188
+ const colLetters = match[1].toUpperCase(), rowNumber = parseInt(match[2], 10);
189
+ let col = 0;
190
+ for (let i = 0; i < colLetters.length; i++) col = 26 * col + (colLetters.charCodeAt(i) - 64);
191
+ col -= 1;
192
+ return {
193
+ col: col,
194
+ row: rowNumber - 1
195
+ };
196
+ } catch (error) {
197
+ return null;
198
+ }
199
+ }
200
+
201
+ exports.importCsvFile = importCsvFile, exports.importExcelMultipleSheets = importExcelMultipleSheets,
202
+ exports.parseWorksheetToSheetData = parseWorksheetToSheetData, exports.parseMergedCells = parseMergedCells,
203
+ exports.parseCellAddress = parseCellAddress;
204
+ //# sourceMappingURL=excel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/excel-import/excel.ts"],"names":[],"mappings":"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","file":"excel.js","sourcesContent":["import ExcelJS from 'exceljs';\nimport type { ExcelImportOptions, SheetData, MultiSheetImportResult } from './types';\n\n/**\n * 解析 CSV 文件为 SheetData 格式\n * @param file CSV 文件\n * @param options 导入选项\n * @returns Promise<MultiSheetImportResult>\n */\nexport async function importCsvFile(file: File, options?: ExcelImportOptions): Promise<MultiSheetImportResult> {\n const text = await file.text();\n const delimiter = options?.delimiter || ',';\n const lines = text.split(/\\r?\\n/).filter(line => line.trim().length > 0);\n\n if (lines.length === 0) {\n throw new Error('CSV 文件为空');\n }\n\n // 解析 CSV 数据\n const data: unknown[][] = [];\n for (const line of lines) {\n const row = parseCsvLine(line, delimiter);\n data.push(row);\n }\n\n // 确定行列数\n const rowCount = data.length;\n const columnCount = Math.max(...data.map(row => row.length), 0);\n\n // 生成 sheet 信息\n const sheetTitle = file.name.replace(/\\.(csv|txt)$/i, '') || 'Sheet1';\n const sheetKey = `sheet_${Date.now()}_0`;\n\n const sheetData: SheetData = {\n sheetTitle,\n sheetKey,\n data,\n columnCount,\n rowCount\n };\n\n return {\n sheets: [sheetData]\n };\n}\n\n/**\n * 解析 CSV 行(处理引号内的分隔符)\n * @param line CSV 行\n * @param delimiter 分隔符\n * @returns 解析后的单元格值数组\n */\nfunction parseCsvLine(line: string, delimiter: string): unknown[] {\n const result: unknown[] = [];\n let current = '';\n let inQuotes = false;\n\n for (let i = 0; i < line.length; i++) {\n const char = line[i];\n const nextChar = line[i + 1];\n\n if (char === '\"') {\n if (inQuotes && nextChar === '\"') {\n // 转义的双引号\n current += '\"';\n i++; // 跳过下一个引号\n } else {\n // 切换引号状态\n inQuotes = !inQuotes;\n }\n } else if (char === delimiter && !inQuotes) {\n // 分隔符(不在引号内)\n result.push(current.trim());\n current = '';\n } else {\n current += char;\n }\n }\n\n // 添加最后一个字段\n result.push(current.trim());\n\n return result;\n}\n\n/**\n * 解析 Excel 文件的多个 sheet\n * @param file Excel 文件\n * @param options 导入选项\n * @returns Promise<MultiSheetImportResult>\n */\nexport async function importExcelMultipleSheets(\n file: File,\n options?: ExcelImportOptions\n): Promise<MultiSheetImportResult> {\n const workbook = new ExcelJS.Workbook();\n await workbook.xlsx.load(await file.arrayBuffer());\n\n if (!workbook.worksheets || workbook.worksheets.length === 0) {\n throw new Error('Excel 文件无有效工作表');\n }\n\n // 确定要导入的 sheet 索引\n let sheetIndices: number[];\n if (options?.sheetIndices && options.sheetIndices.length > 0) {\n // 使用指定的 sheet 索引\n sheetIndices = options.sheetIndices.filter(index => index >= 0 && index < workbook.worksheets.length);\n } else {\n // 导入所有 sheet\n sheetIndices = Array.from({ length: workbook.worksheets.length }, (_, i) => i);\n }\n\n const sheets: SheetData[] = [];\n\n // 处理每个 sheet\n for (const sheetIndex of sheetIndices) {\n const worksheet = workbook.worksheets[sheetIndex];\n if (!worksheet) {\n continue;\n }\n\n try {\n const sheetData = await parseWorksheetToSheetData(worksheet, sheetIndex, options);\n sheets.push(sheetData);\n } catch (error) {\n console.error(`解析 sheet \"${worksheet.name}\" 时出错:`, error);\n // 继续处理其他 sheet\n }\n }\n\n if (sheets.length === 0) {\n throw new Error('没有成功解析任何工作表');\n }\n\n return { sheets };\n}\n\n/**\n * 解析单个 worksheet 为 SheetData 格式\n * @param worksheet ExcelJS worksheet 对象\n * @param sheetIndex sheet 索引\n * @param options 导入选项\n * @returns Promise<SheetData>\n */\nexport async function parseWorksheetToSheetData(\n worksheet: ExcelJS.Worksheet,\n sheetIndex: number,\n options?: ExcelImportOptions\n): Promise<SheetData> {\n const sheetTitle = worksheet.name || `Sheet${sheetIndex + 1}`;\n const sheetKey = `sheet_${Date.now()}_${sheetIndex}`;\n\n // 获取实际数据范围\n const rowCount = worksheet.actualRowCount || 0;\n const columnCount = worksheet.actualColumnCount || 0;\n\n if (rowCount === 0 || columnCount === 0) {\n // 空 sheet,但仍需要解析合并单元格信息(可能只有合并单元格没有数据)\n const cellMerge = parseMergedCells(worksheet, []);\n return {\n sheetTitle,\n sheetKey,\n data: [],\n columnCount: 0,\n rowCount: 0,\n ...(cellMerge.length > 0 ? { cellMerge } : {})\n };\n }\n\n // 提取所有数据(包括表头)为二维数组\n const data: unknown[][] = [];\n\n for (let rowNumber = 1; rowNumber <= rowCount; rowNumber++) {\n const row = worksheet.getRow(rowNumber);\n const rowData: unknown[] = [];\n\n for (let colNumber = 1; colNumber <= columnCount; colNumber++) {\n const cell = row.getCell(colNumber);\n let cellValue: unknown = cell.value;\n\n // 处理特殊的单元格值类型\n if (cellValue && typeof cellValue === 'object') {\n // 处理富文本\n if ('richText' in cellValue) {\n cellValue = (cellValue as { richText: { text: string }[] }).richText\n .map((rt: { text: string }) => rt.text)\n .join('');\n }\n // 处理公式\n else if ('result' in cellValue) {\n cellValue = (cellValue as { result: unknown }).result;\n }\n // 处理超链接\n else if ('text' in cellValue && 'hyperlink' in cellValue) {\n cellValue = (cellValue as { text: string }).text;\n }\n // 处理日期\n else if (cellValue instanceof Date) {\n cellValue = cellValue.toISOString();\n }\n }\n\n rowData.push(cellValue ?? null);\n }\n\n data.push(rowData);\n }\n\n // 解析合并单元格信息\n const cellMerge = parseMergedCells(worksheet, data);\n\n return {\n sheetTitle,\n sheetKey,\n data,\n columnCount,\n rowCount,\n ...(cellMerge.length > 0 ? { cellMerge } : {})\n };\n}\n\n/**\n * 解析 Excel 合并单元格信息\n * @param worksheet ExcelJS worksheet 对象\n * @param data 已解析的数据数组\n * @returns 合并单元格信息数组\n */\nexport function parseMergedCells(\n worksheet: ExcelJS.Worksheet,\n data: unknown[][]\n): Array<{\n text?: string;\n range: {\n start: { col: number; row: number };\n end: { col: number; row: number };\n isCustom?: boolean;\n };\n}> {\n const cellMerge: Array<{\n text?: string;\n range: {\n start: { col: number; row: number };\n end: { col: number; row: number };\n isCustom?: boolean;\n };\n }> = [];\n\n try {\n // ExcelJS 中合并单元格信息存储在 worksheet.model.merges 中\n // 格式: { 'A1': { tl: 'A1', br: 'B2' }, ... }\n // 注意:ExcelJS 的类型定义可能不完整,使用 unknown 进行类型转换\n const worksheetAny = worksheet as unknown as {\n model?: { merges?: Record<string, unknown> };\n _merges?: Record<string, unknown>;\n };\n const merges: Record<string, unknown> =\n (worksheetAny.model?.merges as Record<string, unknown>) ||\n (worksheetAny._merges as Record<string, unknown>) ||\n {};\n\n for (const [masterCell, range] of Object.entries(merges)) {\n try {\n let startCol: number;\n let startRow: number;\n let endCol: number;\n let endRow: number;\n\n // 检查 range 的类型\n if (typeof range === 'string') {\n // range 是地址范围字符串,如 'A1:B3'\n const rangeMatch = range.match(/^([A-Z]+\\d+):([A-Z]+\\d+)$/i);\n if (!rangeMatch) {\n continue;\n }\n\n const startAddr = parseCellAddress(rangeMatch[1]);\n const endAddr = parseCellAddress(rangeMatch[2]);\n if (!startAddr || !endAddr) {\n continue;\n }\n\n startCol = startAddr.col;\n startRow = startAddr.row;\n endCol = endAddr.col;\n endRow = endAddr.row;\n } else if (typeof range === 'object' && range !== null) {\n // range 是对象格式\n const rangeObj = range as {\n tl?: string;\n br?: string;\n top?: number;\n left?: number;\n bottom?: number;\n right?: number;\n };\n\n if (rangeObj.tl && rangeObj.br) {\n // 使用地址字符串格式 (如 'A1', 'B2')\n const startAddr = parseCellAddress(rangeObj.tl);\n const endAddr = parseCellAddress(rangeObj.br);\n if (!startAddr || !endAddr) {\n continue;\n }\n\n startCol = startAddr.col;\n startRow = startAddr.row;\n endCol = endAddr.col;\n endRow = endAddr.row;\n } else if (\n typeof rangeObj.top === 'number' &&\n typeof rangeObj.left === 'number' &&\n typeof rangeObj.bottom === 'number' &&\n typeof rangeObj.right === 'number'\n ) {\n // 使用行列索引格式(ExcelJS 内部格式,1-based)\n startRow = rangeObj.top - 1; // 转换为 0-based\n startCol = rangeObj.left - 1; // 转换为 0-based\n endRow = rangeObj.bottom - 1; // 转换为 0-based\n endCol = rangeObj.right - 1; // 转换为 0-based\n } else {\n continue;\n }\n } else {\n continue;\n }\n\n // 获取合并单元格的文本内容(从主单元格)\n let text: string | undefined;\n if (startRow >= 0 && startRow < data.length && startCol >= 0 && startCol < data[startRow].length) {\n const cellValue = data[startRow][startCol];\n if (cellValue !== null && cellValue !== undefined) {\n text = String(cellValue);\n }\n }\n\n cellMerge.push({\n text,\n range: {\n start: {\n col: startCol,\n row: startRow\n },\n end: {\n col: endCol,\n row: endRow\n },\n isCustom: true\n }\n });\n } catch (error) {\n console.warn(`解析合并单元格 ${masterCell} 时出错:`, error);\n // 继续处理其他合并单元格\n }\n }\n } catch (error) {\n console.warn('解析合并单元格信息时出错:', error);\n }\n\n return cellMerge;\n}\n\n/**\n * 解析单元格地址(如 'A1')为行列索引(0-based)\n * @param address 单元格地址字符串\n * @returns 行列索引对象,解析失败返回 null\n */\nexport function parseCellAddress(address: string): { col: number; row: number } | null {\n try {\n // 匹配格式:列字母 + 行号,如 'A1', 'B2', 'AA10'\n const match = address.match(/^([A-Z]+)(\\d+)$/i);\n if (!match) {\n return null;\n }\n\n const colLetters = match[1].toUpperCase();\n const rowNumber = parseInt(match[2], 10);\n\n // 转换列字母为索引 (A=0, B=1, ..., Z=25, AA=26, etc.)\n // Excel 列是 26 进制,但特殊的是没有 0,A=1, Z=26, AA=27\n let col = 0;\n for (let i = 0; i < colLetters.length; i++) {\n col = col * 26 + (colLetters.charCodeAt(i) - 64); // 'A' = 65, 所以 -64 得到 1\n }\n col = col - 1; // 转换为 0-based (A=1->0, B=2->1, ..., AA=27->26)\n\n // 行号转换为 0-based(Excel 使用 1-based)\n const row = rowNumber - 1;\n\n return { col, row };\n } catch (error) {\n console.warn(`解析单元格地址 \"${address}\" 时出错:`, error);\n return null;\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export { importCsvFile, parseWorksheetToSheetData, parseMergedCells, parseCellAddress } from './excel';
2
+ export { applyImportToVTableSheet } from './vtable-sheet';
3
+ export type { ExcelImportOptions, SheetData, MultiSheetImportResult, ImportResult } from './types';
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: !0
5
+ }), exports.applyImportToVTableSheet = exports.parseCellAddress = exports.parseMergedCells = exports.parseWorksheetToSheetData = exports.importCsvFile = void 0;
6
+
7
+ var excel_1 = require("./excel");
8
+
9
+ Object.defineProperty(exports, "importCsvFile", {
10
+ enumerable: !0,
11
+ get: function() {
12
+ return excel_1.importCsvFile;
13
+ }
14
+ }), Object.defineProperty(exports, "parseWorksheetToSheetData", {
15
+ enumerable: !0,
16
+ get: function() {
17
+ return excel_1.parseWorksheetToSheetData;
18
+ }
19
+ }), Object.defineProperty(exports, "parseMergedCells", {
20
+ enumerable: !0,
21
+ get: function() {
22
+ return excel_1.parseMergedCells;
23
+ }
24
+ }), Object.defineProperty(exports, "parseCellAddress", {
25
+ enumerable: !0,
26
+ get: function() {
27
+ return excel_1.parseCellAddress;
28
+ }
29
+ });
30
+
31
+ var vtable_sheet_1 = require("./vtable-sheet");
32
+
33
+ Object.defineProperty(exports, "applyImportToVTableSheet", {
34
+ enumerable: !0,
35
+ get: function() {
36
+ return vtable_sheet_1.applyImportToVTableSheet;
37
+ }
38
+ });
39
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/excel-import/index.ts"],"names":[],"mappings":";;;AAAA,iCAAuG;AAA9F,sGAAA,aAAa,OAAA;AAAE,kHAAA,yBAAyB,OAAA;AAAE,yGAAA,gBAAgB,OAAA;AAAE,yGAAA,gBAAgB,OAAA;AACrF,+CAA0D;AAAjD,wHAAA,wBAAwB,OAAA","file":"index.js","sourcesContent":["export { importCsvFile, parseWorksheetToSheetData, parseMergedCells, parseCellAddress } from './excel';\nexport { applyImportToVTableSheet } from './vtable-sheet';\nexport type { ExcelImportOptions, SheetData, MultiSheetImportResult, ImportResult } from './types';\n"]}
@@ -0,0 +1,44 @@
1
+ import type { ColumnsDefine } from '@visactor/vtable';
2
+ export interface ImportResult {
3
+ columns: ColumnsDefine;
4
+ records: Record<string, unknown>[];
5
+ }
6
+ export interface SheetData {
7
+ sheetTitle: string;
8
+ sheetKey: string;
9
+ columns?: ColumnsDefine;
10
+ data: unknown[][];
11
+ columnCount: number;
12
+ rowCount: number;
13
+ cellMerge?: Array<{
14
+ text?: string;
15
+ range: {
16
+ start: {
17
+ col: number;
18
+ row: number;
19
+ };
20
+ end: {
21
+ col: number;
22
+ row: number;
23
+ };
24
+ isCustom?: boolean;
25
+ };
26
+ }>;
27
+ }
28
+ export interface MultiSheetImportResult {
29
+ sheets: SheetData[];
30
+ }
31
+ export interface ExcelImportOptions {
32
+ id?: string;
33
+ headerRowCount?: number;
34
+ exportData?: boolean;
35
+ autoTable?: boolean;
36
+ autoColumns?: boolean;
37
+ delimiter?: string;
38
+ batchSize?: number;
39
+ enableBatchProcessing?: boolean;
40
+ asyncDelay?: number;
41
+ importAllSheets?: boolean;
42
+ sheetIndices?: number[];
43
+ clearExisting?: boolean;
44
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: !0
5
+ });
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/excel-import/types.ts"],"names":[],"mappings":"","file":"types.js","sourcesContent":["import type { ColumnsDefine } from '@visactor/vtable';\n\n// 数据导入结果类型(单个sheet)\nexport interface ImportResult {\n columns: ColumnsDefine;\n records: Record<string, unknown>[];\n}\n\n// 单个 sheet 的数据结构(用于多 sheet 导入)\nexport interface SheetData {\n /** sheet 名称 */\n sheetTitle: string;\n /** sheet 唯一标识(自动生成) */\n sheetKey: string;\n /** 列定义 */\n columns?: ColumnsDefine;\n /** 数据 (二维数组格式,用于 VTable-sheet) */\n data: unknown[][];\n /** 列数 */\n columnCount: number;\n /** 行数 */\n rowCount: number;\n /** 单元格合并信息 */\n cellMerge?: Array<{\n text?: string;\n range: {\n start: {\n col: number;\n row: number;\n };\n end: {\n col: number;\n row: number;\n };\n isCustom?: boolean;\n };\n }>;\n}\n\n// 多 sheet 导入结果类型\nexport interface MultiSheetImportResult {\n /** 所有 sheet 的数据 */\n sheets: SheetData[];\n}\n\nexport interface ExcelImportOptions {\n id?: string;\n headerRowCount?: number; // 指定头的层数,不指定会使用detectHeaderRowCount来自动判断,但是只有excel才有\n exportData?: boolean; // 是否导出JavaScript对象字面量格式文件\n autoTable?: boolean; // 是否自动替换表格数据\n autoColumns?: boolean; // 是否自动生成列配置\n delimiter?: string; // CSV分隔符,默认逗号\n batchSize?: number; // 批处理大小,默认1000行\n enableBatchProcessing?: boolean; // 是否启用分批处理,默认true\n asyncDelay?: number; // 异步处理延迟时间(ms),默认5ms\n importAllSheets?: boolean; // 是否导入所有sheet,默认false(仅导入第一个sheet)\n sheetIndices?: number[]; // 指定要导入的sheet索引数组(从0开始),不指定则导入所有\n clearExisting?: boolean; // 对于 VTable-sheet:是否清除现有 sheets(true=替换,false=追加),默认 true\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import type { ExcelImportOptions, MultiSheetImportResult } from './types';
2
+ export declare function applyImportToVTableSheet(vtableSheetInstance: any, result: MultiSheetImportResult, options?: ExcelImportOptions): void;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ function applyImportToVTableSheet(vtableSheetInstance, result, options) {
4
+ const clearExisting = !1 !== (null == options ? void 0 : options.clearExisting);
5
+ if (0 === result.sheets.length) return;
6
+ if ("function" != typeof vtableSheetInstance.addSheet) throw new Error("VTableSheet 实例方法不完整");
7
+ const existingSheetKeys = (clearExisting ? [ ...vtableSheetInstance.getAllSheets() ] : []).map((s => s.sheetKey)), importedSheetKeys = [];
8
+ for (let i = 0; i < result.sheets.length; i++) {
9
+ const sheetData = result.sheets[i];
10
+ let sheetKey = sheetData.sheetKey, suffix = 1;
11
+ for (;vtableSheetInstance.getSheet(sheetKey) || importedSheetKeys.includes(sheetKey); ) sheetKey = `${sheetData.sheetKey}_${suffix}`,
12
+ suffix++;
13
+ const sheetDefine = {
14
+ sheetKey: sheetKey,
15
+ sheetTitle: sheetData.sheetTitle,
16
+ data: sheetData.data,
17
+ rowCount: Math.max(sheetData.rowCount, 100),
18
+ columnCount: Math.max(sheetData.columnCount, 26),
19
+ cellMerge: sheetData.cellMerge,
20
+ active: !1
21
+ };
22
+ vtableSheetInstance.addSheet(sheetDefine), importedSheetKeys.push(sheetKey);
23
+ }
24
+ if (clearExisting && existingSheetKeys.length > 0) for (const oldSheetKey of existingSheetKeys) importedSheetKeys.includes(oldSheetKey) || vtableSheetInstance.getSheet(oldSheetKey) && vtableSheetInstance.getSheetCount() > 1 && vtableSheetInstance.removeSheet(oldSheetKey);
25
+ importedSheetKeys.length > 0 && vtableSheetInstance.activateSheet(importedSheetKeys[0]);
26
+ }
27
+
28
+ Object.defineProperty(exports, "__esModule", {
29
+ value: !0
30
+ }), exports.applyImportToVTableSheet = void 0, exports.applyImportToVTableSheet = applyImportToVTableSheet;
31
+ //# sourceMappingURL=vtable-sheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/excel-import/vtable-sheet.ts"],"names":[],"mappings":";;;AAQA,SAAgB,wBAAwB,CACtC,mBAAwB,EACxB,MAA8B,EAC9B,OAA4B;IAE5B,MAAM,aAAa,GAAG,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,aAAa,MAAK,KAAK,CAAC;IAEvD,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;QAC9B,OAAO;KACR;IAGD,IAAI,OAAO,mBAAmB,CAAC,QAAQ,KAAK,UAAU,EAAE;QACtD,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;KACxC;IAGD,MAAM,cAAc,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpF,MAAM,iBAAiB,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAuB,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAGtF,MAAM,iBAAiB,GAAa,EAAE,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QAC7C,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAGnC,IAAI,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;QAClC,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,OAAO,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;YACrF,QAAQ,GAAG,GAAG,SAAS,CAAC,QAAQ,IAAI,MAAM,EAAE,CAAC;YAC7C,MAAM,EAAE,CAAC;SACV;QAGD,MAAM,WAAW,GAAG;YAClB,QAAQ,EAAE,QAAQ;YAClB,UAAU,EAAE,SAAS,CAAC,UAAU;YAChC,IAAI,EAAE,SAAS,CAAC,IAAI;YACpB,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC;YAC3C,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;YAChD,SAAS,EAAE,SAAS,CAAC,SAAS;YAC9B,MAAM,EAAE,KAAK;SACd,CAAC;QAGF,mBAAmB,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC1C,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;KAClC;IAGD,IAAI,aAAa,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE;QACjD,KAAK,MAAM,WAAW,IAAI,iBAAiB,EAAE;YAE3C,IAAI,iBAAiB,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE;gBAC3C,SAAS;aACV;YAED,IAAI,mBAAmB,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,mBAAmB,CAAC,aAAa,EAAE,GAAG,CAAC,EAAE;gBACxF,mBAAmB,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;aAC9C;SACF;KACF;IAGD,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE;QAChC,mBAAmB,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;KACzD;AACH,CAAC;AAnED,4DAmEC","file":"vtable-sheet.js","sourcesContent":["import type { ExcelImportOptions, MultiSheetImportResult, SheetData } from './types';\n\n/**\n * 将导入的 Excel 数据应用到 VTableSheet 实例\n * @param vtableSheetInstance VTableSheet 实例\n * @param result 导入结果\n * @param options 导入选项\n */\nexport function applyImportToVTableSheet(\n vtableSheetInstance: any,\n result: MultiSheetImportResult,\n options?: ExcelImportOptions\n): void {\n const clearExisting = options?.clearExisting !== false; // 默认 true(替换模式)\n\n if (result.sheets.length === 0) {\n return;\n }\n\n // 验证实例是否有必要的方法\n if (typeof vtableSheetInstance.addSheet !== 'function') {\n throw new Error('VTableSheet 实例方法不完整');\n }\n\n // 记录现有的 sheets(用于替换模式)\n const existingSheets = clearExisting ? [...vtableSheetInstance.getAllSheets()] : [];\n const existingSheetKeys = existingSheets.map((s: { sheetKey: string }) => s.sheetKey);\n\n // 转换并添加导入的 sheets\n const importedSheetKeys: string[] = [];\n for (let i = 0; i < result.sheets.length; i++) {\n const sheetData = result.sheets[i];\n\n // 确保 sheetKey 唯一\n let sheetKey = sheetData.sheetKey;\n let suffix = 1;\n while (vtableSheetInstance.getSheet(sheetKey) || importedSheetKeys.includes(sheetKey)) {\n sheetKey = `${sheetData.sheetKey}_${suffix}`;\n suffix++;\n }\n\n // 创建 sheet 定义\n const sheetDefine = {\n sheetKey: sheetKey,\n sheetTitle: sheetData.sheetTitle,\n data: sheetData.data,\n rowCount: Math.max(sheetData.rowCount, 100),\n columnCount: Math.max(sheetData.columnCount, 26),\n cellMerge: sheetData.cellMerge,\n active: false // 稍后统一激活\n };\n\n // 添加 sheet\n vtableSheetInstance.addSheet(sheetDefine);\n importedSheetKeys.push(sheetKey);\n }\n\n // 替换模式:移除所有旧的 sheets\n if (clearExisting && existingSheetKeys.length > 0) {\n for (const oldSheetKey of existingSheetKeys) {\n // 跳过新添加的 sheet,只删除旧的\n if (importedSheetKeys.includes(oldSheetKey)) {\n continue;\n }\n // 检查是否还存在且可以安全删除\n if (vtableSheetInstance.getSheet(oldSheetKey) && vtableSheetInstance.getSheetCount() > 1) {\n vtableSheetInstance.removeSheet(oldSheetKey);\n }\n }\n }\n\n // 激活第一个导入的 sheet\n if (importedSheetKeys.length > 0) {\n vtableSheetInstance.activateSheet(importedSheetKeys[0]);\n }\n}\n"]}
@@ -1,36 +1,26 @@
1
- import type { ListTable, ColumnsDefine } from '@visactor/vtable';
2
- import type { pluginsDefinition } from '@visactor/vtable';
3
- export interface ImportResult {
4
- columns: ColumnsDefine;
5
- records: Record<string, unknown>[];
6
- }
7
- export interface ExcelImportOptions {
8
- id?: string;
9
- headerRowCount?: number;
10
- exportData?: boolean;
11
- autoTable?: boolean;
12
- autoColumns?: boolean;
13
- delimiter?: string;
14
- batchSize?: number;
15
- enableBatchProcessing?: boolean;
16
- asyncDelay?: number;
17
- }
1
+ import type { pluginsDefinition, ColumnsDefine } from '@visactor/vtable';
2
+ import type { ExcelImportOptions, ImportResult, MultiSheetImportResult } from './excel-import/types';
3
+ export type { ExcelImportOptions, ImportResult, MultiSheetImportResult, SheetData } from './excel-import/types';
18
4
  export declare class ExcelImportPlugin implements pluginsDefinition.IVTablePlugin {
19
5
  id: string;
20
6
  name: string;
21
7
  runTime: "initialized"[];
22
8
  private options;
23
- private _tableInstance;
9
+ private table;
24
10
  constructor(options?: ExcelImportOptions);
25
- run(...args: [unknown, unknown, ListTable]): void;
11
+ run(...args: any[]): void;
12
+ private _importFile;
13
+ private _selectFile;
14
+ private _importFileFromDialogForVTableSheet;
15
+ private _importMultipleSheetsFromFileDialog;
16
+ private _detectVTableSheet;
17
+ private _getFileExtension;
26
18
  release(): void;
27
- importFile(): Promise<ImportResult>;
28
- import(type: 'file' | 'csv' | 'json' | 'html', source?: string | object, options?: Partial<ExcelImportOptions>): Promise<ImportResult>;
19
+ import(type: 'file' | 'csv' | 'json' | 'html', source?: string | object, options?: Partial<ExcelImportOptions>): Promise<ImportResult | MultiSheetImportResult>;
29
20
  private _importFromFileDialog;
30
21
  private _importFromString;
31
22
  private _importFromData;
32
23
  private _parseFile;
33
- private _getFileExtension;
34
24
  private _parseExcelFile;
35
25
  private _parseCsvFile;
36
26
  private _parseJsonFile;