UNPKG

hyperformula

Version:

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

110 lines 4.12 kB
/** * @license * Copyright (c) 2025 Handsoncode. All rights reserved. */ import { CellError, ErrorType } from "./Cell.mjs"; import { DetailedCellError } from "./CellValue.mjs"; import { ErrorMessage } from "./error-message.mjs"; import { EmptyValue, getRawValue, isExtendedNumber } from "./interpreter/InterpreterValue.mjs"; import { SimpleRangeValue } from "./SimpleRangeValue.mjs"; import { NamedExpressions } from "./NamedExpressions.mjs"; import { simpleCellAddressToString } from "./parser/addressRepresentationConverters.mjs"; /** * A list of cells which values changed after the operation, their absolute addresses and new values. */ export class ExportedCellChange { constructor(address, newValue) { this.address = address; this.newValue = newValue; } get col() { return this.address.col; } get row() { return this.address.row; } get sheet() { return this.address.sheet; } get value() { return this.newValue; } } export class ExportedNamedExpressionChange { constructor(name, newValue) { this.name = name; this.newValue = newValue; } } export class Exporter { constructor(config, namedExpressions, sheetMapping, lazilyTransformingService) { this.config = config; this.namedExpressions = namedExpressions; this.sheetMapping = sheetMapping; this.lazilyTransformingService = lazilyTransformingService; } exportChange(change) { const value = change.value; const address = change.address; if (address.sheet === NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS) { const namedExpression = this.namedExpressions.namedExpressionInAddress(address.row); if (!namedExpression) { throw new Error('Missing named expression'); } return new ExportedNamedExpressionChange(namedExpression.displayName, this.exportScalarOrRange(value)); } else if (value instanceof SimpleRangeValue) { const result = []; for (const [cellValue, cellAddress] of value.entriesFromTopLeftCorner(address)) { result.push(new ExportedCellChange(cellAddress, this.exportValue(cellValue))); } return result; } else { return new ExportedCellChange(address, this.exportValue(value)); } } exportValue(value) { if (value instanceof SimpleRangeValue) { return this.detailedError(new CellError(ErrorType.VALUE, ErrorMessage.ScalarExpected)); } else if (this.config.smartRounding && isExtendedNumber(value)) { return this.cellValueRounding(getRawValue(value)); } else if (value instanceof CellError) { return this.detailedError(value); } else if (value === EmptyValue) { return null; } else { return getRawValue(value); } } exportScalarOrRange(value) { if (value instanceof SimpleRangeValue) { return value.rawData().map(row => row.map(v => this.exportValue(v))); } else { return this.exportValue(value); } } detailedError(error) { var _a, _b; let address = undefined; const originAddress = (_a = error.root) === null || _a === void 0 ? void 0 : _a.getAddress(this.lazilyTransformingService); if (originAddress !== undefined) { if (originAddress.sheet === NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS) { address = (_b = this.namedExpressions.namedExpressionInAddress(originAddress.row)) === null || _b === void 0 ? void 0 : _b.displayName; } else { address = simpleCellAddressToString(this.sheetMapping.getSheetNameOrThrowError.bind(this.sheetMapping), originAddress, -1); } } return new DetailedCellError(error, this.config.translationPackage.getErrorTranslation(error.type), address); } cellValueRounding(value) { if (value === 0) { return value; } const magnitudeMultiplierExponent = Math.floor(Math.log10(Math.abs(value))); const placesMultiplier = Math.pow(10, this.config.precisionRounding - magnitudeMultiplierExponent); if (value < 0) { return -Math.round(-value * placesMultiplier) / placesMultiplier; } else { return Math.round(value * placesMultiplier) / placesMultiplier; } } }