Skip to content

Commit 8aee491

Browse files
authored
Merge pull request #4423 from oleibman/issue4416
Column Widths Not Preserved When Using Read Filter
2 parents f52ae20 + 2213139 commit 8aee491

File tree

5 files changed

+118
-14
lines changed

5 files changed

+118
-14
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
3939
- 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)
4040
- 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)
4141
- Fix TREND_BEST_FIT_NO_POLY. [Issue #4400](https://github.com/PHPOffice/PhpSpreadsheet/issues/4400) [PR #4339](https://github.com/PHPOffice/PhpSpreadsheet/pull/4339)
42+
- 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)
4243
- Fix typo in Style exportArray quotePrefix. [Issue #4422](https://github.com/PHPOffice/PhpSpreadsheet/issues/4422) [PR #4424](https://github.com/PHPOffice/PhpSpreadsheet/pull/4424)
4344
- Tweak Spreadsheet clone. [PR #4419](https://github.com/PHPOffice/PhpSpreadsheet/pull/4419)
4445
- Better handling of Chart DisplayBlanksAs. [Issue #4411](https://github.com/PHPOffice/PhpSpreadsheet/issues/4411) [PR #4414](https://github.com/PHPOffice/PhpSpreadsheet/pull/4414)

src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php

+17-14
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ public function load(?IReadFilter $readFilter = null, bool $readDataOnly = false
7777
if ($this->worksheetXml === null) {
7878
return;
7979
}
80+
if ($readFilter !== null && $readFilter::class === DefaultReadFilter::class) {
81+
$readFilter = null;
82+
}
8083

8184
$columnsAttributes = [];
8285
$rowsAttributes = [];
@@ -85,11 +88,7 @@ public function load(?IReadFilter $readFilter = null, bool $readDataOnly = false
8588
}
8689

8790
if ($this->worksheetXml->sheetData && $this->worksheetXml->sheetData->row) {
88-
$rowsAttributes = $this->readRowAttributes($this->worksheetXml->sheetData->row, $readDataOnly, $ignoreRowsWithNoCells);
89-
}
90-
91-
if ($readFilter !== null && $readFilter::class === DefaultReadFilter::class) {
92-
$readFilter = null;
91+
$rowsAttributes = $this->readRowAttributes($this->worksheetXml->sheetData->row, $readDataOnly, $ignoreRowsWithNoCells, $readFilter !== null);
9392
}
9493

9594
// set columns/rows attributes
@@ -123,12 +122,12 @@ public function load(?IReadFilter $readFilter = null, bool $readDataOnly = false
123122
private function isFilteredColumn(IReadFilter $readFilter, string $columnCoordinate, array $rowsAttributes): bool
124123
{
125124
foreach ($rowsAttributes as $rowCoordinate => $rowAttributes) {
126-
if (!$readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) {
127-
return true;
125+
if ($readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) {
126+
return false;
128127
}
129128
}
130129

131-
return false;
130+
return true;
132131
}
133132

134133
private function readColumnAttributes(SimpleXMLElement $worksheetCols, bool $readDataOnly): array
@@ -189,27 +188,31 @@ private function isFilteredRow(IReadFilter $readFilter, int $rowCoordinate, arra
189188
return false;
190189
}
191190

192-
private function readRowAttributes(SimpleXMLElement $worksheetRow, bool $readDataOnly, bool $ignoreRowsWithNoCells): array
191+
private function readRowAttributes(SimpleXMLElement $worksheetRow, bool $readDataOnly, bool $ignoreRowsWithNoCells, bool $readFilterIsNotNull): array
193192
{
194193
$rowAttributes = [];
195194

196195
foreach ($worksheetRow as $rowx) {
197196
$row = $rowx->attributes();
198197
if ($row !== null && (!$ignoreRowsWithNoCells || isset($rowx->c))) {
198+
$rowIndex = (int) $row['r'];
199199
if (isset($row['ht']) && !$readDataOnly) {
200-
$rowAttributes[(int) $row['r']]['rowHeight'] = (float) $row['ht'];
200+
$rowAttributes[$rowIndex]['rowHeight'] = (float) $row['ht'];
201201
}
202202
if (isset($row['hidden']) && self::boolean($row['hidden'])) {
203-
$rowAttributes[(int) $row['r']]['visible'] = false;
203+
$rowAttributes[$rowIndex]['visible'] = false;
204204
}
205205
if (isset($row['collapsed']) && self::boolean($row['collapsed'])) {
206-
$rowAttributes[(int) $row['r']]['collapsed'] = true;
206+
$rowAttributes[$rowIndex]['collapsed'] = true;
207207
}
208208
if (isset($row['outlineLevel']) && (int) $row['outlineLevel'] > 0) {
209-
$rowAttributes[(int) $row['r']]['outlineLevel'] = (int) $row['outlineLevel'];
209+
$rowAttributes[$rowIndex]['outlineLevel'] = (int) $row['outlineLevel'];
210210
}
211211
if (isset($row['s']) && !$readDataOnly) {
212-
$rowAttributes[(int) $row['r']]['xfIndex'] = (int) $row['s'];
212+
$rowAttributes[$rowIndex]['xfIndex'] = (int) $row['s'];
213+
}
214+
if ($readFilterIsNotNull && empty($rowAttributes[$rowIndex])) {
215+
$rowAttributes[$rowIndex]['exists'] = true;
213216
}
214217
}
215218
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
6+
7+
use PhpOffice\PhpSpreadsheet\Reader\IReadFilter;
8+
9+
class Issue4416Filter implements IReadFilter
10+
{
11+
public function readCell(string $columnAddress, int $row, string $worksheetName = ''): bool
12+
{
13+
$allowedColumns = ['A', 'B', 'C', 'D'];
14+
$allowedRows = range(1, 5);
15+
16+
return in_array($columnAddress, $allowedColumns, true) && in_array($row, $allowedRows, true);
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
6+
7+
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
8+
use PHPUnit\Framework\TestCase;
9+
10+
class Issue4416Test extends TestCase
11+
{
12+
private static string $file = 'tests/data/Reader/XLSX/issue.4416.smallauto.xlsx';
13+
14+
public function testNoFilter(): void
15+
{
16+
$file = self::$file;
17+
$reader = new XlsxReader();
18+
$spreadsheet = $reader->load($file);
19+
$sheet = $spreadsheet->getActiveSheet();
20+
self::assertEqualsWithDelta(
21+
16.5430,
22+
$sheet->getColumnDimension('A')->getWidth(),
23+
1E-4
24+
);
25+
self::assertEqualsWithDelta(
26+
6.0,
27+
$sheet->getColumnDimension('B')->getWidth(),
28+
1E-4
29+
);
30+
self::assertEqualsWithDelta(
31+
11.3633,
32+
$sheet->getColumnDimension('C')->getWidth(),
33+
1E-4
34+
);
35+
self::assertEqualsWithDelta(
36+
41.0898,
37+
$sheet->getColumnDimension('D')->getWidth(),
38+
1E-4
39+
);
40+
self::assertEqualsWithDelta(
41+
28.5,
42+
$sheet->getRowDimension(6)->getRowHeight(),
43+
1E-4
44+
);
45+
$spreadsheet->disconnectWorksheets();
46+
}
47+
48+
public function testWithFilter(): void
49+
{
50+
$file = self::$file;
51+
$reader = new XlsxReader();
52+
$reader->setReadFilter(new Issue4416Filter());
53+
$spreadsheet = $reader->load($file);
54+
$sheet = $spreadsheet->getActiveSheet();
55+
self::assertEqualsWithDelta(
56+
16.5430,
57+
$sheet->getColumnDimension('A')->getWidth(),
58+
1E-4
59+
);
60+
self::assertEqualsWithDelta(
61+
6.0,
62+
$sheet->getColumnDimension('B')->getWidth(),
63+
1E-4
64+
);
65+
self::assertEqualsWithDelta(
66+
11.3633,
67+
$sheet->getColumnDimension('C')->getWidth(),
68+
1E-4
69+
);
70+
self::assertEqualsWithDelta(
71+
41.0898,
72+
$sheet->getColumnDimension('D')->getWidth(),
73+
1E-4
74+
);
75+
self::assertEquals(
76+
-1,
77+
$sheet->getRowDimension(6)->getRowHeight(),
78+
'row has been filtered away'
79+
);
80+
$spreadsheet->disconnectWorksheets();
81+
}
82+
}
9.39 KB
Binary file not shown.

0 commit comments

Comments
 (0)