From 339a5933c7285f68428bb17067ee5ed8f245ecd6 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 8 Oct 2022 12:42:01 +0200 Subject: [PATCH] Allow single cell AutoFilter range --- src/PhpSpreadsheet/Worksheet/AutoFilter.php | 8 +++++--- src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php | 4 +++- .../Worksheet/AutoFilter/AutoFilterTest.php | 16 ++++++++++++++-- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/PhpSpreadsheet/Worksheet/AutoFilter.php b/src/PhpSpreadsheet/Worksheet/AutoFilter.php index 05b2e9a0..3ad5f9bd 100644 --- a/src/PhpSpreadsheet/Worksheet/AutoFilter.php +++ b/src/PhpSpreadsheet/Worksheet/AutoFilter.php @@ -9,6 +9,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Internal\WildcardMatch; use PhpOffice\PhpSpreadsheet\Cell\AddressRange; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; +use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException; use PhpOffice\PhpSpreadsheet\Shared\Date; use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule; @@ -104,7 +105,7 @@ class AutoFilter * Set AutoFilter Cell Range. * * @param AddressRange|array|string $range - * A simple string containing a Cell range like 'A1:E10' is permitted + * A simple string containing a Cell range like 'A1:E10' or a Cell address like 'A1' is permitted * or passing in an array of [$fromColumnIndex, $fromRow, $toColumnIndex, $toRow] (e.g. [3, 5, 6, 8]), * or an AddressRange object. */ @@ -115,6 +116,7 @@ class AutoFilter if ($range !== '') { [, $range] = Worksheet::extractSheetTitle(Validations::validateCellRange($range), true); } + if (empty($range)) { // Discard all column rules $this->columns = []; @@ -123,8 +125,8 @@ class AutoFilter return $this; } - if (strpos($range, ':') === false) { - throw new PhpSpreadsheetException('Autofilter must be set on a range of cells.'); + if (ctype_digit($range) || ctype_alpha($range)) { + throw new Exception("{$range} is an invalid range for AutoFilter"); } $this->range = $range; diff --git a/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php b/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php index b3338c07..0ca9f64f 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php @@ -115,7 +115,9 @@ class DefinedNames [, $range[0]] = Worksheet::extractSheetTitle($range[0], true); $range[0] = Coordinate::absoluteCoordinate($range[0]); - $range[1] = Coordinate::absoluteCoordinate($range[1]); + if (count($range) > 1) { + $range[1] = Coordinate::absoluteCoordinate($range[1]); + } $range = implode(':', $range); $this->objWriter->writeRawData('\'' . str_replace("'", "''", $worksheet->getTitle()) . '\'!' . $range); diff --git a/tests/PhpSpreadsheetTests/Worksheet/AutoFilter/AutoFilterTest.php b/tests/PhpSpreadsheetTests/Worksheet/AutoFilter/AutoFilterTest.php index a80d3d63..54af9e0f 100644 --- a/tests/PhpSpreadsheetTests/Worksheet/AutoFilter/AutoFilterTest.php +++ b/tests/PhpSpreadsheetTests/Worksheet/AutoFilter/AutoFilterTest.php @@ -65,6 +65,7 @@ class AutoFilterTest extends SetupTeardown $ranges = [ 'G1:J512' => "$title!G1:J512", 'K1:N20' => 'K1:N20', + 'B10' => 'B10', ]; foreach ($ranges as $actualRange => $fullRange) { @@ -94,11 +95,22 @@ class AutoFilterTest extends SetupTeardown self::assertEquals($expectedResult, $result); } - public function testSetRangeInvalidRange(): void + public function testSetRangeInvalidRowRange(): void { $this->expectException(PhpSpreadsheetException::class); - $expectedResult = 'A1'; + $expectedResult = '999'; + + $sheet = $this->getSheet(); + $autoFilter = $sheet->getAutoFilter(); + $autoFilter->setRange($expectedResult); + } + + public function testSetRangeInvalidColumnRange(): void + { + $this->expectException(PhpSpreadsheetException::class); + + $expectedResult = 'ABC'; $sheet = $this->getSheet(); $autoFilter = $sheet->getAutoFilter();