From 4efda2a512af26d75635d9050f832362f91ec59c Mon Sep 17 00:00:00 2001 From: Paolo Agostinetto Date: Sat, 4 Mar 2017 16:18:56 +0100 Subject: [PATCH] Ods\Writer\Content: added support for xr styles (bold, italic, font family, font size, underline, bg color) --- src/PhpSpreadsheet/Writer/Ods/Content.php | 120 +++++++++++++++++- .../Writer/Ods/ContentTest.php | 16 +++ tests/data/Writer/Ods/content-empty.xml | 9 +- tests/data/Writer/Ods/content-with-data.xml | 69 ++++++++-- 4 files changed, 199 insertions(+), 15 deletions(-) diff --git a/src/PhpSpreadsheet/Writer/Ods/Content.php b/src/PhpSpreadsheet/Writer/Ods/Content.php index 5ad90f95..a7c5556f 100644 --- a/src/PhpSpreadsheet/Writer/Ods/Content.php +++ b/src/PhpSpreadsheet/Writer/Ods/Content.php @@ -30,6 +30,8 @@ namespace PhpOffice\PhpSpreadsheet\Writer\Ods; use PhpOffice\PhpSpreadsheet\Cell; use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; use PhpOffice\PhpSpreadsheet\Spreadsheet; +use PhpOffice\PhpSpreadsheet\Style\Fill; +use PhpOffice\PhpSpreadsheet\Style\Font; use PhpOffice\PhpSpreadsheet\Worksheet; use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Writer\Exception; @@ -47,6 +49,7 @@ class Content extends WriterPart { const NUMBER_COLS_REPEATED_MAX = 1024; const NUMBER_ROWS_REPEATED_MAX = 1048576; + const CELL_STYLE_PREFIX = 'ce'; /** * Write content.xml to XML format. @@ -105,7 +108,11 @@ class Content extends WriterPart $objWriter->writeElement('office:scripts'); $objWriter->writeElement('office:font-face-decls'); - $objWriter->writeElement('office:automatic-styles'); + + // Styles XF + $objWriter->startElement('office:automatic-styles'); + $this->writeXfStyles($objWriter, $this->getParentWriter()->getSpreadsheet()); + $objWriter->endElement(); $objWriter->startElement('office:body'); $objWriter->startElement('office:spreadsheet'); @@ -193,12 +200,20 @@ class Content extends WriterPart $prevColumn = -1; $cells = $row->getCellIterator(); while ($cells->valid()) { + + /** @var Cell $cell */ $cell = $cells->current(); $column = Cell::columnIndexFromString($cell->getColumn()) - 1; $this->writeCellSpan($objWriter, $column, $prevColumn); $objWriter->startElement('table:table-cell'); + // Style XF + $style = $cell->getXfIndex(); + if($style !== null){ + $objWriter->writeAttribute('table:style-name', self::CELL_STYLE_PREFIX.$style); + } + switch ($cell->getDataType()) { case DataType::TYPE_BOOL: $objWriter->writeAttribute('office:value-type', 'boolean'); @@ -271,4 +286,107 @@ class Content extends WriterPart $objWriter->endElement(); } } + + /** + * Write XF cell styles + * + * @param XMLWriter $writer + * @param Spreadsheet $spreadsheet + */ + private function writeXfStyles(XMLWriter $writer, Spreadsheet $spreadsheet) + { + foreach($spreadsheet->getCellXfCollection() as $style) { + + $writer->startElement('style:style'); + $writer->writeAttribute('style:name', self::CELL_STYLE_PREFIX . $style->getIndex()); + $writer->writeAttribute('style:family', 'table-cell'); + $writer->writeAttribute('style:parent-style-name', 'Default'); + + /* + * style:text-properties + */ + + // Font + $writer->startElement('style:text-properties'); + + $font = $style->getFont(); + + if($font->getBold()) { + $writer->writeAttribute('fo:font-weight', 'bold'); + $writer->writeAttribute('style:font-weight-complex', 'bold'); + $writer->writeAttribute('style:font-weight-asian', 'bold'); + } + + if($font->getItalic()) { + $writer->writeAttribute('fo:font-style', 'italic'); + } + + if($color = $font->getColor()) { + $writer->writeAttribute('fo:color', sprintf('#%s', $color->getRGB())); + } + + if($family = $font->getName()) { + $writer->writeAttribute('fo:font-family', $family); + } + + if($size = $font->getSize()) { + $writer->writeAttribute('fo:font-size', sprintf('%.1fpt', $size)); + } + + if($font->getUnderline() && $font->getUnderline() != Font::UNDERLINE_NONE) { + + $writer->writeAttribute('style:text-underline-style', 'solid'); + $writer->writeAttribute('style:text-underline-width', 'auto'); + $writer->writeAttribute('style:text-underline-color', 'font-color'); + + switch($font->getUnderline()){ + + case Font::UNDERLINE_DOUBLE: + $writer->writeAttribute('style:text-underline-type', 'double'); + break; + + case Font::UNDERLINE_SINGLE: + $writer->writeAttribute('style:text-underline-type', 'single'); + break; + } + } + + $writer->endElement(); // Close style:text-properties + + /* + * style:table-cell-properties + */ + + $writer->startElement('style:table-cell-properties'); + $writer->writeAttribute('style:rotation-align', 'none'); + + // Fill + if($fill = $style->getFill()) { + switch($fill->getFillType()) { + + case Fill::FILL_SOLID: + $writer->writeAttribute('fo:background-color', sprintf('#%s', + strtolower($fill->getStartColor()->getRGB()) + )); + break; + + case Fill::FILL_GRADIENT_LINEAR: + case Fill::FILL_GRADIENT_PATH: + /// TODO :: To be implemented + break; + + case Fill::FILL_NONE: + default: + } + } + + $writer->endElement(); // Close style:table-cell-properties + + /* + * End + */ + + $writer->endElement(); // Close style:style + } + } } diff --git a/tests/PhpSpreadsheetTests/Writer/Ods/ContentTest.php b/tests/PhpSpreadsheetTests/Writer/Ods/ContentTest.php index 70d920dc..baf22703 100644 --- a/tests/PhpSpreadsheetTests/Writer/Ods/ContentTest.php +++ b/tests/PhpSpreadsheetTests/Writer/Ods/ContentTest.php @@ -6,6 +6,8 @@ use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Shared\Date; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style\Color; +use PhpOffice\PhpSpreadsheet\Style\Fill; +use PhpOffice\PhpSpreadsheet\Style\Font; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Writer\Ods; use PhpOffice\PhpSpreadsheet\Writer\Ods\Content; @@ -46,6 +48,20 @@ class ContentTest extends \PHPUnit_Framework_TestCase ->getNumberFormat() ->setFormatCode(NumberFormat::FORMAT_DATE_DATETIME); + // Styles + $worksheet1->getStyle('A1')->getFont()->setBold(true); + $worksheet1->getStyle('B1')->getFont()->setItalic(true); + $worksheet1->getStyle('C1')->getFont()->setName("Courier"); + $worksheet1->getStyle('C1')->getFont()->setSize(14); + $worksheet1->getStyle('C1')->getFont()->setColor(new Color(Color::COLOR_BLUE)); + + $worksheet1->getStyle('C1')->getFill()->setFillType(Fill::FILL_SOLID); + $worksheet1->getStyle('C1')->getFill()->setStartColor(new Color(Color::COLOR_RED)); + + $worksheet1->getStyle('C1')->getFont()->setUnderline(Font::UNDERLINE_SINGLE); + $worksheet1->getStyle('C2')->getFont()->setUnderline(Font::UNDERLINE_DOUBLE); + $worksheet1->getStyle('D2')->getFont()->setUnderline(Font::UNDERLINE_NONE); + // Worksheet 2 $worksheet2 = $workbook->createSheet(); $worksheet2->setTitle('New Worksheet'); diff --git a/tests/data/Writer/Ods/content-empty.xml b/tests/data/Writer/Ods/content-empty.xml index 67cc35f2..87f756db 100644 --- a/tests/data/Writer/Ods/content-empty.xml +++ b/tests/data/Writer/Ods/content-empty.xml @@ -2,7 +2,12 @@ - + + + + + + @@ -10,7 +15,7 @@ - + diff --git a/tests/data/Writer/Ods/content-with-data.xml b/tests/data/Writer/Ods/content-with-data.xml index 42f87553..4ee12098 100644 --- a/tests/data/Writer/Ods/content-with-data.xml +++ b/tests/data/Writer/Ods/content-with-data.xml @@ -2,7 +2,52 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -10,37 +55,37 @@ - + 1 - + 12345.6789 - + 1 - + 01234 - + Lorem ipsum - + 1 - + - + 1 TRUE - + 42798.572060185 - + @@ -48,7 +93,7 @@ - + 2