Calculate row range for a single-row AutoFilter range
This commit is contained in:
parent
339a5933c7
commit
720b98a97f
|
|
@ -10,7 +10,6 @@ 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;
|
||||
|
||||
|
|
@ -176,13 +175,13 @@ class AutoFilter
|
|||
public function testColumnInRange($column)
|
||||
{
|
||||
if (empty($this->range)) {
|
||||
throw new PhpSpreadsheetException('No autofilter range is defined.');
|
||||
throw new Exception('No autofilter range is defined.');
|
||||
}
|
||||
|
||||
$columnIndex = Coordinate::columnIndexFromString($column);
|
||||
[$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($this->range);
|
||||
if (($rangeStart[0] > $columnIndex) || ($rangeEnd[0] < $columnIndex)) {
|
||||
throw new PhpSpreadsheetException('Column is outside of current autofilter range.');
|
||||
throw new Exception('Column is outside of current autofilter range.');
|
||||
}
|
||||
|
||||
return $columnIndex - $rangeStart[0];
|
||||
|
|
@ -249,7 +248,7 @@ class AutoFilter
|
|||
} elseif (is_object($columnObjectOrString) && ($columnObjectOrString instanceof AutoFilter\Column)) {
|
||||
$column = $columnObjectOrString->getColumnIndex();
|
||||
} else {
|
||||
throw new PhpSpreadsheetException('Column is not within the autofilter range.');
|
||||
throw new Exception('Column is not within the autofilter range.');
|
||||
}
|
||||
$this->testColumnInRange($column);
|
||||
|
||||
|
|
@ -1033,6 +1032,8 @@ class AutoFilter
|
|||
}
|
||||
}
|
||||
|
||||
$rangeEnd[1] = $this->autoExtendRange($rangeStart[1], $rangeEnd[1]);
|
||||
|
||||
// Execute the column tests for each row in the autoFilter range to determine show/hide,
|
||||
for ($row = $rangeStart[1] + 1; $row <= $rangeEnd[1]; ++$row) {
|
||||
$result = true;
|
||||
|
|
@ -1055,6 +1056,29 @@ class AutoFilter
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Range Auto-sizing.
|
||||
* For a single row rangeSet, we follow MS Excel rules, and search for the first empty row to determine our range.
|
||||
*/
|
||||
public function autoExtendRange(int $startRow, int $endRow): int
|
||||
{
|
||||
if ($startRow === $endRow && $this->workSheet !== null) {
|
||||
try {
|
||||
$rowIterator = $this->workSheet->getRowIterator($startRow + 1);
|
||||
} catch (Exception $e) {
|
||||
// If there are no rows below $startRow
|
||||
return $startRow;
|
||||
}
|
||||
foreach ($rowIterator as $row) {
|
||||
if ($row->isEmpty(CellIterator::TREAT_NULL_VALUE_AS_EMPTY_CELL | CellIterator::TREAT_EMPTY_STRING_AS_EMPTY_CELL) === true) {
|
||||
return $row->getRowIndex() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $endRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement PHP __clone to create a deep clone, not just a shallow copy.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -510,4 +510,26 @@ class AutoFilterTest extends SetupTeardown
|
|||
self::assertArrayHasKey('K', $columns);
|
||||
self::assertArrayHasKey('M', $columns);
|
||||
}
|
||||
|
||||
public function testAutoExtendRange(): void
|
||||
{
|
||||
$spreadsheet = $this->getSpreadsheet();
|
||||
$worksheet = $spreadsheet->addSheet(new Worksheet($spreadsheet, 'Autosized AutoFilter'));
|
||||
|
||||
$worksheet->getCell('A1')->setValue('Col 1');
|
||||
$worksheet->getCell('B1')->setValue('Col 2');
|
||||
|
||||
$worksheet->setAutoFilter('A1:B1');
|
||||
$lastRow = $worksheet->getAutoFilter()->autoExtendRange(1, 1);
|
||||
self::assertSame(1, $lastRow, 'No data below AutoFilter, so there should ne no resize');
|
||||
|
||||
$lastRow = $worksheet->getAutoFilter()->autoExtendRange(1, 999);
|
||||
self::assertSame(999, $lastRow, 'Filter range is already correctly sized');
|
||||
|
||||
$data = [['A', 'A'], ['B', 'A'], ['A', 'B'], ['C', 'B'], ['B', null], [null, null], ['D', 'D'], ['E', 'E']];
|
||||
$worksheet->fromArray($data, null, 'A2', true);
|
||||
|
||||
$lastRow = $worksheet->getAutoFilter()->autoExtendRange(1, 1);
|
||||
self::assertSame(6, $lastRow, 'Filter range has been re-sized incorrectly');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue