Skip to content

Commit 1f1fc36

Browse files
authored
Merge pull request #2877 from PHPOffice/Issue-2776_Allow-Merge-Cells-for-single-cell
Relax validation on merge cells to allow input of a single cell
2 parents 5608e05 + 00dae1b commit 1f1fc36

File tree

2 files changed

+30
-25
lines changed

2 files changed

+30
-25
lines changed

src/PhpSpreadsheet/Worksheet/Worksheet.php

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1752,31 +1752,35 @@ public function mergeCells($range)
17521752
{
17531753
$range = Functions::trimSheetFromCellReference(Validations::validateCellRange($range));
17541754

1755-
if (preg_match('/^([A-Z]+)(\\d+):([A-Z]+)(\\d+)$/', $range, $matches) === 1) {
1756-
$this->mergeCells[$range] = $range;
1757-
$firstRow = (int) $matches[2];
1758-
$lastRow = (int) $matches[4];
1759-
$firstColumn = $matches[1];
1760-
$lastColumn = $matches[3];
1761-
$firstColumnIndex = Coordinate::columnIndexFromString($firstColumn);
1762-
$lastColumnIndex = Coordinate::columnIndexFromString($lastColumn);
1763-
$numberRows = $lastRow - $firstRow;
1764-
$numberColumns = $lastColumnIndex - $firstColumnIndex;
1765-
1766-
// create upper left cell if it does not already exist
1767-
$upperLeft = "{$firstColumn}{$firstRow}";
1768-
if (!$this->cellExists($upperLeft)) {
1769-
$this->getCell($upperLeft)->setValueExplicit(null, DataType::TYPE_NULL);
1770-
}
1755+
if (strpos($range, ':') === false) {
1756+
$range .= ":{$range}";
1757+
}
17711758

1772-
// Blank out the rest of the cells in the range (if they exist)
1773-
if ($numberRows > $numberColumns) {
1774-
$this->clearMergeCellsByColumn($firstColumn, $lastColumn, $firstRow, $lastRow, $upperLeft);
1775-
} else {
1776-
$this->clearMergeCellsByRow($firstColumn, $lastColumnIndex, $firstRow, $lastRow, $upperLeft);
1777-
}
1759+
if (preg_match('/^([A-Z]+)(\\d+):([A-Z]+)(\\d+)$/', $range, $matches) !== 1) {
1760+
throw new Exception('Merge must be on a valid range of cells.');
1761+
}
1762+
1763+
$this->mergeCells[$range] = $range;
1764+
$firstRow = (int) $matches[2];
1765+
$lastRow = (int) $matches[4];
1766+
$firstColumn = $matches[1];
1767+
$lastColumn = $matches[3];
1768+
$firstColumnIndex = Coordinate::columnIndexFromString($firstColumn);
1769+
$lastColumnIndex = Coordinate::columnIndexFromString($lastColumn);
1770+
$numberRows = $lastRow - $firstRow;
1771+
$numberColumns = $lastColumnIndex - $firstColumnIndex;
1772+
1773+
// create upper left cell if it does not already exist
1774+
$upperLeft = "{$firstColumn}{$firstRow}";
1775+
if (!$this->cellExists($upperLeft)) {
1776+
$this->getCell($upperLeft)->setValueExplicit(null, DataType::TYPE_NULL);
1777+
}
1778+
1779+
// Blank out the rest of the cells in the range (if they exist)
1780+
if ($numberRows > $numberColumns) {
1781+
$this->clearMergeCellsByColumn($firstColumn, $lastColumn, $firstRow, $lastRow, $upperLeft);
17781782
} else {
1779-
throw new Exception('Merge must be set on a range of cells.');
1783+
$this->clearMergeCellsByRow($firstColumn, $lastColumnIndex, $firstRow, $lastRow, $upperLeft);
17801784
}
17811785

17821786
return $this;

tests/PhpSpreadsheetTests/Calculation/MergedCellTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ private function setBadRange(Worksheet $sheet, string $range): void
100100
$sheet->mergeCells($range);
101101
self::fail("Expected invalid merge range $range");
102102
} catch (SpreadException $e) {
103-
self::assertSame('Merge must be set on a range of cells.', $e->getMessage());
103+
self::assertSame('Merge must be on a valid range of cells.', $e->getMessage());
104104
}
105105
}
106106

@@ -109,7 +109,8 @@ public function testMergedBadRange(): void
109109
$spreadSheet = new Spreadsheet();
110110

111111
$dataSheet = $spreadSheet->getActiveSheet();
112-
$this->setBadRange($dataSheet, 'B1');
112+
// TODO - Reinstate full validation and disallow single cell merging for version 2.0
113+
// $this->setBadRange($dataSheet, 'B1');
113114
$this->setBadRange($dataSheet, 'Invalid');
114115
$this->setBadRange($dataSheet, '1');
115116
$this->setBadRange($dataSheet, 'C');

0 commit comments

Comments
 (0)