`ReferenceHelper@insertNewBefore` checks for missing coordinates before replacing values (#2541)

* ReferenceHelper@insertNewBefore now changes for missing columns before replacing and deleting columns

* Changelog updated

* Fixed code style

* Added assertion for all cells. Change bugfix implementation to use `createNewCell` on Worksheet

* Additional assertions
This commit is contained in:
Orkhan Ahmadov 2022-02-12 16:08:11 +01:00 committed by GitHub
parent 90e9ea9505
commit 0eeba6dc0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 1 deletions

View File

@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org).
## Unreleased - TBD ## Unreleased - TBD
- Fixed `ReferenceHelper@insertNewBefore` behavior when removing column before last column with null value
### Added ### Added
- Improved support for passing of array arguments to Excel function implementations to return array results (where appropriate). [PR #2562](https://github.com/PHPOffice/PhpSpreadsheet/pull/2562) - Improved support for passing of array arguments to Excel function implementations to return array results (where appropriate). [PR #2562](https://github.com/PHPOffice/PhpSpreadsheet/pull/2562)

View File

@ -398,6 +398,26 @@ class ReferenceHelper
} }
} }
// Find missing coordinates. This is important when inserting column before the last column
$missingCoordinates = array_filter(
array_map(function ($row) use ($highestColumn) {
return $highestColumn . $row;
}, range(1, $highestRow)),
function ($coordinate) use ($allCoordinates) {
return !in_array($coordinate, $allCoordinates);
}
);
// Create missing cells with null values
if (!empty($missingCoordinates)) {
foreach ($missingCoordinates as $coordinate) {
$worksheet->createNewCell($coordinate);
}
// Refresh all coordinates
$allCoordinates = $worksheet->getCoordinates();
}
// Loop through cells, bottom-up, and change cell coordinate // Loop through cells, bottom-up, and change cell coordinate
if ($remove) { if ($remove) {
// It's faster to reverse and pop than to use unshift, especially with large cell collections // It's faster to reverse and pop than to use unshift, especially with large cell collections

View File

@ -1291,7 +1291,7 @@ class Worksheet implements IComparable
* *
* @return Cell Cell that was created * @return Cell Cell that was created
*/ */
private function createNewCell($coordinate) public function createNewCell($coordinate)
{ {
$cell = new Cell(null, DataType::TYPE_NULL, $this); $cell = new Cell(null, DataType::TYPE_NULL, $this);
$this->cellCollection->add($coordinate, $cell); $this->cellCollection->add($coordinate, $cell);

View File

@ -149,4 +149,32 @@ class ReferenceHelperTest extends TestCase
self::assertSame($oldValue, $newValue); self::assertSame($oldValue, $newValue);
self::assertSame($oldDataType, $newDataType); self::assertSame($oldDataType, $newDataType);
} }
public function testRemoveColumnShiftsCorrectColumnValueIntoRemovedColumnCoordinates(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->fromArray([
['a1', 'b1', 'c1'],
['a2', 'b2', null],
]);
$cells = $sheet->toArray();
self::assertSame('a1', $cells[0][0]);
self::assertSame('b1', $cells[0][1]);
self::assertSame('c1', $cells[0][2]);
self::assertSame('a2', $cells[1][0]);
self::assertSame('b2', $cells[1][1]);
self::assertNull($cells[1][2]);
$sheet->removeColumn('B');
$cells = $sheet->toArray();
self::assertSame('a1', $cells[0][0]);
self::assertSame('c1', $cells[0][1]);
self::assertArrayNotHasKey(2, $cells[0]);
self::assertSame('a2', $cells[1][0]);
self::assertNull($cells[1][1]);
self::assertArrayNotHasKey(2, $cells[1]);
}
} }