Support to write merged cells in ODS format

Fixes #287
This commit is contained in:
Adrien Crivelli 2017-12-11 12:17:40 +09:00
parent 962367c95f
commit 96f3f666d6
No known key found for this signature in database
GPG Key ID: B182FD79DC6DE92E
4 changed files with 94 additions and 2 deletions

View File

@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Added ### Added
- Support to write merged cells in ODS format [#287](https://github.com/PHPOffice/PhpSpreadsheet/issues/287)
### Changed ### Changed
### Fixed ### Fixed

View File

@ -696,8 +696,8 @@ class Ods extends BaseReader
} }
// Merged cells // Merged cells
if ($childNode->hasAttributeNS($tableNs, 'number-columns-spanned') if ($cellData->hasAttributeNS($tableNs, 'number-columns-spanned')
|| $childNode->hasAttributeNS($tableNs, 'number-rows-spanned') || $cellData->hasAttributeNS($tableNs, 'number-rows-spanned')
) { ) {
if (($type !== DataType::TYPE_NULL) || (!$this->readDataOnly)) { if (($type !== DataType::TYPE_NULL) || (!$this->readDataOnly)) {
$columnTo = $columnID; $columnTo = $columnID;

View File

@ -2,6 +2,7 @@
namespace PhpOffice\PhpSpreadsheet\Writer\Ods; namespace PhpOffice\PhpSpreadsheet\Writer\Ods;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
@ -183,6 +184,7 @@ class Content extends WriterPart
$this->writeCellSpan($objWriter, $column, $prevColumn); $this->writeCellSpan($objWriter, $column, $prevColumn);
$objWriter->startElement('table:table-cell'); $objWriter->startElement('table:table-cell');
$this->writeCellMerge($objWriter, $cell);
// Style XF // Style XF
$style = $cell->getXfIndex(); $style = $cell->getXfIndex();
@ -363,4 +365,29 @@ class Content extends WriterPart
$writer->endElement(); // Close style:style $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);
}
} }

View File

@ -0,0 +1,63 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class MergedCells extends TestCase
{
public function providerMergedCells()
{
return [
// ['Html'],
// ['Xls'],
// ['Xlsx'],
['Ods'],
];
}
/**
* @dataProvider providerMergedCells
*
* @param string $format
*/
public function testMergedCells($format)
{
$filename = tempnam(sys_get_temp_dir(), strtolower($format));
$this->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;
}
}