From 60ade80c0fb6943e9d16195a617afc5bda6d3b37 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 20 May 2021 22:38:28 +0200 Subject: [PATCH] Resolve Issue with float values losing their decimal when read from SpreadsheetML --- src/PhpSpreadsheet/Cell/AddressHelper.php | 30 ++++++++++++------- .../ConvertFormulaToA1FromSpreadsheetXml.php | 2 ++ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/PhpSpreadsheet/Cell/AddressHelper.php b/src/PhpSpreadsheet/Cell/AddressHelper.php index cf5b0347..81eea788 100644 --- a/src/PhpSpreadsheet/Cell/AddressHelper.php +++ b/src/PhpSpreadsheet/Cell/AddressHelper.php @@ -49,6 +49,22 @@ class AddressHelper return $A1CellReference; } + protected static function convertSpreadsheetMLFormula(string $formula): string + { + $formula = substr($formula, 3); + $temp = explode('"', $formula); + $key = false; + foreach ($temp as &$value) { + // Only replace in alternate array entries (i.e. non-quoted blocks) + if ($key = !$key) { + $value = str_replace(['[.', ':.', ']'], ['', ':', ''], $value); + } + } + unset($value); + + return implode('"', $temp); + } + /** * Converts a formula that uses R1C1/SpreadsheetXML format cell address to an A1 format cell address. */ @@ -58,15 +74,8 @@ class AddressHelper int $currentColumnNumber = 1 ): string { if (substr($formula, 0, 3) == 'of:') { - $formula = substr($formula, 3); - $temp = explode('"', $formula); - $key = false; - foreach ($temp as &$value) { - // Only replace in alternate array entries (i.e. non-quoted blocks) - if ($key = !$key) { - $value = str_replace(['[.', '.', ']'], '', $value); - } - } + // We have a SpreasheetML Formula + return self::convertSpreadsheetMLFormula($formula); } else { // Convert R1C1 style references to A1 style references (but only when not quoted) $temp = explode('"', $formula); @@ -87,8 +96,9 @@ class AddressHelper } } } + unset($value); } - unset($value); + // Then rebuild the formula string $formula = implode('"', $temp); diff --git a/tests/data/Cell/ConvertFormulaToA1FromSpreadsheetXml.php b/tests/data/Cell/ConvertFormulaToA1FromSpreadsheetXml.php index e9878e3b..d350c07b 100644 --- a/tests/data/Cell/ConvertFormulaToA1FromSpreadsheetXml.php +++ b/tests/data/Cell/ConvertFormulaToA1FromSpreadsheetXml.php @@ -10,4 +10,6 @@ return [ 'Formula arithmetic' => ['=SUM(E1:E5, D5)-C5', 'of:=SUM([.E1:.E5], [.D5])-[.C5]'], 'Formula with comparison' => ['=IF(E1>E2, E3, E4)', 'of:=IF([.E1]>[.E2], [.E3], [.E4])'], 'String literal' => ['=CONCAT("Result of formula expression =[.C3]+[.C4] is: ", C3+C4)', 'of:=CONCAT("Result of formula expression =[.C3]+[.C4] is: ", [.C3]+[.C4])'], + 'Simple numeric addition' => ['=1.23+2.34', 'of:=1.23+2.34'], + 'More complex formula with cells and numeric literals' => ['=D3+F7+G4+C6+5.67', 'of:=[.D3]+[.F7]+[.G4]+[.C6]+5.67'], ];