diff --git a/CHANGELOG.md b/CHANGELOG.md index b10abb0e..1f470329 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org). ## Unreleased - TBD +- Fixed `ReferenceHelper@insertNewBefore` behavior when removing column before last column with null value + ### 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) diff --git a/src/PhpSpreadsheet/ReferenceHelper.php b/src/PhpSpreadsheet/ReferenceHelper.php index 0d72b305..98c4807a 100644 --- a/src/PhpSpreadsheet/ReferenceHelper.php +++ b/src/PhpSpreadsheet/ReferenceHelper.php @@ -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 if ($remove) { // It's faster to reverse and pop than to use unshift, especially with large cell collections diff --git a/src/PhpSpreadsheet/Worksheet/Worksheet.php b/src/PhpSpreadsheet/Worksheet/Worksheet.php index 51cf3c52..362f20f0 100644 --- a/src/PhpSpreadsheet/Worksheet/Worksheet.php +++ b/src/PhpSpreadsheet/Worksheet/Worksheet.php @@ -1291,7 +1291,7 @@ class Worksheet implements IComparable * * @return Cell Cell that was created */ - private function createNewCell($coordinate) + public function createNewCell($coordinate) { $cell = new Cell(null, DataType::TYPE_NULL, $this); $this->cellCollection->add($coordinate, $cell); diff --git a/tests/PhpSpreadsheetTests/ReferenceHelperTest.php b/tests/PhpSpreadsheetTests/ReferenceHelperTest.php index 874dbfb5..2c016b0b 100644 --- a/tests/PhpSpreadsheetTests/ReferenceHelperTest.php +++ b/tests/PhpSpreadsheetTests/ReferenceHelperTest.php @@ -149,4 +149,32 @@ class ReferenceHelperTest extends TestCase self::assertSame($oldValue, $newValue); 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]); + } }