Ods defined names unit tests (#2054)

* Defined names/formulae in ODS are prefixed by $$ when used in a formula; so we need to strip this out to fully convert them to an Excel formula

* Test for ODS Writer for DefinedNames
This commit is contained in:
Mark Baker 2021-05-03 08:39:42 +02:00 committed by GitHub
parent 83e55cffcc
commit fd14da1675
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 77 additions and 14 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -0,0 +1,35 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Reader\Ods;
use PhpOffice\PhpSpreadsheet\Reader\Ods;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class DefinedNamesTest extends TestCase
{
/**
* @var Spreadsheet
*/
private $spreadsheet;
protected function setUp(): void
{
$filename = 'tests/data/Reader/Ods/DefinedNames.ods';
$reader = new Ods();
$this->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);
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Writer\Ods;
use PhpOffice\PhpSpreadsheet\NamedFormula;
use PhpOffice\PhpSpreadsheet\NamedRange;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
class DefinedNamesTest extends AbstractFunctional
{
public function testDefinedNamesWriter(): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->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());
}
}

Binary file not shown.