From 26ad59033c6adcbb4caa776d1f2a0d6b0eae93e4 Mon Sep 17 00:00:00 2001 From: Alexander Hofstede Date: Tue, 17 Dec 2019 22:05:01 +0100 Subject: [PATCH] Add support for default cell sizes for ODS files --- .../Writer/ODS/Manager/Style/StyleManager.php | 13 ++++- .../Writer/ODS/Manager/WorksheetManager.php | 46 ++++++++++++++- tests/Spout/Writer/ODS/SheetTest.php | 56 ++++++++++++++++--- 3 files changed, 104 insertions(+), 11 deletions(-) diff --git a/src/Spout/Writer/ODS/Manager/Style/StyleManager.php b/src/Spout/Writer/ODS/Manager/Style/StyleManager.php index 5b3bb0d..23af826 100644 --- a/src/Spout/Writer/ODS/Manager/Style/StyleManager.php +++ b/src/Spout/Writer/ODS/Manager/Style/StyleManager.php @@ -4,6 +4,7 @@ namespace Box\Spout\Writer\ODS\Manager\Style; use Box\Spout\Common\Entity\Style\BorderPart; use Box\Spout\Writer\Common\Entity\Worksheet; +use Box\Spout\Writer\Common\Manager\ManagesCellSize; use Box\Spout\Writer\ODS\Helper\BorderHelper; /** @@ -12,6 +13,8 @@ use Box\Spout\Writer\ODS\Helper\BorderHelper; */ class StyleManager extends \Box\Spout\Writer\Common\Manager\Style\StyleManager { + use ManagesCellSize; + /** @var StyleRegistry */ protected $styleRegistry; @@ -161,12 +164,16 @@ EOD; $content .= $this->getStyleSectionContent($style); } - $content .= <<<'EOD' + $useOptimalRowHeight = empty($this->defaultRowHeight) ? 'true' : 'false'; + $defaultRowHeight = empty($this->defaultRowHeight) ? '15pt' : "{$this->defaultRowHeight}pt"; + $defaultColumnWidth = empty($this->defaultColumnWidth) ? '' : "style:column-width=\"{$this->defaultColumnWidth}pt\""; + + $content .= << - + - + EOD; diff --git a/src/Spout/Writer/ODS/Manager/WorksheetManager.php b/src/Spout/Writer/ODS/Manager/WorksheetManager.php index 6d76fa0..f0fc26e 100644 --- a/src/Spout/Writer/ODS/Manager/WorksheetManager.php +++ b/src/Spout/Writer/ODS/Manager/WorksheetManager.php @@ -9,6 +9,7 @@ use Box\Spout\Common\Exception\InvalidArgumentException; use Box\Spout\Common\Exception\IOException; use Box\Spout\Common\Helper\Escaper\ODS as ODSEscaper; use Box\Spout\Common\Helper\StringHelper; +use Box\Spout\Writer\Common\Entity\Options; use Box\Spout\Writer\Common\Entity\Worksheet; use Box\Spout\Writer\Common\Manager\Style\StyleMerger; use Box\Spout\Writer\Common\Manager\WorksheetManagerInterface; @@ -39,17 +40,25 @@ class WorksheetManager implements WorksheetManagerInterface * @param StyleMerger $styleMerger * @param ODSEscaper $stringsEscaper * @param StringHelper $stringHelper + * @param OptionsManager|null $optionsManager */ public function __construct( StyleManager $styleManager, StyleMerger $styleMerger, ODSEscaper $stringsEscaper, - StringHelper $stringHelper + StringHelper $stringHelper, + $optionsManager = null ) { $this->styleManager = $styleManager; $this->styleMerger = $styleMerger; $this->stringsEscaper = $stringsEscaper; $this->stringHelper = $stringHelper; + + if ($optionsManager) { + $this->setDefaultColumnWidth($optionsManager->getOption(Options::DEFAULT_COLUMN_WIDTH)); + $this->setDefaultRowHeight($optionsManager->getOption(Options::DEFAULT_ROW_HEIGHT)); + $this->columnWidths = $optionsManager->getOption(Options::COLUMN_WIDTHS) ?? []; + } } /** @@ -229,4 +238,39 @@ class WorksheetManager implements WorksheetManagerInterface fclose($worksheetFilePointer); } + + /** + * @param float|null $width + */ + public function setDefaultColumnWidth($width) + { + $this->styleManager->setDefaultColumnWidth($width); + } + + /** + * @param float|null $height + */ + public function setDefaultRowHeight($height) + { + $this->styleManager->setDefaultRowHeight($height); + } + + /** + * @param float $width + * @param array $columns One or more columns with this width + */ + public function setColumnWidth(float $width, ...$columns) + { + $this->styleManager->setColumnWidth($width, ...$columns); + } + + /** + * @param float $width The width to set + * @param int $start First column index of the range + * @param int $end Last column index of the range + */ + public function setColumnWidthForRange(float $width, int $start, int $end) + { + $this->styleManager->setColumnWidthForRange($width, $start, $end); + } } diff --git a/tests/Spout/Writer/ODS/SheetTest.php b/tests/Spout/Writer/ODS/SheetTest.php index a964a59..512b77e 100644 --- a/tests/Spout/Writer/ODS/SheetTest.php +++ b/tests/Spout/Writer/ODS/SheetTest.php @@ -6,6 +6,7 @@ use Box\Spout\TestUsingResource; use Box\Spout\Writer\Common\Creator\WriterEntityFactory; use Box\Spout\Writer\Common\Entity\Sheet; use Box\Spout\Writer\Exception\InvalidSheetNameException; +use Box\Spout\Writer\Exception\WriterNotOpenedException; use Box\Spout\Writer\RowCreationHelper; use PHPUnit\Framework\TestCase; @@ -82,7 +83,7 @@ class SheetTest extends TestCase */ public function testSetSheetVisibilityShouldCreateSheetHidden() { - $fileName = 'test_set_visibility_should_create_sheet_hidden.xlsx'; + $fileName = 'test_set_visibility_should_create_sheet_hidden.ods'; $this->writeDataToHiddenSheet($fileName); $resourcePath = $this->getGeneratedResourcePath($fileName); @@ -92,12 +93,41 @@ class SheetTest extends TestCase $this->assertContains(' table:display="false"', $xmlContents, 'The sheet visibility should have been changed to "hidden"'); } - /** - * @param string $fileName - * @param string $sheetName - * @return Sheet - */ - private function writeDataAndReturnSheetWithCustomName($fileName, $sheetName) + function testThrowsIfWorkbookIsNotInitialized() + { + $this->expectException(WriterNotOpenedException::class); + $writer = WriterEntityFactory::createODSWriter(); + + $writer->addRow($this->createRowFromValues([])); + } + + public function testThrowsWhenTryingToSetDefaultsBeforeWorkbookLoaded() + { + $this->expectException(WriterNotOpenedException::class); + $writer = WriterEntityFactory::createXLSXWriter(); + $writer->setDefaultColumnWidth(10.0); + } + + public function testWritesDefaultCellSizesIfSet() + { + $fileName = 'test_writes_default_cell_sizes_if_set.ods'; + $writer = $this->writerForFile($fileName); + + $writer->setDefaultColumnWidth(100.0); + $writer->setDefaultRowHeight(20.0); + $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(' style:column-width="100pt"', $xmlContents, 'No default col width found in sheet'); + $this->assertContains(' style:row-height="20pt"', $xmlContents, 'No default row height found in sheet'); + $this->assertContains(' style:use-optimal-row-height="false', $xmlContents, 'No optimal row height override found in sheet'); + } + + private function writerForFile($fileName) { $this->createGeneratedFolderIfNeeded($fileName); $resourcePath = $this->getGeneratedResourcePath($fileName); @@ -105,6 +135,18 @@ class SheetTest extends TestCase $writer = WriterEntityFactory::createODSWriter(); $writer->openToFile($resourcePath); + return $writer; + } + + /** + * @param string $fileName + * @param string $sheetName + * @return void + */ + private function writeDataAndReturnSheetWithCustomName($fileName, $sheetName) + { + $writer = $this->writerForFile($fileName); + $sheet = $writer->getCurrentSheet(); $sheet->setName($sheetName);