Skip to content

Commit 0eeba6d

Browse files
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
1 parent 90e9ea9 commit 0eeba6d

File tree

4 files changed

+51
-1
lines changed

4 files changed

+51
-1
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org).
77

88
## Unreleased - TBD
99

10+
- Fixed `ReferenceHelper@insertNewBefore` behavior when removing column before last column with null value
11+
1012
### Added
1113

1214
- 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)

src/PhpSpreadsheet/ReferenceHelper.php

+20
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,26 @@ public function insertNewBefore($beforeCellAddress, $numberOfColumns, $numberOfR
398398
}
399399
}
400400

401+
// Find missing coordinates. This is important when inserting column before the last column
402+
$missingCoordinates = array_filter(
403+
array_map(function ($row) use ($highestColumn) {
404+
return $highestColumn . $row;
405+
}, range(1, $highestRow)),
406+
function ($coordinate) use ($allCoordinates) {
407+
return !in_array($coordinate, $allCoordinates);
408+
}
409+
);
410+
411+
// Create missing cells with null values
412+
if (!empty($missingCoordinates)) {
413+
foreach ($missingCoordinates as $coordinate) {
414+
$worksheet->createNewCell($coordinate);
415+
}
416+
417+
// Refresh all coordinates
418+
$allCoordinates = $worksheet->getCoordinates();
419+
}
420+
401421
// Loop through cells, bottom-up, and change cell coordinate
402422
if ($remove) {
403423
// It's faster to reverse and pop than to use unshift, especially with large cell collections

src/PhpSpreadsheet/Worksheet/Worksheet.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1291,7 +1291,7 @@ public function getCellByColumnAndRow($columnIndex, $row): Cell
12911291
*
12921292
* @return Cell Cell that was created
12931293
*/
1294-
private function createNewCell($coordinate)
1294+
public function createNewCell($coordinate)
12951295
{
12961296
$cell = new Cell(null, DataType::TYPE_NULL, $this);
12971297
$this->cellCollection->add($coordinate, $cell);

tests/PhpSpreadsheetTests/ReferenceHelperTest.php

+28
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,32 @@ public function testInsertNewBeforeRetainDataType(): void
149149
self::assertSame($oldValue, $newValue);
150150
self::assertSame($oldDataType, $newDataType);
151151
}
152+
153+
public function testRemoveColumnShiftsCorrectColumnValueIntoRemovedColumnCoordinates(): void
154+
{
155+
$spreadsheet = new Spreadsheet();
156+
$sheet = $spreadsheet->getActiveSheet();
157+
$sheet->fromArray([
158+
['a1', 'b1', 'c1'],
159+
['a2', 'b2', null],
160+
]);
161+
162+
$cells = $sheet->toArray();
163+
self::assertSame('a1', $cells[0][0]);
164+
self::assertSame('b1', $cells[0][1]);
165+
self::assertSame('c1', $cells[0][2]);
166+
self::assertSame('a2', $cells[1][0]);
167+
self::assertSame('b2', $cells[1][1]);
168+
self::assertNull($cells[1][2]);
169+
170+
$sheet->removeColumn('B');
171+
172+
$cells = $sheet->toArray();
173+
self::assertSame('a1', $cells[0][0]);
174+
self::assertSame('c1', $cells[0][1]);
175+
self::assertArrayNotHasKey(2, $cells[0]);
176+
self::assertSame('a2', $cells[1][0]);
177+
self::assertNull($cells[1][1]);
178+
self::assertArrayNotHasKey(2, $cells[1]);
179+
}
152180
}

0 commit comments

Comments
 (0)