Xlsx Reader Better Namespace Handling Phase 1 First Bugfix (#2204)

See issue #2203. An undotted i uncrossed t. When using namespaces, need to call attributes() to access the attributes before trying to access them directly. Failure to do so in castToFormula caused problem for shared formulas.

Surprisingly, this didn't show up in unit tests. Perhaps sharing the same formula between two cells isn't common. It did show up in Chart Samples. I've added a test.

I was really inclined to merge this right away. Not to worry - I can control myself. It should be moved fairly quickly nevertheless.
This commit is contained in:
oleibman 2021-07-02 03:36:54 -07:00 committed by GitHub
parent 10a69f9983
commit 075cecd268
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 3 deletions

View File

@ -312,15 +312,16 @@ class Xlsx extends BaseReader
private function castToFormula($c, $r, &$cellDataType, &$value, &$calculatedValue, &$sharedFormulas, $castBaseType): void
{
$attr = $c->f->attributes();
$cellDataType = 'f';
$value = "={$c->f}";
$calculatedValue = self::$castBaseType($c);
// Shared formula?
if (isset($c->f['t']) && strtolower((string) $c->f['t']) == 'shared') {
$instance = (string) $c->f['si'];
if (isset($attr['t']) && strtolower((string) $attr['t']) == 'shared') {
$instance = (string) $attr['si'];
if (!isset($sharedFormulas[(string) $c->f['si']])) {
if (!isset($sharedFormulas[(string) $attr['si']])) {
$sharedFormulas[$instance] = ['master' => $r, 'formula' => $value];
} else {
$master = Coordinate::indexesFromString($sharedFormulas[$instance]['master']);

View File

@ -0,0 +1,41 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Reader\IReader;
use PHPUnit\Framework\TestCase;
class SharedFormulaTest extends TestCase
{
/**
* @var string
*/
private static $testbook = 'samples/templates/32readwriteAreaChart1.xlsx';
public function testPreliminaries(): void
{
$file = 'zip://';
$file .= self::$testbook;
$file .= '#xl/worksheets/sheet1.xml';
$data = file_get_contents($file);
// confirm that file contains shared formula
if ($data === false) {
self::fail('Unable to read file');
} else {
self::assertStringContainsString('<c r="D6"><f t="shared" ca="1" si="0"/>', $data);
self::assertStringContainsString('<c r="E6"><f t="shared" ca="1" si="0"/>', $data);
}
}
public function testLoadSheetsXlsxChart(): void
{
$filename = self::$testbook;
$reader = IOFactory::createReader('Xlsx');
$spreadsheet = $reader->load($filename, IReader::LOAD_WITH_CHARTS);
$sheet = $spreadsheet->getActiveSheet();
self::assertSame('=(RANDBETWEEN(-50,250)+100)*10', $sheet->getCell('D6')->getValue());
self::assertSame('=(RANDBETWEEN(-50,250)+100)*10', $sheet->getCell('E6')->getValue());
$spreadsheet->disconnectWorksheets();
}
}