UNPKG

hyperformula

Version:

HyperFormula is a JavaScript engine for efficient processing of spreadsheet-like data and formulas

160 lines 7.12 kB
/** * @license * Copyright (c) 2025 Handsoncode. All rights reserved. */ import { absoluteSheetReference, invalidSimpleCellAddress, simpleCellAddress, simpleColumnAddress, simpleRowAddress } from "../Cell.mjs"; import { columnIndexToLabel } from "./addressRepresentationConverters.mjs"; import { ColumnAddress, ReferenceType } from "./ColumnAddress.mjs"; import { RowAddress } from "./RowAddress.mjs"; /** Possible kinds of cell references */ export var CellReferenceType; (function (CellReferenceType) { /** Cell reference with both row and column relative. */ CellReferenceType["CELL_REFERENCE_RELATIVE"] = "CELL_REFERENCE"; /** Cell reference with both row and column absolute. */ CellReferenceType["CELL_REFERENCE_ABSOLUTE"] = "CELL_REFERENCE_ABSOLUTE"; /** Cell reference with absolute column and relative row. */ CellReferenceType["CELL_REFERENCE_ABSOLUTE_COL"] = "CELL_REFERENCE_ABSOLUTE_COL"; /** Cell reference with relative column and absolute row. */ CellReferenceType["CELL_REFERENCE_ABSOLUTE_ROW"] = "CELL_REFERENCE_ABSOLUTE_ROW"; })(CellReferenceType || (CellReferenceType = {})); export class CellAddress { constructor(col, row, type, sheet) { this.col = col; this.row = row; this.type = type; this.sheet = sheet; } static fromColAndRow(col, row, sheet) { const factoryMethod = col.isColumnAbsolute() && row.isRowAbsolute() ? CellAddress.absolute.bind(this) : col.isColumnAbsolute() ? CellAddress.absoluteCol.bind(this) : row.isRowAbsolute() ? CellAddress.absoluteRow.bind(this) : CellAddress.relative.bind(this); return factoryMethod(col.col, row.row, sheet); } static relative(col, row, sheet) { return new CellAddress(col, row, CellReferenceType.CELL_REFERENCE_RELATIVE, sheet); } static absolute(col, row, sheet) { return new CellAddress(col, row, CellReferenceType.CELL_REFERENCE_ABSOLUTE, sheet); } static absoluteCol(col, row, sheet) { return new CellAddress(col, row, CellReferenceType.CELL_REFERENCE_ABSOLUTE_COL, sheet); } static absoluteRow(col, row, sheet) { return new CellAddress(col, row, CellReferenceType.CELL_REFERENCE_ABSOLUTE_ROW, sheet); } /** * Converts R0C0 representation of cell address to simple object representation. * * @param baseAddress - base address for R0C0 shifts */ toSimpleCellAddress(baseAddress) { const sheet = absoluteSheetReference(this, baseAddress); if (this.type === CellReferenceType.CELL_REFERENCE_ABSOLUTE) { return simpleCellAddress(sheet, this.col, this.row); } else if (this.type === CellReferenceType.CELL_REFERENCE_ABSOLUTE_ROW) { return simpleCellAddress(sheet, baseAddress.col + this.col, this.row); } else if (this.type === CellReferenceType.CELL_REFERENCE_ABSOLUTE_COL) { return simpleCellAddress(sheet, this.col, baseAddress.row + this.row); } else { return simpleCellAddress(sheet, baseAddress.col + this.col, baseAddress.row + this.row); } } toColumnAddress() { const refType = this.isColumnRelative() ? ReferenceType.RELATIVE : ReferenceType.ABSOLUTE; return new ColumnAddress(refType, this.col, this.sheet); } toRowAddress() { const refType = this.isRowRelative() ? ReferenceType.RELATIVE : ReferenceType.ABSOLUTE; return new RowAddress(refType, this.row, this.sheet); } toSimpleColumnAddress(baseAddress) { const sheet = absoluteSheetReference(this, baseAddress); let column = this.col; if (this.isColumnRelative()) { column += baseAddress.col; } return simpleColumnAddress(sheet, column); } toSimpleRowAddress(baseAddress) { const sheet = absoluteSheetReference(this, baseAddress); let row = this.row; if (this.isRowRelative()) { row += baseAddress.row; } return simpleRowAddress(sheet, row); } isRowAbsolute() { return this.type === CellReferenceType.CELL_REFERENCE_ABSOLUTE || this.type === CellReferenceType.CELL_REFERENCE_ABSOLUTE_ROW; } isColumnAbsolute() { return this.type === CellReferenceType.CELL_REFERENCE_ABSOLUTE || this.type === CellReferenceType.CELL_REFERENCE_ABSOLUTE_COL; } isColumnRelative() { return this.type === CellReferenceType.CELL_REFERENCE_RELATIVE || this.type === CellReferenceType.CELL_REFERENCE_ABSOLUTE_ROW; } isRowRelative() { return this.type === CellReferenceType.CELL_REFERENCE_RELATIVE || this.type === CellReferenceType.CELL_REFERENCE_ABSOLUTE_COL; } isAbsolute() { return this.type === CellReferenceType.CELL_REFERENCE_ABSOLUTE && this.sheet !== undefined; } shiftedByRows(numberOfRows) { return new CellAddress(this.col, this.row + numberOfRows, this.type, this.sheet); } shiftedByColumns(numberOfColumns) { return new CellAddress(this.col + numberOfColumns, this.row, this.type, this.sheet); } moved(toSheet, toRight, toBottom) { const newSheet = this.sheet === undefined ? undefined : toSheet; return new CellAddress(this.col + toRight, this.row + toBottom, this.type, newSheet); } withSheet(sheet) { return new CellAddress(this.col, this.row, this.type, sheet); } isInvalid(baseAddress) { return invalidSimpleCellAddress(this.toSimpleCellAddress(baseAddress)); } shiftRelativeDimensions(toRight, toBottom) { const col = this.isColumnAbsolute() ? this.col : this.col + toRight; const row = this.isRowAbsolute() ? this.row : this.row + toBottom; return new CellAddress(col, row, this.type, this.sheet); } shiftAbsoluteDimensions(toRight, toBottom) { const col = this.isColumnRelative() ? this.col : this.col + toRight; const row = this.isRowRelative() ? this.row : this.row + toBottom; return new CellAddress(col, row, this.type, this.sheet); } hash(withSheet) { const sheetPart = withSheet && this.sheet !== undefined ? `#${this.sheet}` : ''; switch (this.type) { case CellReferenceType.CELL_REFERENCE_RELATIVE: { return `${sheetPart}#${this.row}R${this.col}`; } case CellReferenceType.CELL_REFERENCE_ABSOLUTE: { return `${sheetPart}#${this.row}A${this.col}`; } case CellReferenceType.CELL_REFERENCE_ABSOLUTE_COL: { return `${sheetPart}#${this.row}AC${this.col}`; } case CellReferenceType.CELL_REFERENCE_ABSOLUTE_ROW: { return `${sheetPart}#${this.row}AR${this.col}`; } } } unparse(baseAddress) { const simpleAddress = this.toSimpleCellAddress(baseAddress); if (invalidSimpleCellAddress(simpleAddress)) { return undefined; } const column = columnIndexToLabel(simpleAddress.col); const rowDollar = this.type === CellReferenceType.CELL_REFERENCE_ABSOLUTE || this.type === CellReferenceType.CELL_REFERENCE_ABSOLUTE_ROW ? '$' : ''; const colDollar = this.type === CellReferenceType.CELL_REFERENCE_ABSOLUTE || this.type === CellReferenceType.CELL_REFERENCE_ABSOLUTE_COL ? '$' : ''; return `${colDollar}${column}${rowDollar}${simpleAddress.row + 1}`; } exceedsSheetSizeLimits(maxColumns, maxRows) { return this.row >= maxRows || this.col >= maxColumns; } }