diff --git a/src/Spout/Writer/ODS/Manager/Style/StyleManager.php b/src/Spout/Writer/ODS/Manager/Style/StyleManager.php index d18efb6..e563028 100644 --- a/src/Spout/Writer/ODS/Manager/Style/StyleManager.php +++ b/src/Spout/Writer/ODS/Manager/Style/StyleManager.php @@ -188,6 +188,15 @@ EOD; EOD; } + // Sort column widths since ODS cares about order + usort($this->columnWidths, function($a, $b) { + if ($a[0] == $b[0]) { + return 0; + } + return ($a[0] < $b[0]) ? -1 : 1; + }); + $content .= $this->getTableColumnStylesXMLContent(); + $content .= ''; return $content; @@ -340,4 +349,40 @@ EOD; $style->getBackgroundColor() ); } + + public function getTableColumnStylesXMLContent(): string + { + if (empty($this->columnWidths)) { + return ''; + } + + $content = ''; + foreach ($this->columnWidths as $styleIndex => $entry) { + $content .= << + + +EOD; + } + return $content; + } + + public function getStyledTableColumnXMLContent(int $maxNumColumns): string + { + if (empty($this->columnWidths)) { + return ''; + } + + $content = ''; + foreach ($this->columnWidths as $styleIndex => $entry) { + $numCols = $entry[1] - $entry[0] + 1; + $content .= << +EOD; + } + // Note: This assumes the column widths are contiguous and default width is + // only applied to columns after the last custom column with a custom width + $content .= ''; + return $content; + } } diff --git a/src/Spout/Writer/ODS/Manager/WorksheetManager.php b/src/Spout/Writer/ODS/Manager/WorksheetManager.php index 3b47a8b..6623d67 100644 --- a/src/Spout/Writer/ODS/Manager/WorksheetManager.php +++ b/src/Spout/Writer/ODS/Manager/WorksheetManager.php @@ -103,7 +103,7 @@ class WorksheetManager implements WorksheetManagerInterface $tableStyleName = 'ta' . ($externalSheet->getIndex() + 1); $tableElement = ''; - $tableElement .= ''; + $tableElement .= $this->styleManager->getStyledTableColumnXMLContent($worksheet->getMaxNumColumns()); return $tableElement; } diff --git a/tests/Spout/Writer/ODS/SheetTest.php b/tests/Spout/Writer/ODS/SheetTest.php index 512b77e..fac513a 100644 --- a/tests/Spout/Writer/ODS/SheetTest.php +++ b/tests/Spout/Writer/ODS/SheetTest.php @@ -127,6 +127,87 @@ class SheetTest extends TestCase $this->assertContains(' style:use-optimal-row-height="false', $xmlContents, 'No optimal row height override found in sheet'); } + public function testWritesColumnWidths() + { + $fileName = 'test_column_widths.ods'; + $writer = $this->writerForFile($fileName); + + $writer->setColumnWidth(100.0, 1); + $writer->addRow($this->createRowFromValues(['ods--11', 'ods--12'])); + $writer->close(); + + $resourcePath = $this->getGeneratedResourcePath($fileName); + $pathToWorkbookFile = $resourcePath . '#content.xml'; + $xmlContents = file_get_contents('zip://' . $pathToWorkbookFile); + + $this->assertContains('', $xmlContents, 'No matching custom col style definition found in sheet'); + $this->assertContains('', $xmlContents, 'No matching table-column-properties found in sheet'); + $this->assertContains('table:style-name="co0"', $xmlContents, 'No matching table:style-name found in sheet'); + $this->assertContains('table:number-columns-repeated="1"', $xmlContents, 'No matching table:number-columns-repeated count found in sheet'); + } + + public function testWritesMultipleColumnWidths() + { + $fileName = 'test_multiple_column_widths.ods'; + $writer = $this->writerForFile($fileName); + + $writer->setColumnWidth(100.0, 1, 2, 3); + $writer->addRow($this->createRowFromValues(['ods--11', 'ods--12', 'ods--13'])); + $writer->close(); + + $resourcePath = $this->getGeneratedResourcePath($fileName); + $pathToWorkbookFile = $resourcePath . '#content.xml'; + $xmlContents = file_get_contents('zip://' . $pathToWorkbookFile); + + $this->assertContains('', $xmlContents, 'No matching custom col style definition found in sheet'); + $this->assertContains('', $xmlContents, 'No matching table-column-properties found in sheet'); + $this->assertContains('table:style-name="co0"', $xmlContents, 'No matching table:style-name found in sheet'); + $this->assertContains('table:number-columns-repeated="3"', $xmlContents, 'No matching table:number-columns-repeated count found in sheet'); + } + + public function testWritesMultipleColumnWidthsInRanges() + { + $fileName = 'test_multiple_column_widths_in_ranges.ods'; + $writer = $this->writerForFile($fileName); + + $writer->setColumnWidth(50.0, 1, 3, 4, 6); + $writer->setColumnWidth(100.0, 2, 5); + $writer->addRow($this->createRowFromValues(['ods--11', 'ods--12', 'ods--13', 'ods--14', 'ods--15', 'ods--16'])); + $writer->close(); + + $resourcePath = $this->getGeneratedResourcePath($fileName); + $pathToWorkbookFile = $resourcePath . '#content.xml'; + $xmlContents = file_get_contents('zip://' . $pathToWorkbookFile); + + $this->assertContains('', $xmlContents, 'No matching custom col style 0 definition found in sheet'); + $this->assertContains('', $xmlContents, 'No matching custom col style 1 definition found in sheet'); + $this->assertContains('', $xmlContents, 'No matching custom col style 2 definition found in sheet'); + $this->assertContains('', $xmlContents, 'No matching custom col style 3 definition found in sheet'); + $this->assertContains('', $xmlContents, 'No matching custom col style 4 definition found in sheet'); + $this->assertContains('', $xmlContents, 'No matching table-column-properties found in sheet'); + $this->assertContains('', $xmlContents, 'No matching table-column-properties found in sheet'); + $this->assertContains('', $xmlContents, 'No matching table:number-columns-repeated count found in sheet'); + } + + public function testCanTakeColumnWidthsAsRange() + { + $fileName = 'test_column_widths_as_ranges.ods'; + $writer = $this->writerForFile($fileName); + + $writer->setColumnWidthForRange(150.0, 1, 3); + $writer->addRow($this->createRowFromValues(['ods--11', 'ods--12', 'ods--13'])); + $writer->close(); + + $resourcePath = $this->getGeneratedResourcePath($fileName); + $pathToWorkbookFile = $resourcePath . '#content.xml'; + $xmlContents = file_get_contents('zip://' . $pathToWorkbookFile); + + $this->assertContains('', $xmlContents, 'No matching custom col style 0 definition found in sheet'); + $this->assertContains('style:column-width="150pt"/>', $xmlContents, 'No matching table-column-properties found in sheet'); + $this->assertContains('table:style-name="co0"', $xmlContents, 'No matching table:style-name found in sheet'); + $this->assertContains('table:number-columns-repeated="3"', $xmlContents, 'No matching table:number-columns-repeated count found in sheet'); + } + private function writerForFile($fileName) { $this->createGeneratedFolderIfNeeded($fileName);