diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f783d65..7b51acbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added +- Support to write merged cells in ODS format [#287](https://github.com/PHPOffice/PhpSpreadsheet/issues/287) + ### Changed ### Fixed diff --git a/src/PhpSpreadsheet/Reader/Ods.php b/src/PhpSpreadsheet/Reader/Ods.php index b433c2d9..5dd8219d 100644 --- a/src/PhpSpreadsheet/Reader/Ods.php +++ b/src/PhpSpreadsheet/Reader/Ods.php @@ -696,8 +696,8 @@ class Ods extends BaseReader } // Merged cells - if ($childNode->hasAttributeNS($tableNs, 'number-columns-spanned') - || $childNode->hasAttributeNS($tableNs, 'number-rows-spanned') + if ($cellData->hasAttributeNS($tableNs, 'number-columns-spanned') + || $cellData->hasAttributeNS($tableNs, 'number-rows-spanned') ) { if (($type !== DataType::TYPE_NULL) || (!$this->readDataOnly)) { $columnTo = $columnID; diff --git a/src/PhpSpreadsheet/Writer/Ods/Content.php b/src/PhpSpreadsheet/Writer/Ods/Content.php index 69d31eff..40039eea 100644 --- a/src/PhpSpreadsheet/Writer/Ods/Content.php +++ b/src/PhpSpreadsheet/Writer/Ods/Content.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Writer\Ods; +use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; @@ -183,6 +184,7 @@ class Content extends WriterPart $this->writeCellSpan($objWriter, $column, $prevColumn); $objWriter->startElement('table:table-cell'); + $this->writeCellMerge($objWriter, $cell); // Style XF $style = $cell->getXfIndex(); @@ -363,4 +365,29 @@ class Content extends WriterPart $writer->endElement(); // Close style:style } } + + /** + * Write attributes for merged cell. + * + * @param XMLWriter $objWriter + * @param Cell $cell + * + * @throws \PhpOffice\PhpSpreadsheet\Exception + */ + private function writeCellMerge(XMLWriter $objWriter, Cell $cell) + { + if (!$cell->isMergeRangeValueCell()) { + return; + } + + $mergeRange = Coordinate::splitRange($cell->getMergeRange()); + list($startCell, $endCell) = $mergeRange[0]; + $start = Coordinate::coordinateFromString($startCell); + $end = Coordinate::coordinateFromString($endCell); + $columnSpan = Coordinate::columnIndexFromString($end[0]) - Coordinate::columnIndexFromString($start[0]) + 1; + $rowSpan = $end[1] - $start[1] + 1; + + $objWriter->writeAttribute('table:number-columns-spanned', $columnSpan); + $objWriter->writeAttribute('table:number-rows-spanned', $rowSpan); + } } diff --git a/tests/PhpSpreadsheetTests/MergedCells.php b/tests/PhpSpreadsheetTests/MergedCells.php new file mode 100644 index 00000000..753c0077 --- /dev/null +++ b/tests/PhpSpreadsheetTests/MergedCells.php @@ -0,0 +1,63 @@ +writeMergedCells($filename, $format); + $actual = $this->readMergedCells($filename, $format); + unlink($filename); + + self::assertSame(1, $actual, "Format $format failed, could not read 1 merged cell"); + } + + private function writeMergedCells($filename, $format) + { + $spreadsheet = new Spreadsheet(); + $spreadsheet->setActiveSheetIndex(0); + $spreadsheet->getActiveSheet()->setCellValue('A1', '1'); + $spreadsheet->getActiveSheet()->setCellValue('B1', '2'); + $spreadsheet->getActiveSheet()->setCellValue('A2', '33'); + $spreadsheet->getActiveSheet()->mergeCells('A2:B2'); + + $writer = IOFactory::createWriter($spreadsheet, $format); + + $writer->save($filename); + } + + private function readMergedCells($filename, $format) + { + $reader = IOFactory::createReader($format); + $spreadsheet = $reader->load($filename); + $n = 0; + foreach ($spreadsheet->getWorksheetIterator() as $worksheet) { + foreach ($worksheet->getMergeCells() as $cells) { + ++$n; + } + } + + return $n; + } +}