@visactor/vtable-sheet 1.22.7 → 1.22.8-alpha.13
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/cjs/components/sheet-tab-event-handler.js +3 -2
- package/cjs/components/sheet-tab-event-handler.js.map +1 -1
- package/cjs/components/vtable-sheet.d.ts +2 -1
- package/cjs/components/vtable-sheet.js +9 -1
- package/cjs/components/vtable-sheet.js.map +1 -1
- package/cjs/core/WorkSheet.d.ts +1 -1
- package/cjs/core/WorkSheet.js.map +1 -1
- package/cjs/core/table-plugins.js +7 -5
- package/cjs/core/table-plugins.js.map +1 -1
- package/cjs/formula/cell-highlight-manager.d.ts +1 -0
- package/cjs/formula/cell-highlight-manager.js +27 -22
- package/cjs/formula/cell-highlight-manager.js.map +1 -1
- package/cjs/formula/cross-sheet-data-synchronizer.d.ts +48 -0
- package/cjs/formula/cross-sheet-data-synchronizer.js +159 -0
- package/cjs/formula/cross-sheet-data-synchronizer.js.map +1 -0
- package/cjs/formula/cross-sheet-formula-handler.d.ts +58 -0
- package/cjs/formula/cross-sheet-formula-handler.js +240 -0
- package/cjs/formula/cross-sheet-formula-handler.js.map +1 -0
- package/cjs/formula/cross-sheet-formula-manager.d.ts +52 -0
- package/cjs/formula/cross-sheet-formula-manager.js +235 -0
- package/cjs/formula/cross-sheet-formula-manager.js.map +1 -0
- package/cjs/formula/cross-sheet-formula-validator.d.ts +56 -0
- package/cjs/formula/cross-sheet-formula-validator.js +271 -0
- package/cjs/formula/cross-sheet-formula-validator.js.map +1 -0
- package/cjs/formula/formula-engine.d.ts +4 -1
- package/cjs/formula/formula-engine.js +132 -25
- package/cjs/formula/formula-engine.js.map +1 -1
- package/cjs/formula/formula-paste-processor.d.ts +3 -3
- package/cjs/formula/formula-paste-processor.js.map +1 -1
- package/cjs/formula/formula-reference-adjustor.d.ts +1 -1
- package/cjs/formula/formula-reference-adjustor.js.map +1 -1
- package/cjs/formula/index.d.ts +8 -0
- package/cjs/formula/index.js +40 -3
- package/cjs/formula/index.js.map +1 -1
- package/cjs/index.d.ts +1 -1
- package/cjs/index.js +1 -1
- package/cjs/index.js.map +1 -1
- package/cjs/managers/formula-manager.d.ts +17 -2
- package/cjs/managers/formula-manager.js +150 -12
- package/cjs/managers/formula-manager.js.map +1 -1
- package/cjs/styles/menu.js +2 -1
- package/cjs/styles/sheet-tab.js +1 -2
- package/cjs/tools/index.js +2 -1
- package/dist/vtable-sheet.js +11322 -331
- package/dist/vtable-sheet.min.js +1 -1
- package/es/components/sheet-tab-event-handler.js +3 -2
- package/es/components/sheet-tab-event-handler.js.map +1 -1
- package/es/components/vtable-sheet.d.ts +2 -1
- package/es/components/vtable-sheet.js +9 -1
- package/es/components/vtable-sheet.js.map +1 -1
- package/es/core/WorkSheet.d.ts +1 -1
- package/es/core/WorkSheet.js.map +1 -1
- package/es/core/table-plugins.js +7 -5
- package/es/core/table-plugins.js.map +1 -1
- package/es/formula/cell-highlight-manager.d.ts +1 -0
- package/es/formula/cell-highlight-manager.js +27 -22
- package/es/formula/cell-highlight-manager.js.map +1 -1
- package/es/formula/cross-sheet-data-synchronizer.d.ts +48 -0
- package/es/formula/cross-sheet-data-synchronizer.js +151 -0
- package/es/formula/cross-sheet-data-synchronizer.js.map +1 -0
- package/es/formula/cross-sheet-formula-handler.d.ts +58 -0
- package/es/formula/cross-sheet-formula-handler.js +236 -0
- package/es/formula/cross-sheet-formula-handler.js.map +1 -0
- package/es/formula/cross-sheet-formula-manager.d.ts +52 -0
- package/es/formula/cross-sheet-formula-manager.js +227 -0
- package/es/formula/cross-sheet-formula-manager.js.map +1 -0
- package/es/formula/cross-sheet-formula-validator.d.ts +56 -0
- package/es/formula/cross-sheet-formula-validator.js +263 -0
- package/es/formula/cross-sheet-formula-validator.js.map +1 -0
- package/es/formula/formula-engine.d.ts +4 -1
- package/es/formula/formula-engine.js +132 -25
- package/es/formula/formula-engine.js.map +1 -1
- package/es/formula/formula-paste-processor.d.ts +3 -3
- package/es/formula/formula-paste-processor.js.map +1 -1
- package/es/formula/formula-reference-adjustor.d.ts +1 -1
- package/es/formula/formula-reference-adjustor.js.map +1 -1
- package/es/formula/index.d.ts +8 -0
- package/es/formula/index.js +8 -0
- package/es/formula/index.js.map +1 -1
- package/es/index.d.ts +1 -1
- package/es/index.js +1 -1
- package/es/index.js.map +1 -1
- package/es/managers/formula-manager.d.ts +17 -2
- package/es/managers/formula-manager.js +152 -11
- package/es/managers/formula-manager.js.map +1 -1
- package/es/styles/menu.js +2 -1
- package/es/styles/sheet-tab.js +1 -2
- package/es/tools/index.js +2 -1
- package/package.json +5 -5
|
@@ -21,9 +21,9 @@ export interface FormulaPasteContext {
|
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
export declare class FormulaPasteProcessor {
|
|
24
|
-
static adjustFormulaForPaste(formula: string
|
|
25
|
-
static adjustFormulasForPaste(formulas:
|
|
26
|
-
static adjustFormulasForPasteWithOffset(formulas:
|
|
24
|
+
static adjustFormulaForPaste(formula: string, context: FormulaPasteContext): string;
|
|
25
|
+
static adjustFormulasForPaste(formulas: string[][], context: FormulaPasteContext): string[][];
|
|
26
|
+
static adjustFormulasForPasteWithOffset(formulas: string[][], colOffset: number, rowOffset: number): string[][];
|
|
27
27
|
static needsFormulaAdjustment(value: any): boolean;
|
|
28
28
|
static getFormulaReferences(formula: string): import("./formula-reference-adjustor").CellReference[];
|
|
29
29
|
static validateFormulaReferences(formula: string, maxCol: number, maxRow: number): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/formula/formula-paste-processor.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAyBxE,MAAM,OAAO,qBAAqB;IAIhC,MAAM,CAAC,qBAAqB,CAAC,
|
|
1
|
+
{"version":3,"sources":["../src/formula/formula-paste-processor.ts"],"names":[],"mappings":"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","file":"formula-paste-processor.js","sourcesContent":["/**\n * 公式粘贴处理器 - 处理公式在复制粘贴时的引用调整\n */\n\nimport { FormulaReferenceAdjustor } from './formula-reference-adjustor';\n\nexport interface FormulaPasteContext {\n sourceRange: {\n startCol: number;\n startRow: number;\n endCol: number;\n endRow: number;\n };\n targetRange: {\n startCol: number;\n startRow: number;\n endCol: number;\n endRow: number;\n };\n sourceCell: {\n col: number;\n row: number;\n };\n targetCell: {\n col: number;\n row: number;\n };\n}\n\nexport class FormulaPasteProcessor {\n /**\n * 处理单个公式的粘贴调整\n */\n static adjustFormulaForPaste(formula: string, context: FormulaPasteContext): string {\n if (!FormulaReferenceAdjustor.isFormula(formula)) {\n return formula;\n }\n\n // 计算相对偏移:目标位置相对于源位置的位移\n const colOffset = context.targetCell.col - context.sourceCell.col;\n const rowOffset = context.targetCell.row - context.sourceCell.row;\n\n // 调整公式引用(确保 formula 是字符串类型)\n return FormulaReferenceAdjustor.adjustFormulaReferences(formula, colOffset, rowOffset);\n }\n\n /**\n * 批量处理公式粘贴\n */\n static adjustFormulasForPaste(formulas: string[][], context: FormulaPasteContext): string[][] {\n // 计算整个范围的相对位移\n const colOffset = context.targetRange.startCol - context.sourceRange.startCol;\n const rowOffset = context.targetRange.startRow - context.sourceRange.startRow;\n\n return this.adjustFormulasForPasteWithOffset(formulas, colOffset, rowOffset);\n }\n\n /**\n * 使用指定偏移批量处理公式粘贴\n */\n static adjustFormulasForPasteWithOffset(formulas: string[][], colOffset: number, rowOffset: number): string[][] {\n const result: string[][] = [];\n\n for (let row = 0; row < formulas.length; row++) {\n const newRow: string[] = [];\n for (let col = 0; col < formulas[row].length; col++) {\n const formula = formulas[row][col];\n\n if (FormulaReferenceAdjustor.isFormula(formula)) {\n // 对整个公式应用相同的相对位移\n const adjustedFormula = FormulaReferenceAdjustor.adjustFormulaReferences(formula, colOffset, rowOffset);\n newRow.push(adjustedFormula);\n } else {\n // 非公式内容保持不变\n newRow.push(formula);\n }\n }\n result.push(newRow);\n }\n\n return result;\n }\n\n /**\n * 检查是否需要公式调整\n */\n static needsFormulaAdjustment(value: any): boolean {\n return FormulaReferenceAdjustor.isFormula(value);\n }\n\n /**\n * 获取公式中的引用信息\n */\n static getFormulaReferences(formula: string) {\n return FormulaReferenceAdjustor.extractReferences(formula);\n }\n\n /**\n * 验证公式引用是否在有效范围内\n */\n static validateFormulaReferences(formula: string, maxCol: number, maxRow: number): boolean {\n const references = FormulaReferenceAdjustor.extractReferences(formula);\n\n for (const ref of references) {\n if (ref.col < 0 || ref.col > maxCol || ref.row < 0 || ref.row > maxRow) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * 创建粘贴上下文\n */\n static createPasteContext(\n sourceStartCol: number,\n sourceStartRow: number,\n targetStartCol: number,\n targetStartRow: number,\n sourceCols: number,\n sourceRows: number,\n targetCols: number,\n targetRows: number\n ): FormulaPasteContext {\n return {\n sourceRange: {\n startCol: sourceStartCol,\n startRow: sourceStartRow,\n endCol: sourceStartCol + sourceCols - 1,\n endRow: sourceStartRow + sourceRows - 1\n },\n targetRange: {\n startCol: targetStartCol,\n startRow: targetStartRow,\n endCol: targetStartCol + targetCols - 1,\n endRow: targetStartRow + targetRows - 1\n },\n sourceCell: {\n col: sourceStartCol,\n row: sourceStartRow\n },\n targetCell: {\n col: targetStartCol,\n row: targetStartRow\n }\n };\n }\n}\n"]}
|
|
@@ -17,7 +17,7 @@ export declare class FormulaReferenceAdjustor {
|
|
|
17
17
|
static columnToNumber(col: string): number;
|
|
18
18
|
static numberToColumn(num: number): string;
|
|
19
19
|
static adjustCellReference(ref: CellReference, offset: ReferenceOffset): string;
|
|
20
|
-
static adjustFormulaReferences(formula: string
|
|
20
|
+
static adjustFormulaReferences(formula: string, colOffset: number, rowOffset: number): string;
|
|
21
21
|
static isFormula(value: any): boolean;
|
|
22
22
|
static extractReferences(formula: string): CellReference[];
|
|
23
23
|
static getFormulaReferenceBounds(formula: string): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/formula/formula-reference-adjustor.ts"],"names":[],"mappings":"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","file":"formula-reference-adjustor.js","sourcesContent":["/**\n * 公式引用调整器 - 实现Excel风格的公式复制粘贴功能\n * 处理公式中单元格引用的相对调整\n */\n\nexport interface CellReference {\n type: 'absolute' | 'relative' | 'mixed_row' | 'mixed_col';\n col: number; // 0-based column index\n row: number; // 0-based row index\n originalColRef: string; // 原始列引用,如 \"A\", \"$B\"\n originalRowRef: string; // 原始行引用,如 \"1\", \"$2\"\n fullReference: string; // 完整引用,如 \"A1\", \"$B$2\", \"A$1\"\n}\n\nexport interface ReferenceOffset {\n colOffset: number;\n rowOffset: number;\n}\n\nexport class FormulaReferenceAdjustor {\n private static readonly CELL_REF_REGEX = /(\\$?[A-Z]+\\$?\\d+(?::\\$?[A-Z]+\\$?\\d+)?)/gi;\n private static readonly SINGLE_CELL_REGEX = /(\\$?)([A-Z]+)(\\$?)(\\d+)/i;\n\n /**\n * 解析单元格引用\n */\n static parseCellReference(ref: string): CellReference | null {\n const match = ref.match(this.SINGLE_CELL_REGEX);\n if (!match) {\n return null;\n }\n\n const [, colAbsolute, colStr, rowAbsolute, rowStr] = match;\n const col = this.columnToNumber(colStr);\n const row = parseInt(rowStr, 10) - 1; // Convert to 0-based\n\n let type: CellReference['type'];\n if (colAbsolute && rowAbsolute) {\n type = 'absolute';\n } else if (colAbsolute && !rowAbsolute) {\n type = 'mixed_col';\n } else if (!colAbsolute && rowAbsolute) {\n type = 'mixed_row';\n } else {\n type = 'relative';\n }\n\n return {\n type,\n col,\n row,\n originalColRef: colAbsolute + colStr,\n originalRowRef: rowAbsolute + rowStr,\n fullReference: ref\n };\n }\n\n /**\n * 将列字母转换为数字 (A -> 0, B -> 1, ..., Z -> 25, AA -> 26, etc.)\n */\n static columnToNumber(col: string): number {\n let result = 0;\n for (let i = 0; i < col.length; i++) {\n result = result * 26 + (col.charCodeAt(i) - 'A'.charCodeAt(0) + 1);\n }\n return result - 1; // Convert to 0-based\n }\n\n /**\n * 将数字转换为列字母 (0 -> A, 1 -> B, ..., 25 -> Z, 26 -> AA, etc.)\n */\n static numberToColumn(num: number): string {\n let result = '';\n let n = num + 1; // Convert to 1-based\n while (n > 0) {\n n--;\n result = String.fromCharCode('A'.charCodeAt(0) + (n % 26)) + result;\n n = Math.floor(n / 26);\n }\n return result;\n }\n\n /**\n * 调整单元格引用\n */\n static adjustCellReference(ref: CellReference, offset: ReferenceOffset): string {\n let newCol = ref.col;\n let newRow = ref.row;\n\n switch (ref.type) {\n case 'relative':\n newCol += offset.colOffset;\n newRow += offset.rowOffset;\n break;\n case 'mixed_row':\n // 行绝对,列相对\n newCol += offset.colOffset;\n newRow = ref.row; // 行绝对引用,不改变\n break;\n case 'mixed_col':\n // 列绝对,行相对\n newCol = ref.col; // 列绝对引用,不改变\n newRow += offset.rowOffset;\n break;\n case 'absolute':\n // 绝对引用,不改变任何值\n newCol = ref.col;\n newRow = ref.row;\n break;\n }\n\n // 确保坐标在有效范围内\n if (newCol < 0) {\n newCol = 0;\n }\n if (newRow < 0) {\n newRow = 0;\n }\n\n // 构建新的引用字符串\n let result = '';\n if (ref.type === 'absolute' || ref.type === 'mixed_col') {\n result += '$';\n }\n result += this.numberToColumn(newCol);\n if (ref.type === 'absolute' || ref.type === 'mixed_row') {\n result += '$';\n }\n result += newRow + 1; // Convert back to 1-based\n\n return result;\n }\n\n /**\n * 调整公式中的引用\n * @param formula 原始公式\n * @param colOffset 列位移(目标列 - 源列)\n * @param rowOffset 行位移(目标行 - 源行)\n */\n static adjustFormulaReferences(formula: string | number, colOffset: number, rowOffset: number): string | number {\n const offset = {\n colOffset: colOffset,\n rowOffset: rowOffset\n };\n\n return typeof formula === 'string'\n ? formula.replace(this.CELL_REF_REGEX, match => {\n // 处理范围引用(如 A1:B2)\n if (match.includes(':')) {\n const parts = match.split(':');\n const startRef = this.parseCellReference(parts[0]);\n const endRef = this.parseCellReference(parts[1]);\n\n if (startRef && endRef) {\n const newStart = this.adjustCellReference(startRef, offset);\n const newEnd = this.adjustCellReference(endRef, offset);\n return `${newStart}:${newEnd}`;\n }\n return match; // 如果解析失败,保持原样\n }\n\n // 处理单个单元格引用\n const ref = this.parseCellReference(match);\n if (ref) {\n return this.adjustCellReference(ref, offset);\n }\n return match; // 如果解析失败,保持原样\n })\n : formula;\n }\n\n /**\n * 检查是否为公式\n */\n static isFormula(value: any): boolean {\n return typeof value === 'string' && value.startsWith('=');\n }\n\n /**\n * 提取公式中的引用\n */\n static extractReferences(formula: string): CellReference[] {\n const references: CellReference[] = [];\n const matches = formula.match(this.CELL_REF_REGEX);\n\n if (matches) {\n matches.forEach(match => {\n // 处理范围引用\n if (match.includes(':')) {\n const parts = match.split(':');\n const startRef = this.parseCellReference(parts[0]);\n const endRef = this.parseCellReference(parts[1]);\n\n if (startRef) {\n references.push(startRef);\n }\n if (endRef) {\n references.push(endRef);\n }\n } else {\n const ref = this.parseCellReference(match);\n if (ref) {\n references.push(ref);\n }\n }\n });\n }\n\n return references;\n }\n\n /**\n * 获取公式中的引用范围\n */\n static getFormulaReferenceBounds(formula: string): {\n minCol: number;\n maxCol: number;\n minRow: number;\n maxRow: number;\n } | null {\n const references = this.extractReferences(formula);\n if (references.length === 0) {\n return null;\n }\n\n let minCol = Infinity;\n let maxCol = -Infinity;\n let minRow = Infinity;\n let maxRow = -Infinity;\n\n references.forEach(ref => {\n minCol = Math.min(minCol, ref.col);\n maxCol = Math.max(maxCol, ref.col);\n minRow = Math.min(minRow, ref.row);\n maxRow = Math.max(maxRow, ref.row);\n });\n\n return {\n minCol,\n maxCol,\n minRow,\n maxRow\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/formula/formula-reference-adjustor.ts"],"names":[],"mappings":"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","file":"formula-reference-adjustor.js","sourcesContent":["/**\n * 公式引用调整器 - 实现Excel风格的公式复制粘贴功能\n * 处理公式中单元格引用的相对调整\n */\n\nexport interface CellReference {\n type: 'absolute' | 'relative' | 'mixed_row' | 'mixed_col';\n col: number; // 0-based column index\n row: number; // 0-based row index\n originalColRef: string; // 原始列引用,如 \"A\", \"$B\"\n originalRowRef: string; // 原始行引用,如 \"1\", \"$2\"\n fullReference: string; // 完整引用,如 \"A1\", \"$B$2\", \"A$1\"\n}\n\nexport interface ReferenceOffset {\n colOffset: number;\n rowOffset: number;\n}\n\nexport class FormulaReferenceAdjustor {\n private static readonly CELL_REF_REGEX = /(\\$?[A-Z]+\\$?\\d+(?::\\$?[A-Z]+\\$?\\d+)?)/gi;\n private static readonly SINGLE_CELL_REGEX = /(\\$?)([A-Z]+)(\\$?)(\\d+)/i;\n\n /**\n * 解析单元格引用\n */\n static parseCellReference(ref: string): CellReference | null {\n const match = ref.match(this.SINGLE_CELL_REGEX);\n if (!match) {\n return null;\n }\n\n const [, colAbsolute, colStr, rowAbsolute, rowStr] = match;\n const col = this.columnToNumber(colStr);\n const row = parseInt(rowStr, 10) - 1; // Convert to 0-based\n\n let type: CellReference['type'];\n if (colAbsolute && rowAbsolute) {\n type = 'absolute';\n } else if (colAbsolute && !rowAbsolute) {\n type = 'mixed_col';\n } else if (!colAbsolute && rowAbsolute) {\n type = 'mixed_row';\n } else {\n type = 'relative';\n }\n\n return {\n type,\n col,\n row,\n originalColRef: colAbsolute + colStr,\n originalRowRef: rowAbsolute + rowStr,\n fullReference: ref\n };\n }\n\n /**\n * 将列字母转换为数字 (A -> 0, B -> 1, ..., Z -> 25, AA -> 26, etc.)\n */\n static columnToNumber(col: string): number {\n let result = 0;\n for (let i = 0; i < col.length; i++) {\n result = result * 26 + (col.charCodeAt(i) - 'A'.charCodeAt(0) + 1);\n }\n return result - 1; // Convert to 0-based\n }\n\n /**\n * 将数字转换为列字母 (0 -> A, 1 -> B, ..., 25 -> Z, 26 -> AA, etc.)\n */\n static numberToColumn(num: number): string {\n let result = '';\n let n = num + 1; // Convert to 1-based\n while (n > 0) {\n n--;\n result = String.fromCharCode('A'.charCodeAt(0) + (n % 26)) + result;\n n = Math.floor(n / 26);\n }\n return result;\n }\n\n /**\n * 调整单元格引用\n */\n static adjustCellReference(ref: CellReference, offset: ReferenceOffset): string {\n let newCol = ref.col;\n let newRow = ref.row;\n\n switch (ref.type) {\n case 'relative':\n newCol += offset.colOffset;\n newRow += offset.rowOffset;\n break;\n case 'mixed_row':\n // 行绝对,列相对\n newCol += offset.colOffset;\n newRow = ref.row; // 行绝对引用,不改变\n break;\n case 'mixed_col':\n // 列绝对,行相对\n newCol = ref.col; // 列绝对引用,不改变\n newRow += offset.rowOffset;\n break;\n case 'absolute':\n // 绝对引用,不改变任何值\n newCol = ref.col;\n newRow = ref.row;\n break;\n }\n\n // 确保坐标在有效范围内\n if (newCol < 0) {\n newCol = 0;\n }\n if (newRow < 0) {\n newRow = 0;\n }\n\n // 构建新的引用字符串\n let result = '';\n if (ref.type === 'absolute' || ref.type === 'mixed_col') {\n result += '$';\n }\n result += this.numberToColumn(newCol);\n if (ref.type === 'absolute' || ref.type === 'mixed_row') {\n result += '$';\n }\n result += newRow + 1; // Convert back to 1-based\n\n return result;\n }\n\n /**\n * 调整公式中的引用\n * @param formula 原始公式\n * @param colOffset 列位移(目标列 - 源列)\n * @param rowOffset 行位移(目标行 - 源行)\n */\n static adjustFormulaReferences(formula: string, colOffset: number, rowOffset: number): string {\n const offset = {\n colOffset: colOffset,\n rowOffset: rowOffset\n };\n\n return typeof formula === 'string'\n ? formula.replace(this.CELL_REF_REGEX, match => {\n // 处理范围引用(如 A1:B2)\n if (match.includes(':')) {\n const parts = match.split(':');\n const startRef = this.parseCellReference(parts[0]);\n const endRef = this.parseCellReference(parts[1]);\n\n if (startRef && endRef) {\n const newStart = this.adjustCellReference(startRef, offset);\n const newEnd = this.adjustCellReference(endRef, offset);\n return `${newStart}:${newEnd}`;\n }\n return match; // 如果解析失败,保持原样\n }\n\n // 处理单个单元格引用\n const ref = this.parseCellReference(match);\n if (ref) {\n return this.adjustCellReference(ref, offset);\n }\n return match; // 如果解析失败,保持原样\n })\n : formula;\n }\n\n /**\n * 检查是否为公式\n */\n static isFormula(value: any): boolean {\n return typeof value === 'string' && value.startsWith('=');\n }\n\n /**\n * 提取公式中的引用\n */\n static extractReferences(formula: string): CellReference[] {\n const references: CellReference[] = [];\n const matches = formula.match(this.CELL_REF_REGEX);\n\n if (matches) {\n matches.forEach(match => {\n // 处理范围引用\n if (match.includes(':')) {\n const parts = match.split(':');\n const startRef = this.parseCellReference(parts[0]);\n const endRef = this.parseCellReference(parts[1]);\n\n if (startRef) {\n references.push(startRef);\n }\n if (endRef) {\n references.push(endRef);\n }\n } else {\n const ref = this.parseCellReference(match);\n if (ref) {\n references.push(ref);\n }\n }\n });\n }\n\n return references;\n }\n\n /**\n * 获取公式中的引用范围\n */\n static getFormulaReferenceBounds(formula: string): {\n minCol: number;\n maxCol: number;\n minRow: number;\n maxRow: number;\n } | null {\n const references = this.extractReferences(formula);\n if (references.length === 0) {\n return null;\n }\n\n let minCol = Infinity;\n let maxCol = -Infinity;\n let minRow = Infinity;\n let maxRow = -Infinity;\n\n references.forEach(ref => {\n minCol = Math.min(minCol, ref.col);\n maxCol = Math.max(maxCol, ref.col);\n minRow = Math.min(minRow, ref.row);\n maxRow = Math.max(maxRow, ref.row);\n });\n\n return {\n minCol,\n maxCol,\n minRow,\n maxRow\n };\n }\n}\n"]}
|
package/es/formula/index.d.ts
CHANGED
|
@@ -7,3 +7,11 @@ export { FormulaReferenceAdjustor } from './formula-reference-adjustor';
|
|
|
7
7
|
export { FormulaPasteProcessor } from './formula-paste-processor';
|
|
8
8
|
export type { CellReference, ReferenceOffset } from './formula-reference-adjustor';
|
|
9
9
|
export type { FormulaPasteContext } from './formula-paste-processor';
|
|
10
|
+
export { CrossSheetFormulaManager } from './cross-sheet-formula-manager';
|
|
11
|
+
export { CrossSheetDataSynchronizer } from './cross-sheet-data-synchronizer';
|
|
12
|
+
export { CrossSheetFormulaValidator } from './cross-sheet-formula-validator';
|
|
13
|
+
export { CrossSheetFormulaHandler } from './cross-sheet-formula-handler';
|
|
14
|
+
export type { CrossSheetReference, CrossSheetDependency } from './cross-sheet-formula-manager';
|
|
15
|
+
export type { DataChangeEvent, SyncOptions } from './cross-sheet-data-synchronizer';
|
|
16
|
+
export type { ValidationError, ValidationResult, ValidationOptions } from './cross-sheet-formula-validator';
|
|
17
|
+
export type { CrossSheetFormulaOptions, FormulaCalculationResult } from './cross-sheet-formula-handler';
|
package/es/formula/index.js
CHANGED
|
@@ -11,4 +11,12 @@ export * from "./cell-highlight-manager";
|
|
|
11
11
|
export { FormulaReferenceAdjustor } from "./formula-reference-adjustor";
|
|
12
12
|
|
|
13
13
|
export { FormulaPasteProcessor } from "./formula-paste-processor";
|
|
14
|
+
|
|
15
|
+
export { CrossSheetFormulaManager } from "./cross-sheet-formula-manager";
|
|
16
|
+
|
|
17
|
+
export { CrossSheetDataSynchronizer } from "./cross-sheet-data-synchronizer";
|
|
18
|
+
|
|
19
|
+
export { CrossSheetFormulaValidator } from "./cross-sheet-formula-validator";
|
|
20
|
+
|
|
21
|
+
export { CrossSheetFormulaHandler } from "./cross-sheet-formula-handler";
|
|
14
22
|
//# sourceMappingURL=index.js.map
|
package/es/formula/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/formula/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC","file":"index.js","sourcesContent":["export * from './formula-editor';\nexport * from './formula-autocomplete';\nexport * from './formula-range-selector';\nexport * from './formula-ui-manager';\nexport * from './cell-highlight-manager';\nexport { FormulaReferenceAdjustor } from './formula-reference-adjustor';\nexport { FormulaPasteProcessor } from './formula-paste-processor';\nexport type { CellReference, ReferenceOffset } from './formula-reference-adjustor';\nexport type { FormulaPasteContext } from './formula-paste-processor';\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/formula/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAKlE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC","file":"index.js","sourcesContent":["export * from './formula-editor';\nexport * from './formula-autocomplete';\nexport * from './formula-range-selector';\nexport * from './formula-ui-manager';\nexport * from './cell-highlight-manager';\nexport { FormulaReferenceAdjustor } from './formula-reference-adjustor';\nexport { FormulaPasteProcessor } from './formula-paste-processor';\nexport type { CellReference, ReferenceOffset } from './formula-reference-adjustor';\nexport type { FormulaPasteContext } from './formula-paste-processor';\n\n// 跨sheet公式支持\nexport { CrossSheetFormulaManager } from './cross-sheet-formula-manager';\nexport { CrossSheetDataSynchronizer } from './cross-sheet-data-synchronizer';\nexport { CrossSheetFormulaValidator } from './cross-sheet-formula-validator';\nexport { CrossSheetFormulaHandler } from './cross-sheet-formula-handler';\nexport type { CrossSheetReference, CrossSheetDependency } from './cross-sheet-formula-manager';\nexport type { DataChangeEvent, SyncOptions } from './cross-sheet-data-synchronizer';\nexport type { ValidationError, ValidationResult, ValidationOptions } from './cross-sheet-formula-validator';\nexport type { CrossSheetFormulaOptions, FormulaCalculationResult } from './cross-sheet-formula-handler';\n"]}
|
package/es/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ import VTableSheet from './components/vtable-sheet';
|
|
|
2
2
|
import type { ISheetDefine, IVTableSheetOptions } from './ts-types';
|
|
3
3
|
import * as TYPES from './ts-types';
|
|
4
4
|
import * as VTable from './vtable';
|
|
5
|
-
export declare const version = "1.22.
|
|
5
|
+
export declare const version = "1.22.8-alpha.13";
|
|
6
6
|
export { VTableSheet, TYPES, VTable, ISheetDefine, IVTableSheetOptions };
|
package/es/index.js
CHANGED
package/es/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,2BAA2B,CAAC;AAEpD,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,MAAM,CAAC,MAAM,OAAO,GAAG,
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,2BAA2B,CAAC;AAEpD,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,MAAM,CAAC,MAAM,OAAO,GAAG,iBAAiB,CAAC;AAEzC,YAAY,EAAE,CAAC;AAIf,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAqC,CAAC","file":"index.js","sourcesContent":["import VTableSheet from './components/vtable-sheet';\nimport type { ISheetDefine, IVTableSheetOptions } from './ts-types';\nimport * as TYPES from './ts-types';\nimport * as VTable from './vtable';\nimport { importStyles } from './styles/style-manager';\nexport const version = \"1.22.8-alpha.13\";\n// 导入样式\nimportStyles();\n/**\n * @namespace VTableSheet\n */\nexport { VTableSheet, TYPES, VTable, ISheetDefine, IVTableSheetOptions };\n"]}
|
|
@@ -5,6 +5,8 @@ import { FormulaRangeSelector } from '../formula/formula-range-selector';
|
|
|
5
5
|
import type { CellRange } from '../ts-types';
|
|
6
6
|
import { CellHighlightManager } from '../formula';
|
|
7
7
|
import type * as VTable from '@visactor/vtable';
|
|
8
|
+
import { CrossSheetFormulaHandler } from '../formula/cross-sheet-formula-handler';
|
|
9
|
+
import type { CrossSheetFormulaOptions } from '../formula/cross-sheet-formula-handler';
|
|
8
10
|
export declare class FormulaManager implements IFormulaManager {
|
|
9
11
|
sheet: VTableSheet;
|
|
10
12
|
formulaEngine: FormulaEngine;
|
|
@@ -25,14 +27,21 @@ export declare class FormulaManager implements IFormulaManager {
|
|
|
25
27
|
} | null;
|
|
26
28
|
} | null;
|
|
27
29
|
inputingElement: HTMLInputElement | null;
|
|
30
|
+
crossSheetHandler: CrossSheetFormulaHandler;
|
|
28
31
|
get formulaWorkingOnCell(): FormulaCell | null;
|
|
29
32
|
set formulaWorkingOnCell(value: FormulaCell | null);
|
|
30
33
|
constructor(sheet: VTableSheet);
|
|
31
34
|
private initializeFormulaEngine;
|
|
32
|
-
addSheet(sheetKey: string, normalizedData?: unknown[][]): number;
|
|
35
|
+
addSheet(sheetKey: string, normalizedData?: unknown[][], sheetTitle?: string): number;
|
|
33
36
|
normalizeSheetData(data: unknown[][], tableInstance: VTable.ListTable): unknown[][];
|
|
34
37
|
removeSheet(sheetKey: string): void;
|
|
35
38
|
renameSheet(oldKey: string, newKey: string): void;
|
|
39
|
+
updateSheetTitle(sheetKey: string, newTitle: string): void;
|
|
40
|
+
private updateCrossSheetFormulasWithNewTitle;
|
|
41
|
+
private parseA1CellRef;
|
|
42
|
+
private ensureSheetRegistered;
|
|
43
|
+
private ensureAllSheetsRegisteredForCrossSheetFormula;
|
|
44
|
+
private normalizeDataForFormulaEngine;
|
|
36
45
|
getSheetId(sheetKey: string): number;
|
|
37
46
|
setCellContent(cell: FormulaCell, value: unknown): void;
|
|
38
47
|
getCellValue(cell: FormulaCell): FormulaResult;
|
|
@@ -74,7 +83,7 @@ export declare class FormulaManager implements IFormulaManager {
|
|
|
74
83
|
getAllSheets(): Array<{
|
|
75
84
|
key: string;
|
|
76
85
|
id: number;
|
|
77
|
-
|
|
86
|
+
title: string;
|
|
78
87
|
}>;
|
|
79
88
|
setActiveSheet(sheetKey: string): void;
|
|
80
89
|
getActiveSheet(): string | null;
|
|
@@ -84,4 +93,10 @@ export declare class FormulaManager implements IFormulaManager {
|
|
|
84
93
|
endRow: number;
|
|
85
94
|
endCol: number;
|
|
86
95
|
}, targetSheet: string, targetRow: number, targetCol: number): void;
|
|
96
|
+
private hasCrossSheetReference;
|
|
97
|
+
getCrossSheetDependencies(): Map<string, string[]>;
|
|
98
|
+
validateCrossSheetFormula(cell: FormulaCell): import("../formula").ValidationResult;
|
|
99
|
+
validateAllCrossSheetFormulas(): Map<string, import("../formula").ValidationResult>;
|
|
100
|
+
recalculateAllCrossSheetFormulas(): Promise<void>;
|
|
101
|
+
updateCrossSheetOptions(options: Partial<CrossSheetFormulaOptions>): void;
|
|
87
102
|
}
|
|
@@ -1,9 +1,37 @@
|
|
|
1
|
+
var __awaiter = this && this.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
2
|
+
return new (P || (P = Promise))((function(resolve, reject) {
|
|
3
|
+
function fulfilled(value) {
|
|
4
|
+
try {
|
|
5
|
+
step(generator.next(value));
|
|
6
|
+
} catch (e) {
|
|
7
|
+
reject(e);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function rejected(value) {
|
|
11
|
+
try {
|
|
12
|
+
step(generator.throw(value));
|
|
13
|
+
} catch (e) {
|
|
14
|
+
reject(e);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function step(result) {
|
|
18
|
+
var value;
|
|
19
|
+
result.done ? resolve(result.value) : (value = result.value, value instanceof P ? value : new P((function(resolve) {
|
|
20
|
+
resolve(value);
|
|
21
|
+
}))).then(fulfilled, rejected);
|
|
22
|
+
}
|
|
23
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
24
|
+
}));
|
|
25
|
+
};
|
|
26
|
+
|
|
1
27
|
import { FormulaEngine } from "../formula/formula-engine";
|
|
2
28
|
|
|
3
29
|
import { FormulaRangeSelector } from "../formula/formula-range-selector";
|
|
4
30
|
|
|
5
31
|
import { CellHighlightManager } from "../formula";
|
|
6
32
|
|
|
33
|
+
import { CrossSheetFormulaHandler } from "../formula/cross-sheet-formula-handler";
|
|
34
|
+
|
|
7
35
|
const DEFAULT_FORMULA_ENGINE_CONFIG = {
|
|
8
36
|
precisionRounding: 14,
|
|
9
37
|
caseSensitive: !1,
|
|
@@ -29,7 +57,8 @@ export class FormulaManager {
|
|
|
29
57
|
this.nextSheetId = 0, this._formulaWorkingOnCell = null, this.lastKnownCursorPosInFormulaInput = null,
|
|
30
58
|
this.lastSelectionRangesOfHandling = [], this.inputIsParamMode = null, this.inputingElement = null,
|
|
31
59
|
this.sheet = sheet, this.cellHighlightManager = new CellHighlightManager(sheet),
|
|
32
|
-
this.formulaRangeSelector = new FormulaRangeSelector(this), this.initializeFormulaEngine()
|
|
60
|
+
this.formulaRangeSelector = new FormulaRangeSelector(this), this.initializeFormulaEngine(),
|
|
61
|
+
this.crossSheetHandler = new CrossSheetFormulaHandler(this.formulaEngine, this.sheet.getSheetManager(), this);
|
|
33
62
|
}
|
|
34
63
|
initializeFormulaEngine() {
|
|
35
64
|
try {
|
|
@@ -38,16 +67,16 @@ export class FormulaManager {
|
|
|
38
67
|
throw new Error("FormulaManager initialization failed");
|
|
39
68
|
}
|
|
40
69
|
}
|
|
41
|
-
addSheet(sheetKey, normalizedData) {
|
|
70
|
+
addSheet(sheetKey, normalizedData, sheetTitle) {
|
|
42
71
|
if (this.ensureInitialized(), this.sheetMapping.has(sheetKey)) {
|
|
43
72
|
const existingId = this.sheetMapping.get(sheetKey);
|
|
44
73
|
if (void 0 !== existingId) return existingId;
|
|
45
74
|
}
|
|
46
75
|
try {
|
|
47
76
|
const wasFirstSheet = 0 === this.sheetMapping.size, sheetId = this.formulaEngine.addSheet(sheetKey, normalizedData);
|
|
48
|
-
return this.
|
|
49
|
-
this.nextSheetId = Math.max(this.nextSheetId, sheetId + 1),
|
|
50
|
-
sheetId;
|
|
77
|
+
return sheetTitle && this.formulaEngine.setSheetTitle(sheetKey, sheetTitle), this.sheetMapping.set(sheetKey, sheetId),
|
|
78
|
+
this.reverseSheetMapping.set(sheetId, sheetKey), this.nextSheetId = Math.max(this.nextSheetId, sheetId + 1),
|
|
79
|
+
wasFirstSheet && this.formulaEngine.setActiveSheet(sheetKey), sheetId;
|
|
51
80
|
} catch (error) {
|
|
52
81
|
throw new Error(`Failed to add sheet: ${sheetKey}`);
|
|
53
82
|
}
|
|
@@ -103,15 +132,99 @@ export class FormulaManager {
|
|
|
103
132
|
throw new Error(`Failed to rename sheet: ${oldKey}`);
|
|
104
133
|
}
|
|
105
134
|
}
|
|
135
|
+
updateSheetTitle(sheetKey, newTitle) {
|
|
136
|
+
const oldTitle = this.formulaEngine.getSheetTitle(sheetKey);
|
|
137
|
+
this.formulaEngine.setSheetTitle(sheetKey, newTitle), oldTitle && oldTitle !== newTitle && this.updateCrossSheetFormulasWithNewTitle(oldTitle, newTitle),
|
|
138
|
+
this.crossSheetHandler && this.crossSheetHandler.clearCache();
|
|
139
|
+
}
|
|
140
|
+
updateCrossSheetFormulasWithNewTitle(oldTitle, newTitle) {
|
|
141
|
+
try {
|
|
142
|
+
const allSheets = this.sheet.getSheetManager().getAllSheets();
|
|
143
|
+
for (const sheetInfo of allSheets) {
|
|
144
|
+
const formulas = this.formulaEngine.exportFormulas(sheetInfo.sheetKey);
|
|
145
|
+
for (const [cellRef, formula] of Object.entries(formulas)) if (this.hasCrossSheetReference(formula)) {
|
|
146
|
+
const escapedOldTitle = oldTitle.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), patterns = [ `${escapedOldTitle}!`, `${escapedOldTitle}!`, `'${escapedOldTitle}'!`, `'${escapedOldTitle}'!` ];
|
|
147
|
+
let updatedFormula = formula, hasChanges = !1;
|
|
148
|
+
for (const pattern of patterns) updatedFormula.includes(pattern) && (pattern.includes(`'${escapedOldTitle}'`) ? pattern.endsWith("!") ? updatedFormula = updatedFormula.replace(new RegExp(`'${escapedOldTitle}'!`, "g"), `'${newTitle}'!`) : pattern.endsWith("!") && (updatedFormula = updatedFormula.replace(new RegExp(`'${escapedOldTitle}'!`, "g"), `'${newTitle}'!`)) : pattern.endsWith("!") ? updatedFormula = updatedFormula.replace(new RegExp(`${escapedOldTitle}!`, "g"), `${newTitle}!`) : pattern.endsWith("!") && (updatedFormula = updatedFormula.replace(new RegExp(`${escapedOldTitle}!`, "g"), `${newTitle}!`)),
|
|
149
|
+
hasChanges = !0);
|
|
150
|
+
if (hasChanges && updatedFormula !== formula) {
|
|
151
|
+
const cell = this.parseA1CellRef(`${sheetInfo.sheetKey}!${cellRef}`);
|
|
152
|
+
cell && this.formulaEngine.setCellContent(cell, updatedFormula);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
} catch (error) {}
|
|
157
|
+
}
|
|
158
|
+
parseA1CellRef(cellRef) {
|
|
159
|
+
try {
|
|
160
|
+
let parts;
|
|
161
|
+
if (parts = cellRef.includes("!") ? cellRef.split("!") : cellRef.includes("!") ? cellRef.split("!") : [ "Sheet1", cellRef ],
|
|
162
|
+
2 !== parts.length) return null;
|
|
163
|
+
const [sheet, a1Notation] = parts, match = a1Notation.match(/^([A-Z]+)([0-9]+)$/);
|
|
164
|
+
if (!match) return null;
|
|
165
|
+
const colLetters = match[1], rowNumber = parseInt(match[2], 10);
|
|
166
|
+
let col = 0;
|
|
167
|
+
for (let i = 0; i < colLetters.length; i++) col = 26 * col + (colLetters.charCodeAt(i) - 65);
|
|
168
|
+
return {
|
|
169
|
+
sheet: sheet,
|
|
170
|
+
row: rowNumber - 1,
|
|
171
|
+
col: col
|
|
172
|
+
};
|
|
173
|
+
} catch (_a) {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
ensureSheetRegistered(sheetKey) {
|
|
178
|
+
if (this.sheet.workSheetInstances.has(sheetKey)) return;
|
|
179
|
+
const sheetDefine = this.sheet.getSheetManager().getSheet(sheetKey);
|
|
180
|
+
if (!sheetDefine) return;
|
|
181
|
+
const instance = this.sheet.createWorkSheetInstance(sheetDefine);
|
|
182
|
+
this.sheet.workSheetInstances.set(sheetKey, instance);
|
|
183
|
+
}
|
|
184
|
+
ensureAllSheetsRegisteredForCrossSheetFormula(formula) {
|
|
185
|
+
try {
|
|
186
|
+
const sheetPattern = /([A-Za-z0-9_一-龥]+)!/g;
|
|
187
|
+
let match;
|
|
188
|
+
const referencedSheets = new Set;
|
|
189
|
+
for (;null !== (match = sheetPattern.exec(formula)); ) {
|
|
190
|
+
const sheetName = match[1];
|
|
191
|
+
sheetName && referencedSheets.add(sheetName);
|
|
192
|
+
}
|
|
193
|
+
for (const sheetTitle of referencedSheets) {
|
|
194
|
+
const sheetInfo = this.sheet.getSheetManager().getAllSheets().find((sheet => sheet.sheetTitle.toLowerCase() === sheetTitle.toLowerCase()));
|
|
195
|
+
sheetInfo && this.ensureSheetRegistered(sheetInfo.sheetKey);
|
|
196
|
+
}
|
|
197
|
+
} catch (error) {}
|
|
198
|
+
}
|
|
199
|
+
normalizeDataForFormulaEngine(data) {
|
|
200
|
+
if (!Array.isArray(data) || 0 === data.length) return [ [ "" ] ];
|
|
201
|
+
const maxCols = Math.max(...data.map((row => Array.isArray(row) ? row.length : 0)));
|
|
202
|
+
return data.map((row => {
|
|
203
|
+
if (!Array.isArray(row)) return Array(maxCols).fill("");
|
|
204
|
+
const normalizedRow = row.map((cell => {
|
|
205
|
+
if ("string" == typeof cell) {
|
|
206
|
+
if (cell.startsWith("=")) return cell;
|
|
207
|
+
const num = Number(cell);
|
|
208
|
+
return isNaN(num) || "" === cell.trim() ? cell : num;
|
|
209
|
+
}
|
|
210
|
+
return null != cell ? cell : "";
|
|
211
|
+
}));
|
|
212
|
+
for (;normalizedRow.length < maxCols; ) normalizedRow.push("");
|
|
213
|
+
return normalizedRow;
|
|
214
|
+
}));
|
|
215
|
+
}
|
|
106
216
|
getSheetId(sheetKey) {
|
|
107
217
|
const sheetId = this.sheetMapping.get(sheetKey);
|
|
108
|
-
|
|
218
|
+
if (void 0 !== sheetId) return sheetId;
|
|
219
|
+
const lowerSheetKey = sheetKey.toLowerCase();
|
|
220
|
+
for (const [existingKey, existingId] of this.sheetMapping.entries()) if (existingKey.toLowerCase() === lowerSheetKey) return existingId;
|
|
221
|
+
return this.addSheet(sheetKey);
|
|
109
222
|
}
|
|
110
223
|
setCellContent(cell, value) {
|
|
111
224
|
if (this.ensureInitialized(), !cell || void 0 === cell.sheet || void 0 === cell.row || void 0 === cell.col) throw new Error("Invalid cell parameter for setCellContent");
|
|
112
225
|
if (cell.row < 0 || cell.col < 0) throw new Error(`Cell coordinates out of bounds: row=${cell.row}, col=${cell.col}`);
|
|
113
226
|
try {
|
|
114
|
-
this.formulaEngine.setCellContent(cell, value);
|
|
227
|
+
"string" == typeof value && value.startsWith("=") && this.hasCrossSheetReference(value) ? this.crossSheetHandler.setCrossSheetFormula(cell, value) : this.formulaEngine.setCellContent(cell, value);
|
|
115
228
|
} catch (error) {
|
|
116
229
|
throw error instanceof Error ? new Error(`Failed to set cell content at ${cell.sheet}:${cell.row}:${cell.col}. ${error.message}`) : new Error(`Failed to set cell content at ${cell.sheet}:${cell.row}:${cell.col}`);
|
|
117
230
|
}
|
|
@@ -119,7 +232,12 @@ export class FormulaManager {
|
|
|
119
232
|
getCellValue(cell) {
|
|
120
233
|
this.ensureInitialized();
|
|
121
234
|
try {
|
|
122
|
-
|
|
235
|
+
const formula = this.formulaEngine.getCellFormula(cell);
|
|
236
|
+
if (formula && this.hasCrossSheetReference(formula)) {
|
|
237
|
+
this.ensureAllSheetsRegisteredForCrossSheetFormula(formula);
|
|
238
|
+
return this.formulaEngine.getCellValue(cell);
|
|
239
|
+
}
|
|
240
|
+
return this.ensureSheetRegistered(cell.sheet), this.formulaEngine.getCellValue(cell);
|
|
123
241
|
} catch (error) {
|
|
124
242
|
return {
|
|
125
243
|
value: null,
|
|
@@ -319,7 +437,8 @@ export class FormulaManager {
|
|
|
319
437
|
}
|
|
320
438
|
calculateFormula(formula) {
|
|
321
439
|
try {
|
|
322
|
-
return this.
|
|
440
|
+
return this.hasCrossSheetReference(formula) && this.ensureAllSheetsRegisteredForCrossSheetFormula(formula),
|
|
441
|
+
this.formulaEngine.calculateFormula(formula);
|
|
323
442
|
} catch (error) {
|
|
324
443
|
return {
|
|
325
444
|
value: null,
|
|
@@ -336,8 +455,9 @@ export class FormulaManager {
|
|
|
336
455
|
} catch (error) {}
|
|
337
456
|
}
|
|
338
457
|
release() {
|
|
339
|
-
var _a, _b;
|
|
340
|
-
null === (_a = this.formulaRangeSelector) || void 0 === _a || _a.release(), null === (_b = this.cellHighlightManager) || void 0 === _b || _b.release()
|
|
458
|
+
var _a, _b, _c;
|
|
459
|
+
null === (_a = this.formulaRangeSelector) || void 0 === _a || _a.release(), null === (_b = this.cellHighlightManager) || void 0 === _b || _b.release(),
|
|
460
|
+
null === (_c = this.crossSheetHandler) || void 0 === _c || _c.destroy();
|
|
341
461
|
try {
|
|
342
462
|
this.formulaEngine && this.formulaEngine.release();
|
|
343
463
|
} catch (error) {} finally {
|
|
@@ -350,6 +470,7 @@ export class FormulaManager {
|
|
|
350
470
|
isInitialized: this.isInitialized,
|
|
351
471
|
sheets: Array.from(this.sheetMapping.entries()),
|
|
352
472
|
functions: this.getAvailableFunctions(),
|
|
473
|
+
crossSheetHandler: this.crossSheetHandler ? this.crossSheetHandler.getHandlerStatus() : null,
|
|
353
474
|
stats: null
|
|
354
475
|
};
|
|
355
476
|
}
|
|
@@ -406,5 +527,25 @@ export class FormulaManager {
|
|
|
406
527
|
throw new Error("Failed to copy cell range");
|
|
407
528
|
}
|
|
408
529
|
}
|
|
530
|
+
hasCrossSheetReference(formula) {
|
|
531
|
+
return formula.includes("!") || formula.includes("!");
|
|
532
|
+
}
|
|
533
|
+
getCrossSheetDependencies() {
|
|
534
|
+
return this.crossSheetHandler.getCrossSheetDependencies();
|
|
535
|
+
}
|
|
536
|
+
validateCrossSheetFormula(cell) {
|
|
537
|
+
return this.crossSheetHandler.validateCrossSheetFormula(cell);
|
|
538
|
+
}
|
|
539
|
+
validateAllCrossSheetFormulas() {
|
|
540
|
+
return this.crossSheetHandler.validateAllCrossSheetFormulas();
|
|
541
|
+
}
|
|
542
|
+
recalculateAllCrossSheetFormulas() {
|
|
543
|
+
return __awaiter(this, void 0, void 0, (function*() {
|
|
544
|
+
yield this.crossSheetHandler.recalculateAllCrossSheetFormulas();
|
|
545
|
+
}));
|
|
546
|
+
}
|
|
547
|
+
updateCrossSheetOptions(options) {
|
|
548
|
+
this.crossSheetHandler.updateOptions(options);
|
|
549
|
+
}
|
|
409
550
|
}
|
|
410
551
|
//# sourceMappingURL=formula-manager.js.map
|