Bugfix/remove column out of range (#1197)
* Call garbage collector after removing a column Otherwise callers of getHighestColumn get stale values * Update changelog * Fix remove a column out of range removes the last column Given: +---+---+ | A | B | +---+---+ Attempting to remove 'D', should not alter the worksheet * Avoid side effects when trying to remove more columns than exists
This commit is contained in:
parent
b82afe37dc
commit
89066d2568
|
@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Call garbage collector after removing a column to prevent stale cached values
|
- Call garbage collector after removing a column to prevent stale cached values
|
||||||
|
- Trying to remove a column that doesn't exist deletes the latest column
|
||||||
|
|
||||||
## [1.9.0] - 2019-08-17
|
## [1.9.0] - 2019-08-17
|
||||||
|
|
||||||
|
|
|
@ -2145,19 +2145,30 @@ class Worksheet implements IComparable
|
||||||
*/
|
*/
|
||||||
public function removeColumn($pColumn, $pNumCols = 1)
|
public function removeColumn($pColumn, $pNumCols = 1)
|
||||||
{
|
{
|
||||||
if (!is_numeric($pColumn)) {
|
if (is_numeric($pColumn)) {
|
||||||
|
throw new Exception('Column references should not be numeric.');
|
||||||
|
}
|
||||||
|
|
||||||
$highestColumn = $this->getHighestDataColumn();
|
$highestColumn = $this->getHighestDataColumn();
|
||||||
$pColumn = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($pColumn) + $pNumCols);
|
$highestColumnIndex = Coordinate::columnIndexFromString($highestColumn);
|
||||||
|
$pColumnIndex = Coordinate::columnIndexFromString($pColumn);
|
||||||
|
|
||||||
|
if ($pColumnIndex > $highestColumnIndex) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pColumn = Coordinate::stringFromColumnIndex($pColumnIndex + $pNumCols);
|
||||||
$objReferenceHelper = ReferenceHelper::getInstance();
|
$objReferenceHelper = ReferenceHelper::getInstance();
|
||||||
$objReferenceHelper->insertNewBefore($pColumn . '1', -$pNumCols, 0, $this);
|
$objReferenceHelper->insertNewBefore($pColumn . '1', -$pNumCols, 0, $this);
|
||||||
for ($c = 0; $c < $pNumCols; ++$c) {
|
|
||||||
|
$maxPossibleColumnsToBeRemoved = $highestColumnIndex - $pColumnIndex + 1;
|
||||||
|
|
||||||
|
for ($c = 0, $n = min($maxPossibleColumnsToBeRemoved, $pNumCols); $c < $n; ++$c) {
|
||||||
$this->getCellCollection()->removeColumn($highestColumn);
|
$this->getCellCollection()->removeColumn($highestColumn);
|
||||||
$highestColumn = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($highestColumn) - 1);
|
$highestColumn = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($highestColumn) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->garbageCollect();
|
$this->garbageCollect();
|
||||||
} else {
|
|
||||||
throw new Exception('Column references should not be numeric.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,6 +191,7 @@ class WorksheetTest extends TestCase
|
||||||
['A2', 'B2', 'C2'],
|
['A2', 'B2', 'C2'],
|
||||||
],
|
],
|
||||||
'A',
|
'A',
|
||||||
|
1,
|
||||||
[
|
[
|
||||||
['B1', 'C1'],
|
['B1', 'C1'],
|
||||||
['B2', 'C2'],
|
['B2', 'C2'],
|
||||||
|
@ -203,6 +204,7 @@ class WorksheetTest extends TestCase
|
||||||
['A2', 'B2', 'C2'],
|
['A2', 'B2', 'C2'],
|
||||||
],
|
],
|
||||||
'B',
|
'B',
|
||||||
|
1,
|
||||||
[
|
[
|
||||||
['A1', 'C1'],
|
['A1', 'C1'],
|
||||||
['A2', 'C2'],
|
['A2', 'C2'],
|
||||||
|
@ -215,12 +217,39 @@ class WorksheetTest extends TestCase
|
||||||
['A2', 'B2', 'C2'],
|
['A2', 'B2', 'C2'],
|
||||||
],
|
],
|
||||||
'C',
|
'C',
|
||||||
|
1,
|
||||||
[
|
[
|
||||||
['A1', 'B1'],
|
['A1', 'B1'],
|
||||||
['A2', 'B2'],
|
['A2', 'B2'],
|
||||||
],
|
],
|
||||||
'B',
|
'B',
|
||||||
],
|
],
|
||||||
|
'Remove a column out of range' => [
|
||||||
|
[
|
||||||
|
['A1', 'B1', 'C1'],
|
||||||
|
['A2', 'B2', 'C2'],
|
||||||
|
],
|
||||||
|
'D',
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
['A1', 'B1', 'C1'],
|
||||||
|
['A2', 'B2', 'C2'],
|
||||||
|
],
|
||||||
|
'C',
|
||||||
|
],
|
||||||
|
'Remove multiple columns' => [
|
||||||
|
[
|
||||||
|
['A1', 'B1', 'C1'],
|
||||||
|
['A2', 'B2', 'C2'],
|
||||||
|
],
|
||||||
|
'B',
|
||||||
|
5,
|
||||||
|
[
|
||||||
|
['A1'],
|
||||||
|
['A2'],
|
||||||
|
],
|
||||||
|
'A',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,6 +259,7 @@ class WorksheetTest extends TestCase
|
||||||
public function testRemoveColumn(
|
public function testRemoveColumn(
|
||||||
array $initialData,
|
array $initialData,
|
||||||
string $columnToBeRemoved,
|
string $columnToBeRemoved,
|
||||||
|
int $columnsToBeRemoved,
|
||||||
array $expectedData,
|
array $expectedData,
|
||||||
string $expectedHighestColumn
|
string $expectedHighestColumn
|
||||||
) {
|
) {
|
||||||
|
@ -237,7 +267,7 @@ class WorksheetTest extends TestCase
|
||||||
$worksheet = $spreadsheet->getActiveSheet();
|
$worksheet = $spreadsheet->getActiveSheet();
|
||||||
$worksheet->fromArray($initialData);
|
$worksheet->fromArray($initialData);
|
||||||
|
|
||||||
$worksheet->removeColumn($columnToBeRemoved);
|
$worksheet->removeColumn($columnToBeRemoved, $columnsToBeRemoved);
|
||||||
|
|
||||||
self::assertSame($expectedHighestColumn, $worksheet->getHighestColumn());
|
self::assertSame($expectedHighestColumn, $worksheet->getHighestColumn());
|
||||||
self::assertSame($expectedData, $worksheet->toArray());
|
self::assertSame($expectedData, $worksheet->toArray());
|
||||||
|
|
Loading…
Reference in New Issue