Merge branch 'master' into Refactoring_Function_Tests-Database

This commit is contained in:
Mark Baker
2022-12-09 13:36:21 +01:00
committed by GitHub
3 changed files with 104 additions and 4 deletions
+42 -4
View File
@@ -4,8 +4,10 @@ namespace PhpOffice\PhpSpreadsheet\Worksheet;
use PhpOffice\PhpSpreadsheet\Cell\AddressRange;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\Table\TableStyle;
class Table
@@ -15,7 +17,7 @@ class Table
*
* @var string
*/
private $name = '';
private $name;
/**
* Show Header Row.
@@ -153,12 +155,48 @@ class Table
private function updateStructuredReferences(string $name): void
{
// Remember that table names are case-insensitive
$name = StringHelper::strToLower($name);
if ($this->workSheet === null || $this->name === null || $this->name === '') {
return;
}
if ($this->name !== null && StringHelper::strToLower($this->name) !== $name) {
// Remember that table names are case-insensitive
if (StringHelper::strToLower($this->name) !== StringHelper::strToLower($name)) {
// We need to check all formula cells that might contain fully-qualified Structured References
// that refer to this table, and update those formulae to reference the new table name
$spreadsheet = $this->workSheet->getParent();
foreach ($spreadsheet->getWorksheetIterator() as $sheet) {
$this->updateStructuredReferencesInCells($sheet, $name);
}
$this->updateStructuredReferencesInNamedFormulae($spreadsheet, $name);
}
}
private function updateStructuredReferencesInCells(Worksheet $worksheet, string $newName): void
{
$pattern = '/' . preg_quote($this->name) . '\[/mui';
foreach ($worksheet->getCoordinates(false) as $coordinate) {
$cell = $worksheet->getCell($coordinate);
if ($cell->getDataType() === DataType::TYPE_FORMULA) {
$formula = $cell->getValue();
if (preg_match($pattern, $formula) === 1) {
$formula = preg_replace($pattern, "{$newName}[", $formula);
$cell->setValueExplicit($formula, DataType::TYPE_FORMULA);
}
}
}
}
private function updateStructuredReferencesInNamedFormulae(Spreadsheet $spreadsheet, string $newName): void
{
$pattern = '/' . preg_quote($this->name) . '\[/mui';
foreach ($spreadsheet->getNamedFormulae() as $namedFormula) {
$formula = $namedFormula->getValue();
if (preg_match($pattern, $formula) === 1) {
$formula = preg_replace($pattern, "{$newName}[", $formula);
$namedFormula->setValue($formula); // @phpstan-ignore-line
}
}
}
@@ -0,0 +1,62 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Worksheet\Table;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PHPUnit\Framework\TestCase;
class FormulaTest extends TestCase
{
public function testCellFormulaUpdateOnTableNameChange(): void
{
$reader = new Xlsx();
$filename = 'tests/data/Worksheet/Table/TableFormulae.xlsx';
$spreadsheet = $reader->load($filename);
$worksheet = $spreadsheet->getActiveSheet();
// Verify original formulae
// Row Formula
self::assertSame("=DeptSales[[#This Row],[Sales\u{a0}Amount]]*DeptSales[[#This Row],[% Commission]]", $worksheet->getCell('E2')->getValue());
// Totals Formula
self::assertSame('=SUBTOTAL(109,DeptSales[Commission Amount])', $worksheet->getCell('E8')->getValue());
$table = $worksheet->getTableCollection()[0];
if ($table === null) {
self::markTestSkipped('Unable to read table for testing.');
}
$table->setName('tblSalesByDepartment');
// Verify modified formulae
// Row Formula
self::assertSame("=tblSalesByDepartment[[#This Row],[Sales\u{a0}Amount]]*tblSalesByDepartment[[#This Row],[% Commission]]", $worksheet->getCell('E2')->getValue());
// Totals Formula
self::assertSame('=SUBTOTAL(109,tblSalesByDepartment[Commission Amount])', $worksheet->getCell('E8')->getValue());
$spreadsheet->disconnectWorksheets();
}
public function testNamedFormulaUpdateOnTableNameChange(): void
{
$reader = new Xlsx();
$filename = 'tests/data/Worksheet/Table/TableFormulae.xlsx';
$spreadsheet = $reader->load($filename);
$table = $spreadsheet->getActiveSheet()->getTableCollection()[0];
if ($table === null) {
self::markTestSkipped('Unable to read table for testing.');
}
$namedFormula = $spreadsheet->getNamedFormula('CommissionTotal');
if ($namedFormula === null) {
self::markTestSkipped('Unable to read named formula for testing.');
}
// Verify original formula
self::assertSame('SUBTOTAL(109,DeptSales[Commission Amount])', $namedFormula->getFormula());
$table->setName('tblSalesByDepartment');
// Verify modified formula
self::assertSame('SUBTOTAL(109,tblSalesByDepartment[Commission Amount])', $namedFormula->getFormula());
$spreadsheet->disconnectWorksheets();
}
}
Binary file not shown.