From 803737a893ef6e8b2b46050577e83453e774e223 Mon Sep 17 00:00:00 2001 From: Olivier TARGET Date: Tue, 15 Jun 2021 13:28:10 +0200 Subject: [PATCH] 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 --- src/PhpSpreadsheet/Reader/Xlsx.php | 16 +++++++++++ tests/PhpSpreadsheetTests/Reader/XlsxTest.php | 26 ++++++++++++++++++ .../data/Reader/XLSX/dataValidation2Test.xlsx | Bin 0 -> 11035 bytes 3 files changed, 42 insertions(+) create mode 100644 tests/data/Reader/XLSX/dataValidation2Test.xlsx diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index 8adb3bc8..da4a80d1 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -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(); } diff --git a/tests/PhpSpreadsheetTests/Reader/XlsxTest.php b/tests/PhpSpreadsheetTests/Reader/XlsxTest.php index b5b26712..611f5656 100644 --- a/tests/PhpSpreadsheetTests/Reader/XlsxTest.php +++ b/tests/PhpSpreadsheetTests/Reader/XlsxTest.php @@ -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. * diff --git a/tests/data/Reader/XLSX/dataValidation2Test.xlsx b/tests/data/Reader/XLSX/dataValidation2Test.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..55ccd5821403706dc60318b19c21d690449104a5 GIT binary patch literal 11035 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 QKmz}u!Ac52_uIe!0g`-L^#A|> literal 0 HcmV?d00001