diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f9bc6b4d0..6e383ed0c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org). Note that a ChartSheet is still only written as a normal Worksheet containing a single chart, not as an actual ChartSheet. +- Added Worksheet visibility in Ods Reader [PR #2851](https://github.com/PHPOffice/PhpSpreadsheet/pull/2851) + ### Changed - Memory and speed improvements, particularly for the Cell Collection, and the Writers. diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index eabedcc86a..ad2777a0f3 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1945,36 +1945,11 @@ parameters: count: 6 path: src/PhpSpreadsheet/Reader/Ods/PageSettings.php - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\PageSettings\\:\\:\\$masterPrintStylesCrossReference has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Ods/PageSettings.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\PageSettings\\:\\:\\$masterStylesCrossReference has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Ods/PageSettings.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\PageSettings\\:\\:\\$officeNs has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Ods/PageSettings.php - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\PageSettings\\:\\:\\$pageLayoutStyles has no type specified\\.$#" count: 1 path: src/PhpSpreadsheet/Reader/Ods/PageSettings.php - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\PageSettings\\:\\:\\$stylesFo has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Ods/PageSettings.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\PageSettings\\:\\:\\$stylesNs has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Ods/PageSettings.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\Properties\\:\\:load\\(\\) has parameter \\$namespacesMeta with no type specified\\.$#" count: 1 diff --git a/src/PhpSpreadsheet/Reader/Ods.php b/src/PhpSpreadsheet/Reader/Ods.php index 27c58edbde..7e776ab788 100644 --- a/src/PhpSpreadsheet/Reader/Ods.php +++ b/src/PhpSpreadsheet/Reader/Ods.php @@ -588,6 +588,7 @@ public function loadIntoExisting($filename, Spreadsheet $spreadsheet) break; } } + $pageSettings->setVisibilityForWorksheet($spreadsheet->getActiveSheet(), $worksheetStyleName); $pageSettings->setPrintSettingsForWorksheet($spreadsheet->getActiveSheet(), $worksheetStyleName); ++$worksheetID; } diff --git a/src/PhpSpreadsheet/Reader/Ods/PageSettings.php b/src/PhpSpreadsheet/Reader/Ods/PageSettings.php index 8d24fd0c24..4d2fd9927f 100644 --- a/src/PhpSpreadsheet/Reader/Ods/PageSettings.php +++ b/src/PhpSpreadsheet/Reader/Ods/PageSettings.php @@ -8,16 +8,41 @@ class PageSettings { + /** + * @var string + */ private $officeNs; + /** + * @var string + */ private $stylesNs; + /** + * @var string + */ private $stylesFo; + /** + * @var string + */ + private $tableNs; + + /** + * @var string[] + */ + private $tableStylesCrossReference = []; + private $pageLayoutStyles = []; + /** + * @var string[] + */ private $masterStylesCrossReference = []; + /** + * @var string[] + */ private $masterPrintStylesCrossReference = []; public function __construct(DOMDocument $styleDom) @@ -32,6 +57,7 @@ private function setDomNameSpaces(DOMDocument $styleDom): void $this->officeNs = $styleDom->lookupNamespaceUri('office'); $this->stylesNs = $styleDom->lookupNamespaceUri('style'); $this->stylesFo = $styleDom->lookupNamespaceUri('fo'); + $this->tableNs = $styleDom->lookupNamespaceUri('table'); } private function readPageSettingStyles(DOMDocument $styleDom): void @@ -98,12 +124,33 @@ public function readStyleCrossReferences(DOMDocument $contentDom): void foreach ($styleXReferences as $styleXreferenceSet) { $styleXRefName = $styleXreferenceSet->getAttributeNS($this->stylesNs, 'name'); $stylePageLayoutName = $styleXreferenceSet->getAttributeNS($this->stylesNs, 'master-page-name'); + $styleFamilyName = $styleXreferenceSet->getAttributeNS($this->stylesNs, 'family'); + if (!empty($styleFamilyName) && $styleFamilyName === 'table') { + $styleVisibility = 'true'; + foreach ($styleXreferenceSet->getElementsByTagNameNS($this->stylesNs, 'table-properties') as $tableProperties) { + $styleVisibility = $tableProperties->getAttributeNS($this->tableNs, 'display'); + } + $this->tableStylesCrossReference[$styleXRefName] = $styleVisibility; + } if (!empty($stylePageLayoutName)) { $this->masterStylesCrossReference[$styleXRefName] = $stylePageLayoutName; } } } + public function setVisibilityForWorksheet(Worksheet $worksheet, string $styleName): void + { + if (!array_key_exists($styleName, $this->tableStylesCrossReference)) { + return; + } + + $worksheet->setSheetState( + $this->tableStylesCrossReference[$styleName] === 'false' + ? Worksheet::SHEETSTATE_HIDDEN + : Worksheet::SHEETSTATE_VISIBLE + ); + } + public function setPrintSettingsForWorksheet(Worksheet $worksheet, string $styleName): void { if (!array_key_exists($styleName, $this->masterStylesCrossReference)) { diff --git a/tests/PhpSpreadsheetTests/Reader/Ods/HiddenWorksheetTest.php b/tests/PhpSpreadsheetTests/Reader/Ods/HiddenWorksheetTest.php new file mode 100644 index 0000000000..9edaa9b739 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Ods/HiddenWorksheetTest.php @@ -0,0 +1,57 @@ +spreadsheet = $reader->load($filename); + } + + public function testPageSetup(): void + { + $assertions = $this->worksheetAssertions(); + + foreach ($this->spreadsheet->getAllSheets() as $worksheet) { + if (!array_key_exists($worksheet->getTitle(), $assertions)) { + continue; + } + + $sheetAssertions = $assertions[$worksheet->getTitle()]; + foreach ($sheetAssertions as $test => $expectedResult) { + $testMethodName = 'get' . ucfirst($test); + $actualResult = $worksheet->getSheetState(); + self::assertSame( + $expectedResult, + $actualResult, + "Failed asserting sheet state {$expectedResult} for Worksheet '{$worksheet->getTitle()}' {$test}" + ); + } + } + } + + private function worksheetAssertions(): array + { + return [ + 'Sheet1' => [ + 'sheetState' => Worksheet::SHEETSTATE_VISIBLE, + ], + 'Sheet2' => [ + 'sheetState' => Worksheet::SHEETSTATE_HIDDEN, + ], + ]; + } +} diff --git a/tests/data/Reader/Ods/HiddenSheet.ods b/tests/data/Reader/Ods/HiddenSheet.ods new file mode 100644 index 0000000000..9b1d01a69c Binary files /dev/null and b/tests/data/Reader/Ods/HiddenSheet.ods differ