Fix for #2149 / Read data validations for drop down list in another sheet. (#2150)

* Read data validations for drop down list in another sheet.

* Add function testLoadXlsxDataValidationOfAnotherSheet() in class tests/PhpSpreadsheetTests/Reader/XlsxTest.php for unit test.

* Add sample xlsx for unit tests.

* Modifiy call function isset() for warnings.

* Additional assertions to ensure that the worksheet has been read correctly for DataValidation that references a list on a different worksheet

* This should resolve the phpstan issues

Co-authored-by: Mark Baker <mark@lange.demon.co.uk>
This commit is contained in:
Olivier TARGET 2021-06-15 13:28:10 +02:00 committed by GitHub
parent 1e74282259
commit 803737a893
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 0 deletions

View File

@ -797,6 +797,22 @@ class Xlsx extends BaseReader
$unparsedLoadedData = (new PageSetup($docSheet, $xmlSheet))->load($unparsedLoadedData);
}
if ($xmlSheet !== false && isset($xmlSheet->extLst, $xmlSheet->extLst->ext, $xmlSheet->extLst->ext['uri']) && ($xmlSheet->extLst->ext['uri'] == '{CCE6A557-97BC-4b89-ADB6-D9C93CAAB3DF}')) {
// Create dataValidations node if does not exists, maybe is better inside the foreach ?
if (!$xmlSheet->dataValidations) {
$xmlSheet->addChild('dataValidations');
}
foreach ($xmlSheet->extLst->ext->children('x14', true)->dataValidations->dataValidation as $item) {
$node = $xmlSheet->dataValidations->addChild('dataValidation');
foreach ($item->attributes() as $attr) {
$node->addAttribute($attr->getName(), $attr);
}
$node->addAttribute('sqref', $item->children('xm', true)->sqref);
$node->addChild('formula1', $item->formula1->children('xm', true)->f);
}
}
if ($xmlSheet && $xmlSheet->dataValidations && !$this->readDataOnly) {
(new DataValidations($docSheet, $xmlSheet))->load();
}

View File

@ -3,6 +3,7 @@
namespace PhpOffice\PhpSpreadsheetTests\Reader;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
use PhpOffice\PhpSpreadsheet\Document\Properties;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Shared\File;
@ -147,6 +148,31 @@ class XlsxTest extends TestCase
self::assertTrue($worksheet->getCell('B3')->hasDataValidation());
}
/*
* Test for load drop down lists of another sheet.
* Pull #2150, issue #2149
*/
public function testLoadXlsxDataValidationOfAnotherSheet(): void
{
$filename = 'tests/data/Reader/XLSX/dataValidation2Test.xlsx';
$reader = new Xlsx();
$spreadsheet = $reader->load($filename);
$worksheet = $spreadsheet->getActiveSheet();
// same sheet
$validationCell = $worksheet->getCell('B5');
self::assertTrue($validationCell->hasDataValidation());
self::assertSame(DataValidation::TYPE_LIST, $validationCell->getDataValidation()->getType());
self::assertSame('$A$5:$A$7', $validationCell->getDataValidation()->getFormula1());
// another sheet
$validationCell = $worksheet->getCell('B14');
self::assertTrue($validationCell->hasDataValidation());
self::assertSame(DataValidation::TYPE_LIST, $validationCell->getDataValidation()->getType());
self::assertSame('Feuil2!$A$3:$A$5', $validationCell->getDataValidation()->getFormula1());
}
/**
* Test load Xlsx file without cell reference.
*

Binary file not shown.