diff --git a/src/xlsx/conversion/cf_conversion.ts b/src/xlsx/conversion/cf_conversion.ts index 980c3eb75f..6f8069336c 100644 --- a/src/xlsx/conversion/cf_conversion.ts +++ b/src/xlsx/conversion/cf_conversion.ts @@ -1,5 +1,4 @@ import { ICON_SETS } from "../../components/icons/icons"; -import { tokenize } from "../../formulas"; import { ColorScaleMidPointThreshold, ColorScaleThreshold, @@ -8,6 +7,7 @@ import { IconThreshold, } from "../../types"; import { ExcelIconSet, XLSXConditionalFormat, XLSXDxf } from "../../types/xlsx"; +import { prefixFormulaWithEqual } from "../helpers/misc"; import { WarningTypes, XLSXImportWarningManager } from "../helpers/xlsx_parser_error_manager"; import { convertColor, hexaToInt } from "./color_conversion"; import { @@ -76,9 +76,9 @@ export function convertConditionalFormats( case "cellIs": if (!rule.operator || !rule.formula || rule.formula.length === 0) continue; operator = convertCFCellIsOperator(rule.operator); - values.push(prefixFormula(rule.formula[0])); + values.push(prefixFormulaWithEqual(rule.formula[0])); if (rule.formula.length === 2) { - values.push(prefixFormula(rule.formula[1])); + values.push(prefixFormulaWithEqual(rule.formula[1])); } break; } @@ -244,12 +244,6 @@ function convertIcons(xlsxIconSet: ExcelIconSet, index: number): string { : ICON_SETS[iconSet].good; } -/** Prefix the string by "=" if the string looks like a formula */ -function prefixFormula(formula: string): string { - const tokens = tokenize(formula); - return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula; -} - // --------------------------------------------------------------------------- // Warnings // --------------------------------------------------------------------------- diff --git a/src/xlsx/conversion/data_validation_conversion.ts b/src/xlsx/conversion/data_validation_conversion.ts index f0520a1b22..51879b171b 100644 --- a/src/xlsx/conversion/data_validation_conversion.ts +++ b/src/xlsx/conversion/data_validation_conversion.ts @@ -7,6 +7,7 @@ import { DateIsNotBetweenCriterion, } from "../../types"; import { XLSXDataValidation } from "../../types/xlsx"; +import { prefixFormulaWithEqual } from "../helpers/misc"; import { WarningTypes, XLSXImportWarningManager } from "../helpers/xlsx_parser_error_manager"; import { XLSX_DV_DATE_OPERATOR_TO_DV_TYPE_MAPPING, @@ -65,9 +66,9 @@ export function convertDataValidationRules( } function convertDecimalRule(id: number, dv: XLSXDataValidation): DataValidationRuleData { - const values = [dv.formula1.toString()]; + const values = [prefixFormulaWithEqual(dv.formula1.toString())]; if (dv.formula2) { - values.push(dv.formula2.toString()); + values.push(prefixFormulaWithEqual(dv.formula2.toString())); } return { id: id.toString(), @@ -126,7 +127,7 @@ function convertCustomRule(id: number, dv: XLSXDataValidation): DataValidationRu isBlocking: dv.errorStyle !== "warning", criterion: { type: "customFormula", - values: [`=${dv.formula1.toString()}`], + values: [prefixFormulaWithEqual(dv.formula1.toString())], }, }; } diff --git a/src/xlsx/helpers/misc.ts b/src/xlsx/helpers/misc.ts index 990d4577d6..cdcaba850f 100644 --- a/src/xlsx/helpers/misc.ts +++ b/src/xlsx/helpers/misc.ts @@ -1,3 +1,4 @@ +import { tokenize } from "../../formulas/tokenizer"; import { Dimension, ExcelHeaderData, ExcelSheetData } from "../../types"; /** @@ -80,3 +81,12 @@ export function getSheetDataHeader( } return sheetData.rows[index]; } + +/** Prefix the string by "=" if the string looks like a formula */ +export function prefixFormulaWithEqual(formula: string): string { + if (formula[0] === "=") { + return formula; + } + const tokens = tokenize(formula); + return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula; +} diff --git a/tests/__xlsx__/xlsx_demo_data.xlsx b/tests/__xlsx__/xlsx_demo_data.xlsx index 18d20909fe..dec255dfb3 100644 Binary files a/tests/__xlsx__/xlsx_demo_data.xlsx and b/tests/__xlsx__/xlsx_demo_data.xlsx differ diff --git a/tests/xlsx/xlsx_import.test.ts b/tests/xlsx/xlsx_import.test.ts index 23cc5c5737..1ee2c85be2 100644 --- a/tests/xlsx/xlsx_import.test.ts +++ b/tests/xlsx/xlsx_import.test.ts @@ -414,6 +414,18 @@ describe("Import xlsx data", () => { }); }); + test("Can import a data validation rule with a formula", () => { + const testSheet = getWorkbookSheet("jestDataValidations", convertedData)!; + const dvRule = getDataValidationBeginningAt("J2", testSheet); + expect(dvRule).toMatchObject({ + criterion: { + type: "isBetween", + values: ["=$A$2", "=2+10"], + }, + ranges: ["J2:J6"], + }); + }); + test.each([ ["2 colors max", "H2"], ["3 colors max", "H3"],