Handle additional merge options like those provide in OpenOffice or LibreOffice to hide cell values in a merge range rather than empty them, or to merge the values as well as the cells
This includes reading hidden values in merge ranges, so that Unmerging can restore their visibility
This commit is contained in:
parent
c6e84fbaf9
commit
8ecf69a5c4
|
|
@ -17,7 +17,11 @@ and this project adheres to [Semantic Versioning](https://semver.org).
|
|||
|
||||
### Changed
|
||||
|
||||
- Nothing
|
||||
- Allow variant behaviour when merging cells [Issue #3065](https://github.com/PHPOffice/PhpSpreadsheet/issues/3065)
|
||||
- Merge methods now allow an additional `$behaviour` argument. Permitted values are:
|
||||
- Worksheet::MERGE_CELL_CONTENT_EMPTY - Empty the content of the hidden cells (the default behaviour)
|
||||
- Worksheet::MERGE_CELL_CONTENT_HIDE - Keep the content of the hidden cells
|
||||
- Worksheet::MERGE_CELL_CONTENT_MERGE - Move the content of the hidden cells into the first cell
|
||||
|
||||
### Deprecated
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
|
|
@ -1332,22 +1332,72 @@ rows (default), or above. The following code adds the summary above:
|
|||
$spreadsheet->getActiveSheet()->setShowSummaryBelow(false);
|
||||
```
|
||||
|
||||
## Merge/unmerge cells
|
||||
## Merge/Unmerge cells
|
||||
|
||||
If you have a big piece of data you want to display in a worksheet, you
|
||||
can merge two or more cells together, to become one cell. This can be
|
||||
done using the following code:
|
||||
If you have a big piece of data you want to display in a worksheet, or a
|
||||
heading that needs to span multiple sub-heading columns, you can merge
|
||||
two or more cells together, to become one cell. This can be done using
|
||||
the following code:
|
||||
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->mergeCells('A18:E22');
|
||||
```
|
||||
|
||||
Removing a merge can be done using the unmergeCells method:
|
||||
Removing a merge can be done using the `unmergeCells()` method:
|
||||
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->unmergeCells('A18:E22');
|
||||
```
|
||||
|
||||
MS Excel itself doesn't yet offer the functionality to simply hide the merged cells, or to merge the content of cells into a single cell, but it is available in Open/Libre Office.
|
||||
|
||||
### Merge with MERGE_CELL_CONTENT_EMPTY
|
||||
|
||||
The default behaviour is to empty all cells except for the top-left corner cell in the merge range; and this is also the default behaviour for the `mergeCells()` method in PhpSpreadsheet.
|
||||
When this behaviour is applied, those cell values will be set to null; and if they are subsequently Unmerged, they will be empty cells.
|
||||
|
||||
Passing an extra flag value to the `mergeCells()` method in PhpSpreadsheet can change this behaviour.
|
||||
|
||||

|
||||
|
||||
Possible flag values are:
|
||||
- Worksheet::MERGE_CELL_CONTENT_EMPTY (the default)
|
||||
- Worksheet::MERGE_CELL_CONTENT_HIDE
|
||||
- Worksheet::MERGE_CELL_CONTENT_MERGE
|
||||
|
||||
### Merge with MERGE_CELL_CONTENT_HIDE
|
||||
|
||||
The first alternative, available only in OpenOffice, is to hide those cells, but to leave their content intact.
|
||||
When a file saved as `Xlsx` in those applications is opened in MS Excel, and those cells are unmerged, the original content will still be present.
|
||||
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->mergeCells('A1:C3', Worksheet::MERGE_CELL_CONTENT_HIDE);
|
||||
```
|
||||
|
||||
Will replicate that behaviour.
|
||||
|
||||
### Merge with MERGE_CELL_CONTENT_MERGE
|
||||
|
||||
The second alternative, available in both OpenOffice and LibreOffice is to merge the content of every cell in the merge range into the top-left cell, while setting those hidden cells to empty.
|
||||
|
||||
```php
|
||||
$spreadsheet->getActiveSheet()->mergeCells('A1:C3', Worksheet::MERGE_CELL_CONTENT_MERGE);
|
||||
```
|
||||
|
||||
Particularly when the merged cells contain formulae, the logic for this merge seems strange:
|
||||
walking through the merge range, each cell is calculated in turn, and appended to the "master" cell, then it is emptied, so any subsequent calculations that reference the cell see an empty cell, not the pre-merge value.
|
||||
For example, suppose our spreadsheet contains
|
||||
|
||||

|
||||
|
||||
where `B2` is the formula `=5-B1` and `C2` is the formula `=A2/B2`,
|
||||
and we want to merge cells `A2` to `C2` with all the cell values merged.
|
||||
The result is:
|
||||
|
||||

|
||||
|
||||
The cell value `12` from cell `A2` is fixed; the value from `B2` is the result of the formula `=5-B1` (`4`, which is appended to our merged value), and cell `B2` is then emptied, so when we evaluate cell `C2` with the formula `=A2/B2` it gives us `12 / 0` which results in a `#DIV/0!` error (so the error `#DIV/0!` is appended to our merged value rather than the original calculation result of `3`).
|
||||
|
||||
## Inserting or Removing rows/columns
|
||||
|
||||
You can insert/remove rows/columns at a specific position. The following
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ class Gnumeric extends BaseReader
|
|||
if ($sheet !== null && isset($sheet->MergedRegions)) {
|
||||
foreach ($sheet->MergedRegions->Merge as $mergeCells) {
|
||||
if (strpos((string) $mergeCells, ':') !== false) {
|
||||
$this->spreadsheet->getActiveSheet()->mergeCells($mergeCells);
|
||||
$this->spreadsheet->getActiveSheet()->mergeCells($mergeCells, Worksheet::MERGE_CELL_CONTENT_HIDE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ use PhpOffice\PhpSpreadsheet\Shared\Date;
|
|||
use PhpOffice\PhpSpreadsheet\Shared\File;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use Throwable;
|
||||
use XMLReader;
|
||||
use ZipArchive;
|
||||
|
|
@ -759,7 +760,7 @@ class Ods extends BaseReader
|
|||
}
|
||||
|
||||
$cellRange = $columnID . $rowID . ':' . $columnTo . $rowTo;
|
||||
$spreadsheet->getActiveSheet()->mergeCells($cellRange);
|
||||
$spreadsheet->getActiveSheet()->mergeCells($cellRange, Worksheet::MERGE_CELL_CONTENT_HIDE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4585,7 +4585,7 @@ class Xls extends BaseReader
|
|||
(strpos($cellRangeAddress, ':') !== false) &&
|
||||
($this->includeCellRangeFiltered($cellRangeAddress))
|
||||
) {
|
||||
$this->phpSheet->mergeCells($cellRangeAddress);
|
||||
$this->phpSheet->mergeCells($cellRangeAddress, Worksheet::MERGE_CELL_CONTENT_HIDE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -914,7 +914,7 @@ class Xlsx extends BaseReader
|
|||
foreach ($xmlSheet->mergeCells->mergeCell as $mergeCell) {
|
||||
$mergeRef = (string) $mergeCell['ref'];
|
||||
if (strpos($mergeRef, ':') !== false) {
|
||||
$docSheet->mergeCells((string) $mergeCell['ref']);
|
||||
$docSheet->mergeCells((string) $mergeCell['ref'], Worksheet::MERGE_CELL_CONTENT_HIDE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ use PhpOffice\PhpSpreadsheet\Shared\Date;
|
|||
use PhpOffice\PhpSpreadsheet\Shared\File;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use SimpleXMLElement;
|
||||
|
||||
/**
|
||||
|
|
@ -364,7 +365,7 @@ class Xml extends BaseReader
|
|||
$rowTo = $rowTo + $cell_ss['MergeDown'];
|
||||
}
|
||||
$cellRange .= ':' . $columnTo . $rowTo;
|
||||
$spreadsheet->getActiveSheet()->mergeCells($cellRange);
|
||||
$spreadsheet->getActiveSheet()->mergeCells($cellRange, Worksheet::MERGE_CELL_CONTENT_HIDE);
|
||||
}
|
||||
|
||||
$hasCalculatedValue = false;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@ class Worksheet implements IComparable
|
|||
public const SHEETSTATE_HIDDEN = 'hidden';
|
||||
public const SHEETSTATE_VERYHIDDEN = 'veryHidden';
|
||||
|
||||
public const MERGE_CELL_CONTENT_EMPTY = 'empty';
|
||||
public const MERGE_CELL_CONTENT_HIDE = 'hide';
|
||||
public const MERGE_CELL_CONTENT_MERGE = 'merge';
|
||||
|
||||
protected const SHEET_NAME_REQUIRES_NO_QUOTES = '/^[_\p{L}][_\p{L}\p{N}]*$/mui';
|
||||
|
||||
/**
|
||||
|
|
@ -1758,10 +1762,15 @@ class Worksheet implements IComparable
|
|||
* @param AddressRange|array<int>|string $range A simple string containing a Cell range like 'A1:E10'
|
||||
* or passing in an array of [$fromColumnIndex, $fromRow, $toColumnIndex, $toRow] (e.g. [3, 5, 6, 8]),
|
||||
* or an AddressRange.
|
||||
* @param string $behaviour How the merged cells should behave.
|
||||
* Possible values are:
|
||||
* MERGE_CELL_CONTENT_EMPTY - Empty the content of the hidden cells
|
||||
* MERGE_CELL_CONTENT_HIDE - Keep the content of the hidden cells
|
||||
* MERGE_CELL_CONTENT_MERGE - Move the content of the hidden cells into the first cell
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function mergeCells($range)
|
||||
public function mergeCells($range, $behaviour = self::MERGE_CELL_CONTENT_EMPTY)
|
||||
{
|
||||
$range = Functions::trimSheetFromCellReference(Validations::validateCellRange($range));
|
||||
|
||||
|
|
@ -1793,18 +1802,22 @@ class Worksheet implements IComparable
|
|||
$this->getCell($upperLeft)->setValueExplicit(null, DataType::TYPE_NULL);
|
||||
}
|
||||
|
||||
if ($behaviour !== self::MERGE_CELL_CONTENT_HIDE) {
|
||||
// Blank out the rest of the cells in the range (if they exist)
|
||||
if ($numberRows > $numberColumns) {
|
||||
$this->clearMergeCellsByColumn($firstColumn, $lastColumn, $firstRow, $lastRow, $upperLeft);
|
||||
$this->clearMergeCellsByColumn($firstColumn, $lastColumn, $firstRow, $lastRow, $upperLeft, $behaviour);
|
||||
} else {
|
||||
$this->clearMergeCellsByRow($firstColumn, $lastColumnIndex, $firstRow, $lastRow, $upperLeft);
|
||||
$this->clearMergeCellsByRow($firstColumn, $lastColumnIndex, $firstRow, $lastRow, $upperLeft, $behaviour);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function clearMergeCellsByColumn(string $firstColumn, string $lastColumn, int $firstRow, int $lastRow, string $upperLeft): void
|
||||
private function clearMergeCellsByColumn(string $firstColumn, string $lastColumn, int $firstRow, int $lastRow, string $upperLeft, string $behaviour): void
|
||||
{
|
||||
$leftCellValue = [$this->getCell($upperLeft)->getFormattedValue()];
|
||||
|
||||
foreach ($this->getColumnIterator($firstColumn, $lastColumn) as $column) {
|
||||
$iterator = $column->getCellIterator($firstRow);
|
||||
$iterator->setIterateOnlyExistingCells(true);
|
||||
|
|
@ -1814,17 +1827,21 @@ class Worksheet implements IComparable
|
|||
if ($row > $lastRow) {
|
||||
break;
|
||||
}
|
||||
$thisCell = $cell->getColumn() . $row;
|
||||
if ($upperLeft !== $thisCell) {
|
||||
$cell->setValueExplicit(null, DataType::TYPE_NULL);
|
||||
}
|
||||
}
|
||||
$leftCellValue = $this->mergeCellBehaviour($cell, $upperLeft, $behaviour, $leftCellValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function clearMergeCellsByRow(string $firstColumn, int $lastColumnIndex, int $firstRow, int $lastRow, string $upperLeft): void
|
||||
$leftCellValue = implode(' ', $leftCellValue);
|
||||
if ($behaviour === self::MERGE_CELL_CONTENT_MERGE) {
|
||||
$this->getCell($upperLeft)->setValueExplicit($leftCellValue, DataType::TYPE_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
private function clearMergeCellsByRow(string $firstColumn, int $lastColumnIndex, int $firstRow, int $lastRow, string $upperLeft, string $behaviour): void
|
||||
{
|
||||
$leftCellValue = [$this->getCell($upperLeft)->getFormattedValue()];
|
||||
|
||||
foreach ($this->getRowIterator($firstRow, $lastRow) as $row) {
|
||||
$iterator = $row->getCellIterator($firstColumn);
|
||||
$iterator->setIterateOnlyExistingCells(true);
|
||||
|
|
@ -1835,13 +1852,31 @@ class Worksheet implements IComparable
|
|||
if ($columnIndex > $lastColumnIndex) {
|
||||
break;
|
||||
}
|
||||
$thisCell = $column . $cell->getRow();
|
||||
if ($upperLeft !== $thisCell) {
|
||||
$leftCellValue = $this->mergeCellBehaviour($cell, $upperLeft, $behaviour, $leftCellValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$leftCellValue = implode(' ', $leftCellValue);
|
||||
if ($behaviour === self::MERGE_CELL_CONTENT_MERGE) {
|
||||
$this->getCell($upperLeft)->setValueExplicit($leftCellValue, DataType::TYPE_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
public function mergeCellBehaviour(Cell $cell, string $upperLeft, string $behaviour, array $leftCellValue): array
|
||||
{
|
||||
if ($cell->getCoordinate() !== $upperLeft) {
|
||||
Calculation::getInstance($cell->getWorksheet()->getParent())->flushInstance();
|
||||
if ($behaviour === self::MERGE_CELL_CONTENT_MERGE) {
|
||||
$cellValue = $cell->getFormattedValue();
|
||||
if ($cellValue !== '') {
|
||||
$leftCellValue[] = $cellValue;
|
||||
}
|
||||
}
|
||||
$cell->setValueExplicit(null, DataType::TYPE_NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $leftCellValue;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1856,17 +1891,22 @@ class Worksheet implements IComparable
|
|||
* @param int $row1 Numeric row coordinate of the first cell
|
||||
* @param int $columnIndex2 Numeric column coordinate of the last cell
|
||||
* @param int $row2 Numeric row coordinate of the last cell
|
||||
* @param string $behaviour How the merged cells should behave.
|
||||
* Possible values are:
|
||||
* MERGE_CELL_CONTENT_EMPTY - Empty the content of the hidden cells
|
||||
* MERGE_CELL_CONTENT_HIDE - Keep the content of the hidden cells
|
||||
* MERGE_CELL_CONTENT_MERGE - Move the content of the hidden cells into the first cell
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function mergeCellsByColumnAndRow($columnIndex1, $row1, $columnIndex2, $row2)
|
||||
public function mergeCellsByColumnAndRow($columnIndex1, $row1, $columnIndex2, $row2, $behaviour = self::MERGE_CELL_CONTENT_EMPTY)
|
||||
{
|
||||
$cellRange = new CellRange(
|
||||
CellAddress::fromColumnAndRow($columnIndex1, $row1),
|
||||
CellAddress::fromColumnAndRow($columnIndex2, $row2)
|
||||
);
|
||||
|
||||
return $this->mergeCells($cellRange);
|
||||
return $this->mergeCells($cellRange, $behaviour);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,166 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
|
||||
|
||||
class MergeBehaviourTest extends AbstractFunctional
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $testDataRaw = [
|
||||
[1.1, 2.2, '=ROUND(A1+B1, 1)'],
|
||||
[4.4, 5.5, '=ROUND(A2+B2, 1)'],
|
||||
['=ROUND(A1+A2, 1)', '=ROUND(B1+B2, 1)', '=ROUND(A3+B3, 1)'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $testDataFormatted = [
|
||||
['=DATE(1960, 12, 19)', '=DATE(2022, 09, 15)'],
|
||||
];
|
||||
|
||||
public function testMergeCellsDefaultBehaviour(): void
|
||||
{
|
||||
$expectedResult = [
|
||||
[1.1, null, null],
|
||||
[null, null, null],
|
||||
[null, null, null],
|
||||
];
|
||||
|
||||
$mergeRange = 'A1:C3';
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
$worksheet->fromArray($this->testDataRaw, null, 'A1', true);
|
||||
$worksheet->mergeCells($mergeRange);
|
||||
|
||||
$mergeResult = $worksheet->toArray(null, true, true, false);
|
||||
self::assertSame($expectedResult, $mergeResult);
|
||||
}
|
||||
|
||||
public function testMergeCellsDefaultBehaviourFormatted(): void
|
||||
{
|
||||
$expectedResult = [
|
||||
['1960-12-19', null],
|
||||
];
|
||||
|
||||
$mergeRange = 'A1:B1';
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
$worksheet->fromArray($this->testDataFormatted, null, 'A1', true);
|
||||
$worksheet->getStyle($mergeRange)->getNumberFormat()->setFormatCode('yyyy-mm-dd');
|
||||
$worksheet->mergeCells($mergeRange);
|
||||
|
||||
$mergeResult = $worksheet->toArray(null, true, true, false);
|
||||
self::assertSame($expectedResult, $mergeResult);
|
||||
}
|
||||
|
||||
public function testMergeCellsHideBehaviour(): void
|
||||
{
|
||||
$expectedResult = [
|
||||
[1.1, 2.2, 3.3],
|
||||
[4.4, 5.5, 9.9],
|
||||
[5.5, 7.7, 13.2],
|
||||
];
|
||||
|
||||
$mergeRange = 'A1:C3';
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
$worksheet->fromArray($this->testDataRaw, null, 'A1', true);
|
||||
$worksheet->mergeCells($mergeRange, Worksheet::MERGE_CELL_CONTENT_HIDE);
|
||||
|
||||
$mergeResult = $worksheet->toArray(null, true, true, false);
|
||||
self::assertSame($expectedResult, $mergeResult);
|
||||
}
|
||||
|
||||
public function testMergeCellsHideBehaviourFormatted(): void
|
||||
{
|
||||
$expectedResult = [
|
||||
['1960-12-19', '2022-09-15'],
|
||||
];
|
||||
|
||||
$mergeRange = 'A1:B1';
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
$worksheet->fromArray($this->testDataFormatted, null, 'A1', true);
|
||||
$worksheet->getStyle($mergeRange)->getNumberFormat()->setFormatCode('yyyy-mm-dd');
|
||||
$worksheet->mergeCells($mergeRange, Worksheet::MERGE_CELL_CONTENT_HIDE);
|
||||
|
||||
$mergeResult = $worksheet->toArray(null, true, true, false);
|
||||
self::assertSame($expectedResult, $mergeResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider mergeCellsMergeBehaviourProvider
|
||||
*/
|
||||
public function testMergeCellsMergeBehaviour(array $testData, string $mergeRange, array $expectedResult): void
|
||||
{
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
$worksheet->fromArray($testData, null, 'A1', true);
|
||||
// Force a precalculation to populate the calculation cache, so that we can verify that it is being cleared
|
||||
$worksheet->toArray();
|
||||
$worksheet->mergeCells($mergeRange, Worksheet::MERGE_CELL_CONTENT_MERGE);
|
||||
|
||||
$mergeResult = $worksheet->toArray(null, true, true, false);
|
||||
self::assertSame($expectedResult, $mergeResult);
|
||||
}
|
||||
|
||||
public function mergeCellsMergeBehaviourProvider(): array
|
||||
{
|
||||
return [
|
||||
'With Calculated Values' => [
|
||||
$this->testDataRaw,
|
||||
'A1:C3',
|
||||
[
|
||||
['1.1 2.2 1.1 4.4 5.5 0 1.1 0 0', null, null],
|
||||
[null, null, null],
|
||||
[null, null, null],
|
||||
],
|
||||
],
|
||||
'With Empty Cells' => [
|
||||
[
|
||||
[1, '', 2],
|
||||
[null, 3, null],
|
||||
[4, null, 5],
|
||||
],
|
||||
'A1:C3',
|
||||
[
|
||||
['1 2 3 4 5', null, null],
|
||||
[null, null, null],
|
||||
[null, null, null],
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
[12, '=5+1', '=A1/A2'],
|
||||
],
|
||||
'A1:C1',
|
||||
[
|
||||
['12 6 #DIV/0!', null, null],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testMergeCellsMergeBehaviourFormatted(): void
|
||||
{
|
||||
$expectedResult = [
|
||||
['1960-12-19 2022-09-15', null],
|
||||
];
|
||||
|
||||
$mergeRange = 'A1:B1';
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
$worksheet->fromArray($this->testDataFormatted, null, 'A1', true);
|
||||
$worksheet->getStyle($mergeRange)->getNumberFormat()->setFormatCode('yyyy-mm-dd');
|
||||
$worksheet->mergeCells($mergeRange, Worksheet::MERGE_CELL_CONTENT_MERGE);
|
||||
|
||||
$mergeResult = $worksheet->toArray(null, true, true, false);
|
||||
self::assertSame($expectedResult, $mergeResult);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue