diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 89f50e3b..af995b7b 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2810,16 +2810,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/Ods.php - - - message: "#^Parameter \\#3 \\$subject of function preg_replace expects array\\|string, string\\|null given\\.$#" - count: 3 - path: src/PhpSpreadsheet/Reader/Ods.php - - - - message: "#^Parameter \\#3 \\$formula of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:translateSeparator\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Ods.php - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\PageSettings\\:\\:\\$officeNs has no typehint specified\\.$#" count: 1 diff --git a/src/PhpSpreadsheet/Reader/Ods.php b/src/PhpSpreadsheet/Reader/Ods.php index d4163cf7..26151cdc 100644 --- a/src/PhpSpreadsheet/Reader/Ods.php +++ b/src/PhpSpreadsheet/Reader/Ods.php @@ -783,11 +783,13 @@ class Ods extends BaseReader // Cell range reference in another sheet $value = preg_replace('/\[\$?([^\.]+)\.([^\.]+):\.([^\.]+)\]/miu', '$1!$2:$3', $value); // Cell reference in another sheet - $value = preg_replace('/\[\$?([^\.]+)\.([^\.]+)\]/miu', '$1!$2', $value); + $value = preg_replace('/\[\$?([^\.]+)\.([^\.]+)\]/miu', '$1!$2', $value ?? ''); // Cell range reference - $value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/miu', '$1:$2', $value); + $value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/miu', '$1:$2', $value ?? ''); // Simple cell reference - $value = preg_replace('/\[\.([^\.]+)\]/miu', '$1', $value); + $value = preg_replace('/\[\.([^\.]+)\]/miu', '$1', $value ?? ''); + // Convert references to defined names/formulae + $value = str_replace('$$', '', $value ?? ''); $value = Calculation::translateSeparator(';', ',', $value, $inBraces); } diff --git a/src/PhpSpreadsheet/Reader/Ods/BaseReader.php b/src/PhpSpreadsheet/Reader/Ods/BaseReader.php index 82d41710..17e2d4d5 100644 --- a/src/PhpSpreadsheet/Reader/Ods/BaseReader.php +++ b/src/PhpSpreadsheet/Reader/Ods/BaseReader.php @@ -62,8 +62,10 @@ abstract class BaseReader $value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/miu', '$1:$2', $value ?? ''); // Simple cell reference $value = preg_replace('/\[\.([^\.]+)\]/miu', '$1', $value ?? ''); + // Convert references to defined names/formulae + $value = str_replace('$$', '', $value ?? ''); - $value = Calculation::translateSeparator(';', ',', $value ?? '', $inBraces); + $value = Calculation::translateSeparator(';', ',', $value, $inBraces); } } diff --git a/src/PhpSpreadsheet/Reader/Ods/DefinedNames.php b/src/PhpSpreadsheet/Reader/Ods/DefinedNames.php index 79f5c027..6810a3c7 100644 --- a/src/PhpSpreadsheet/Reader/Ods/DefinedNames.php +++ b/src/PhpSpreadsheet/Reader/Ods/DefinedNames.php @@ -44,6 +44,7 @@ class DefinedNames extends BaseReader $expression = $definedNameElement->getAttributeNS($this->tableNs, 'expression'); $baseAddress = $this->convertToExcelAddressValue($baseAddress); + $expression = substr($expression, strpos($expression, ':=') + 1); $expression = $this->convertToExcelFormulaValue($expression); $this->addDefinedName($baseAddress, $definedName, $expression); diff --git a/tests/PhpSpreadsheetTests/Reader/Ods/DefinedNamesTest.php b/tests/PhpSpreadsheetTests/Reader/Ods/DefinedNamesTest.php new file mode 100644 index 00000000..760421ce --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Ods/DefinedNamesTest.php @@ -0,0 +1,35 @@ +spreadsheet = $reader->load($filename); + } + + public function testDefinedNames(): void + { + $worksheet = $this->spreadsheet->getActiveSheet(); + + $firstDefinedNameValue = $worksheet->getCell('First')->getValue(); + $secondDefinedNameValue = $worksheet->getCell('Second')->getValue(); + $calculatedFormulaValue = $worksheet->getCell('B2')->getCalculatedValue(); + + self::assertSame(3, $firstDefinedNameValue); + self::assertSame(4, $secondDefinedNameValue); + self::assertSame(12, $calculatedFormulaValue); + } +} diff --git a/tests/PhpSpreadsheetTests/Writer/Ods/DefinedNamesTest.php b/tests/PhpSpreadsheetTests/Writer/Ods/DefinedNamesTest.php new file mode 100644 index 00000000..1b2e30b2 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Writer/Ods/DefinedNamesTest.php @@ -0,0 +1,33 @@ +getActiveSheet(); + + $dataSet = [ + [7, 'x', 5], + ['=', '=FORMULA'], + ]; + $worksheet->fromArray($dataSet, null, 'A1'); + + $spreadsheet->addDefinedName(new NamedRange('FIRST', $worksheet, '$A$1')); + $spreadsheet->addDefinedName(new NamedRange('SECOND', $worksheet, '$C$1')); + $spreadsheet->addDefinedName(new NamedFormula('FORMULA', $worksheet, '=FIRST*SECOND')); + + $reloaded = $this->writeAndReload($spreadsheet, 'Ods'); + + self::assertSame(7, $reloaded->getActiveSheet()->getCell('FIRST')->getValue()); + self::assertSame(5, $reloaded->getActiveSheet()->getCell('SECOND')->getValue()); + self::assertSame(35, $reloaded->getActiveSheet()->getCell('B2')->getCalculatedValue()); + } +} diff --git a/tests/data/Reader/Ods/DefinedNames.ods b/tests/data/Reader/Ods/DefinedNames.ods new file mode 100644 index 00000000..4246435b Binary files /dev/null and b/tests/data/Reader/Ods/DefinedNames.ods differ