Fix for 3 Issues Involving ReadXlsx and NamedRange (#1742)
* Fix for 3 Issues Involving ReadXlsx and NamedRange Issues #1686 and #1723, which provide sample spreadsheets, are probably solved by this ticket. Issue #1730 is also probably solved, but I have no way to verify. There are two problems with how PhpSpreadsheet is handling things now. Although the first problem is much less severe, and isn't really a factor in the issues named above, it is helpful to get it out of the way first. If you define a named range in Excel, and then delete the sheet where the range exists, Excel saves the range as #REF!. If there is a cell which references the range, it will similarly have the value #REF! when you open the Excel file. Currently, PhpSpreadsheet discards the #REF! definition, so a cell which references the range will appear as #NAME? rather than #REF!. This PR changes the behavior so that PhpSpreadsheet retains the #REF! definition, and cells which reference it will appear as #REF!. The second problem is the more severe, and is, I believe, responsible for the 3 issues identified above. If you define a named range and the sheet on which the range is defined does not exist at the time, Excel will save the range as something like: '[1]Unknown Sheet'!$A$1 If a cell references such a range, Excel will again display #REF!. PhpSpreadsheet currently throws an Exception when it encounters such a definition while reading the file. This PR changes the behavior so that PhpSpreadsheet saves the definition as #REF!, and cells which reference it will behave similarly. For the record, I will note that Excel does not magically recalculate when a missing sheet is subsequently added, despite the fact that the reference might now become resolvable. PhpSpreadsheet behaves likewise. * Remove Dead Code in Test Identified it after push but before merge.
This commit is contained in:
parent
ff04c8502a
commit
497a934374
|
@ -1280,7 +1280,7 @@ class Xlsx extends BaseReader
|
||||||
}
|
}
|
||||||
|
|
||||||
// Valid range?
|
// Valid range?
|
||||||
if (stripos((string) $definedName, '#REF!') !== false || $extractedRange == '') {
|
if ($extractedRange == '') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1350,7 +1350,7 @@ class Xlsx extends BaseReader
|
||||||
$extractedRange = (string) $definedName;
|
$extractedRange = (string) $definedName;
|
||||||
|
|
||||||
// Valid range?
|
// Valid range?
|
||||||
if (stripos((string) $definedName, '#REF!') !== false || $extractedRange == '') {
|
if ($extractedRange == '') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1398,6 +1398,9 @@ class Xlsx extends BaseReader
|
||||||
$locatedSheet = $excel->getSheetByName($extractedSheetName);
|
$locatedSheet = $excel->getSheetByName($extractedSheetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($locatedSheet === null && !DefinedName::testIfFormula($definedRange)) {
|
||||||
|
$definedRange = '#REF!';
|
||||||
|
}
|
||||||
$excel->addDefinedName(DefinedName::createInstance((string) $definedName['name'], $locatedSheet, $definedRange, false));
|
$excel->addDefinedName(DefinedName::createInstance((string) $definedName['name'], $locatedSheet, $definedRange, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class NamedRangeTest extends TestCase
|
||||||
|
{
|
||||||
|
public static function testBug1686b(): void
|
||||||
|
{
|
||||||
|
$xlsxFile = 'tests/data/Reader/XLSX/bug1686b.xlsx';
|
||||||
|
$reader = new Xlsx();
|
||||||
|
$spreadsheet = $reader->load($xlsxFile);
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
self::assertEquals(2.1, $sheet->getCell('A1')->getCalculatedValue());
|
||||||
|
self::assertEquals('#REF!', $sheet->getCell('A2')->getCalculatedValue());
|
||||||
|
self::assertEquals('#REF!', $sheet->getCell('A3')->getCalculatedValue());
|
||||||
|
self::assertEquals('#NAME?', $sheet->getCell('A4')->getCalculatedValue());
|
||||||
|
self::assertEquals('#REF!', $sheet->getCell('A5')->getCalculatedValue());
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Loading…
Reference in New Issue