mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-09-12 11:06:28 +00:00
Removing Columns/Rows Containing Merged Cells
Fix #282, which went stale over 7 years ago, and is now reopened. This is certainly related to issue #4379. If merged cells are in the midst of deleted rows/columns, the merge may continue to exist after the deletion, leading to various problems including spreadsheet corruption. The problem is not with either Reader or Writer. This PR will automatically unmerge all merged cells whose first cell is in the delete range before performing the deletion. This will address the corruption problem. Something more sophisticated may be required, so I won't merge this PR for a while to give me a chance to think about it some more.
This commit is contained in:
@@ -2392,6 +2392,20 @@ class Worksheet
|
||||
if ($row < 1) {
|
||||
throw new Exception('Rows to be deleted should at least start from row 1.');
|
||||
}
|
||||
$startRow = $row;
|
||||
$endRow = $startRow + $numberOfRows - 1;
|
||||
$removeKeys = [];
|
||||
foreach ($this->mergeCells as $key => $value) {
|
||||
if (preg_match('/^[a-z]{1,3}(\d+)/i', $key, $matches) === 1) {
|
||||
$startMergeInt = (int) $matches[1];
|
||||
if ($startMergeInt >= $startRow && $startMergeInt <= $endRow) {
|
||||
$removeKeys[] = $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($removeKeys as $key) {
|
||||
unset($this->mergeCells[$key]);
|
||||
}
|
||||
|
||||
$holdRowDimensions = $this->removeRowDimensions($row, $numberOfRows);
|
||||
$highestRow = $this->getHighestDataRow();
|
||||
@@ -2448,6 +2462,20 @@ class Worksheet
|
||||
if (is_numeric($column)) {
|
||||
throw new Exception('Column references should not be numeric.');
|
||||
}
|
||||
$startColumnInt = Coordinate::columnIndexFromString($column);
|
||||
$endColumnInt = $startColumnInt + $numberOfColumns - 1;
|
||||
$removeKeys = [];
|
||||
foreach ($this->mergeCells as $key => $value) {
|
||||
if (preg_match('/^[a-z]{1,3}/i', $key, $matches) === 1) {
|
||||
$startMergeInt = Coordinate::columnIndexFromString($matches[0]);
|
||||
if ($startMergeInt >= $startColumnInt && $startMergeInt <= $endColumnInt) {
|
||||
$removeKeys[] = $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($removeKeys as $key) {
|
||||
unset($this->mergeCells[$key]);
|
||||
}
|
||||
|
||||
$highestColumn = $this->getHighestDataColumn();
|
||||
$highestColumnIndex = Coordinate::columnIndexFromString($highestColumn);
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class MergeCellsDeletedTest extends TestCase
|
||||
{
|
||||
public function testDeletedColumns(): void
|
||||
{
|
||||
$infile = 'tests/data/Reader/XLSX/issue.282.xlsx';
|
||||
$reader = new XlsxReader();
|
||||
$spreadsheet = $reader->load($infile);
|
||||
$sheet = $spreadsheet->getSheetByName('Sheet1');
|
||||
|
||||
$mergeCells = $sheet->getMergeCells();
|
||||
self::assertSame(['B1:F1', 'G1:I1'], array_values($mergeCells));
|
||||
|
||||
// Want to delete column B,C,D,E,F
|
||||
$sheet->removeColumnByIndex(2, 5);
|
||||
$mergeCells2 = $sheet->getMergeCells();
|
||||
self::assertSame(['B1:D1'], array_values($mergeCells2));
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
}
|
||||
|
||||
public function testDeletedRows(): void
|
||||
{
|
||||
$infile = 'tests/data/Reader/XLSX/issue.282.xlsx';
|
||||
$reader = new XlsxReader();
|
||||
$spreadsheet = $reader->load($infile);
|
||||
$sheet = $spreadsheet->getSheetByName('Sheet2');
|
||||
|
||||
$mergeCells = $sheet->getMergeCells();
|
||||
self::assertSame(['A2:A6', 'A7:A9'], array_values($mergeCells));
|
||||
|
||||
// Want to delete rows 2 to 4
|
||||
$sheet->removeRow(2, 3);
|
||||
$mergeCells2 = $sheet->getMergeCells();
|
||||
self::assertSame(['A4:A6'], array_values($mergeCells2));
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user