diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ca1b6c663..f7a291c4ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). - Ignore fractional part of Drawing Shadow Alpha. [Issue #4415](https://github.com/PHPOffice/PhpSpreadsheet/issues/4415) [PR #4417](https://github.com/PHPOffice/PhpSpreadsheet/pull/4417) - BIN2DEC, OCT2DEC, and HEX2DEC return numbers rather than strings. [Issue #4383](https://github.com/PHPOffice/PhpSpreadsheet/issues/4383) [PR #4389](https://github.com/PHPOffice/PhpSpreadsheet/pull/4389) - Fix TREND_BEST_FIT_NO_POLY. [Issue #4400](https://github.com/PHPOffice/PhpSpreadsheet/issues/4400) [PR #4339](https://github.com/PHPOffice/PhpSpreadsheet/pull/4339) +- Column widths not preserved when using read filter. [Issue #4416](https://github.com/PHPOffice/PhpSpreadsheet/issues/4416) [PR #4423](https://github.com/PHPOffice/PhpSpreadsheet/pull/4423) - Fix typo in Style exportArray quotePrefix. [Issue #4422](https://github.com/PHPOffice/PhpSpreadsheet/issues/4422) [PR #4424](https://github.com/PHPOffice/PhpSpreadsheet/pull/4424) - Tweak Spreadsheet clone. [PR #4419](https://github.com/PHPOffice/PhpSpreadsheet/pull/4419) - Better handling of Chart DisplayBlanksAs. [Issue #4411](https://github.com/PHPOffice/PhpSpreadsheet/issues/4411) [PR #4414](https://github.com/PHPOffice/PhpSpreadsheet/pull/4414) diff --git a/src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php b/src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php index cf9046ce57..63dd4ade58 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php +++ b/src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php @@ -77,6 +77,9 @@ public function load(?IReadFilter $readFilter = null, bool $readDataOnly = false if ($this->worksheetXml === null) { return; } + if ($readFilter !== null && $readFilter::class === DefaultReadFilter::class) { + $readFilter = null; + } $columnsAttributes = []; $rowsAttributes = []; @@ -85,11 +88,7 @@ public function load(?IReadFilter $readFilter = null, bool $readDataOnly = false } if ($this->worksheetXml->sheetData && $this->worksheetXml->sheetData->row) { - $rowsAttributes = $this->readRowAttributes($this->worksheetXml->sheetData->row, $readDataOnly, $ignoreRowsWithNoCells); - } - - if ($readFilter !== null && $readFilter::class === DefaultReadFilter::class) { - $readFilter = null; + $rowsAttributes = $this->readRowAttributes($this->worksheetXml->sheetData->row, $readDataOnly, $ignoreRowsWithNoCells, $readFilter !== null); } // set columns/rows attributes @@ -123,12 +122,12 @@ public function load(?IReadFilter $readFilter = null, bool $readDataOnly = false private function isFilteredColumn(IReadFilter $readFilter, string $columnCoordinate, array $rowsAttributes): bool { foreach ($rowsAttributes as $rowCoordinate => $rowAttributes) { - if (!$readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) { - return true; + if ($readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) { + return false; } } - return false; + return true; } private function readColumnAttributes(SimpleXMLElement $worksheetCols, bool $readDataOnly): array @@ -189,27 +188,31 @@ private function isFilteredRow(IReadFilter $readFilter, int $rowCoordinate, arra return false; } - private function readRowAttributes(SimpleXMLElement $worksheetRow, bool $readDataOnly, bool $ignoreRowsWithNoCells): array + private function readRowAttributes(SimpleXMLElement $worksheetRow, bool $readDataOnly, bool $ignoreRowsWithNoCells, bool $readFilterIsNotNull): array { $rowAttributes = []; foreach ($worksheetRow as $rowx) { $row = $rowx->attributes(); if ($row !== null && (!$ignoreRowsWithNoCells || isset($rowx->c))) { + $rowIndex = (int) $row['r']; if (isset($row['ht']) && !$readDataOnly) { - $rowAttributes[(int) $row['r']]['rowHeight'] = (float) $row['ht']; + $rowAttributes[$rowIndex]['rowHeight'] = (float) $row['ht']; } if (isset($row['hidden']) && self::boolean($row['hidden'])) { - $rowAttributes[(int) $row['r']]['visible'] = false; + $rowAttributes[$rowIndex]['visible'] = false; } if (isset($row['collapsed']) && self::boolean($row['collapsed'])) { - $rowAttributes[(int) $row['r']]['collapsed'] = true; + $rowAttributes[$rowIndex]['collapsed'] = true; } if (isset($row['outlineLevel']) && (int) $row['outlineLevel'] > 0) { - $rowAttributes[(int) $row['r']]['outlineLevel'] = (int) $row['outlineLevel']; + $rowAttributes[$rowIndex]['outlineLevel'] = (int) $row['outlineLevel']; } if (isset($row['s']) && !$readDataOnly) { - $rowAttributes[(int) $row['r']]['xfIndex'] = (int) $row['s']; + $rowAttributes[$rowIndex]['xfIndex'] = (int) $row['s']; + } + if ($readFilterIsNotNull && empty($rowAttributes[$rowIndex])) { + $rowAttributes[$rowIndex]['exists'] = true; } } } diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/Issue4416Filter.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/Issue4416Filter.php new file mode 100644 index 0000000000..e7e5cbb66f --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/Issue4416Filter.php @@ -0,0 +1,18 @@ +load($file); + $sheet = $spreadsheet->getActiveSheet(); + self::assertEqualsWithDelta( + 16.5430, + $sheet->getColumnDimension('A')->getWidth(), + 1E-4 + ); + self::assertEqualsWithDelta( + 6.0, + $sheet->getColumnDimension('B')->getWidth(), + 1E-4 + ); + self::assertEqualsWithDelta( + 11.3633, + $sheet->getColumnDimension('C')->getWidth(), + 1E-4 + ); + self::assertEqualsWithDelta( + 41.0898, + $sheet->getColumnDimension('D')->getWidth(), + 1E-4 + ); + self::assertEqualsWithDelta( + 28.5, + $sheet->getRowDimension(6)->getRowHeight(), + 1E-4 + ); + $spreadsheet->disconnectWorksheets(); + } + + public function testWithFilter(): void + { + $file = self::$file; + $reader = new XlsxReader(); + $reader->setReadFilter(new Issue4416Filter()); + $spreadsheet = $reader->load($file); + $sheet = $spreadsheet->getActiveSheet(); + self::assertEqualsWithDelta( + 16.5430, + $sheet->getColumnDimension('A')->getWidth(), + 1E-4 + ); + self::assertEqualsWithDelta( + 6.0, + $sheet->getColumnDimension('B')->getWidth(), + 1E-4 + ); + self::assertEqualsWithDelta( + 11.3633, + $sheet->getColumnDimension('C')->getWidth(), + 1E-4 + ); + self::assertEqualsWithDelta( + 41.0898, + $sheet->getColumnDimension('D')->getWidth(), + 1E-4 + ); + self::assertEquals( + -1, + $sheet->getRowDimension(6)->getRowHeight(), + 'row has been filtered away' + ); + $spreadsheet->disconnectWorksheets(); + } +} diff --git a/tests/data/Reader/XLSX/issue.4416.smallauto.xlsx b/tests/data/Reader/XLSX/issue.4416.smallauto.xlsx new file mode 100644 index 0000000000..a9dc2d0a67 Binary files /dev/null and b/tests/data/Reader/XLSX/issue.4416.smallauto.xlsx differ