Merge pull request #1 from ignaczistvan/master

Test + minor fixes/refacts
This commit is contained in:
quamis 2020-08-17 09:17:22 +03:00 committed by GitHub
commit ba1d66086d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 239 additions and 29 deletions

View File

@ -66,8 +66,10 @@ class Style
/** @var bool Whether the wrap text property was set */
private $hasSetWrapText = false;
private $shrinkToFit = false;
/** @var bool Whether the cell should shrink to fit to content */
private $shouldShrinkToFit = false;
/** @var bool Whether the shouldShrinkToFit text property was set */
private $hasSetShrinkToFit = false;
/** @var Border */
private $border;
@ -474,7 +476,7 @@ class Style
*/
public function setShouldShrinkToFit($shrinkToFit = true)
{
$this->shrinkToFit = $shrinkToFit;
$this->hasSetShrinkToFit = true;
$this->shouldShrinkToFit = $shrinkToFit;
return $this;
@ -487,4 +489,12 @@ class Style
{
return $this->shouldShrinkToFit;
}
/**
* @return bool
*/
public function hasSetShrinkToFit()
{
return $this->hasSetShrinkToFit;
}
}

View File

@ -19,4 +19,13 @@ interface OptionsManagerInterface
* @return mixed|null The set option or NULL if no option with given name found
*/
public function getOption($optionName);
/**
* Add an option to the internal list of options
* Used only for mergeCells() for now
* @param mixed $optionName
* @param mixed $optionValue
* @return void
*/
public function addOption($optionName, $optionValue);
}

View File

@ -186,7 +186,8 @@ class StyleBuilder
/**
* Set should shrink to fit
* @param bool $shrinkToFit
* @return void
* @return StyleBuilder
* @api
*/
public function setShouldShrinkToFit($shrinkToFit = true)
{

View File

@ -85,6 +85,9 @@ class StyleMerger
if (!$style->hasSetWrapText() && $baseStyle->shouldWrapText()) {
$styleToUpdate->setShouldWrapText();
}
if (!$style->hasSetShrinkToFit() && $baseStyle->shouldShrinkToFit()) {
$styleToUpdate->setShouldShrinkToFit();
}
if (!$style->hasSetCellAlignment() && $baseStyle->shouldApplyCellAlignment()) {
$styleToUpdate->setCellAlignment($baseStyle->getCellAlignment());
}

View File

@ -4,6 +4,7 @@ namespace Box\Spout\Writer;
use Box\Spout\Common\Creator\HelperFactory;
use Box\Spout\Common\Entity\Row;
use Box\Spout\Common\Exception\IOException;
use Box\Spout\Common\Helper\GlobalFunctionsHelper;
use Box\Spout\Common\Manager\OptionsManagerInterface;
use Box\Spout\Writer\Common\Creator\ManagerFactoryInterface;
@ -61,31 +62,6 @@ abstract class WriterMultiSheetsAbstract extends WriterAbstract
return $this;
}
/**
* Set columns widths as list. If value is null will set column with default width (8.43)
* @param array $columnWidths
* @return WriterMultiSheetsAbstract
*/
public function setColumnWidths(array $columnWidths)
{
$this->optionsManager->setOption(Options::COLUMN_WIDTHS, $columnWidths);
return $this;
}
/**
* Undocumented function
*
* @param array $range
* @return void
*/
public function mergeCells(array $range1, array $range2)
{
$this->optionsManager->addOption(Options::MERGE_CELLS, [$range1, $range2]);
return $this;
}
/**
* {@inheritdoc}
*/
@ -122,6 +98,7 @@ abstract class WriterMultiSheetsAbstract extends WriterAbstract
* Creates a new sheet and make it the current sheet. The data will now be written to this sheet.
*
* @throws WriterNotOpenedException If the writer has not been opened yet
* @throws IOException If unable to open the sheet for writing
* @return Sheet The created sheet
*/
public function addNewSheetAndMakeItCurrent()

View File

@ -249,7 +249,7 @@ EOD;
$content .= \sprintf(' applyBorder="%d"', $style->shouldApplyBorder() ? 1 : 0);
if ($style->shouldApplyCellAlignment() || $style->shouldWrapText()) {
if ($style->shouldApplyCellAlignment() || $style->shouldWrapText() || $style->shouldShrinkToFit()) {
$content .= ' applyAlignment="1">';
$content .= '<alignment';
if ($style->shouldApplyCellAlignment()) {

View File

@ -47,4 +47,34 @@ class Writer extends WriterMultiSheetsAbstract
return $this;
}
/**
* Set columns widths as list. If value is null will set column with default width (8.43)
* @param array $columnWidths
* @return WriterMultiSheetsAbstract
*/
public function setColumnWidths(array $columnWidths)
{
$this->optionsManager->setOption(Options::COLUMN_WIDTHS, $columnWidths);
return $this;
}
/**
* Merge cells.
* Row coordinates are indexed from 1, columns from 0 (A = 0),
* so a merge B2:G2 looks like $writer->mergeCells([1,2], [6, 2]);
*
* You may use CellHelper::getColumnLettersFromColumnIndex() to convert from "B2" to "[1,2]"
*
* @param int[] $range1 - top left cell's coordinate [column, row]
* @param int[] $range2 - bottom right cell's coordinate [column, row]
* @return $this
*/
public function mergeCells(array $range1, array $range2)
{
$this->optionsManager->addOption(Options::MERGE_CELLS, [$range1, $range2]);
return $this;
}
}

View File

@ -73,4 +73,28 @@ class OptionsManagerTest extends TestCase
$optionsManager->setOption('not-supported', 'something');
$this->assertNull($optionsManager->getOption('not-supported'));
}
/**
* @return void
*/
public function testOptionManagerShouldReturnArrayIfListOptionsAdded()
{
$optionsManager = $this->optionsManager;
$optionsManager->addOption('bar', 'something');
$optionsManager->addOption('bar', 'something-else');
$this->assertIsArray($optionsManager->getOption('bar'));
$this->assertCount(2, $optionsManager->getOption('bar'));
$this->assertEquals('something', $optionsManager->getOption('bar')[0]);
$this->assertEquals('something-else', $optionsManager->getOption('bar')[1]);
}
/**
* @return void
*/
public function testOptionsManagerShouldReturnNullIfListOptionNotSupported()
{
$optionsManager = $this->optionsManager;
$optionsManager->addOption('not-supported', 'something');
$this->assertNull($optionsManager->getOption('not-supported'));
}
}

View File

@ -7,6 +7,7 @@ use Box\Spout\Common\Entity\Row;
use Box\Spout\Common\Exception\InvalidArgumentException;
use Box\Spout\Common\Exception\IOException;
use Box\Spout\Common\Exception\SpoutException;
use Box\Spout\Reader\Wrapper\XMLReader;
use Box\Spout\TestUsingResource;
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
use Box\Spout\Writer\Exception\WriterAlreadyOpenedException;
@ -527,6 +528,105 @@ class WriterTest extends TestCase
$this->assertInlineDataWasWrittenToSheet($fileName, 1, 'control _x0015_ character');
}
/**
* @return void
*/
public function testAddRowShouldSupportRowHeights()
{
$fileName = 'test_add_row_should_support_row_heights.xlsx';
$dataRows = $this->createRowsFromValues([
['First row with default height'],
['Second row with custom height'],
]);
$dataRows[1]->setHeight('23');
$this->writeToXLSXFile($dataRows, $fileName);
$firstRow = $this->getXmlRowFromXmlFile($fileName, 1, 1);
$secondRow = $this->getXmlRowFromXmlFile($fileName, 1, 2);
$this->assertEquals('15', $firstRow->getAttribute('ht'), '1st row does not have default height.');
$this->assertEquals('23', $secondRow->getAttribute('ht'), '2nd row does not have custom height.');
}
/**
* @return void
*/
public function testAddRowShouldSupportColumnWidths()
{
$fileName = 'test_add_row_should_support_column_widths.xlsx';
$this->createGeneratedFolderIfNeeded($fileName);
$resourcePath = $this->getGeneratedResourcePath($fileName);
$writer = WriterEntityFactory::createXLSXWriter();
$writer->setShouldUseInlineStrings(true);
$writer->openToFile($resourcePath);
$columnWidths = [1, 2, 3, 4];
$writer->setColumnWidths($columnWidths);
$writer->addRows($this->createRowsFromValues([
['Test cell'],
]));
$writer->close();
$xmlReader = $this->getXmlReaderForSheetFromXmlFile($fileName, 1);
$xmlReader->readUntilNodeFound('cols');
$this->assertEquals('cols', $xmlReader->getCurrentNodeName(), 'Sheet does not have cols tag');
$this->assertEquals(count($columnWidths), $xmlReader->expand()->childNodes->length, 'Sheet does not have the specified number of column definitions');
foreach ($columnWidths as $index => $columnWidth) {
$xmlReader->readUntilNodeFound('col');
$this->assertEquals($index + 1, $xmlReader->expand()->getAttribute('min'));
$this->assertEquals($index + 1, $xmlReader->expand()->getAttribute('max'));
$this->assertEquals($columnWidth, $xmlReader->expand()->getAttribute('width'));
}
}
/**
* @return void
*/
public function testCloseShouldAddMergeCellTags()
{
$fileName = 'test_add_row_should_support_column_widths.xlsx';
$this->createGeneratedFolderIfNeeded($fileName);
$resourcePath = $this->getGeneratedResourcePath($fileName);
$writer = WriterEntityFactory::createXLSXWriter();
$writer->setShouldUseInlineStrings(true);
$writer->openToFile($resourcePath);
$writer->mergeCells([0, 1], [3, 1]);
$writer->mergeCells([2, 3], [10, 3]);
$writer->close();
$xmlReader = $this->getXmlReaderForSheetFromXmlFile($fileName, 1);
$xmlReader->readUntilNodeFound('mergeCells');
$this->assertEquals('mergeCells', $xmlReader->getCurrentNodeName(), 'Sheet does not have mergeCells tag');
$this->assertEquals(2, $xmlReader->expand()->childNodes->length, 'Sheet does not have the specified number of mergeCell definitions');
$xmlReader->readUntilNodeFound('mergeCell');
$this->assertEquals('A1:D1', $xmlReader->expand()->getAttribute('ref'), 'Merge ref for first range is not valid.');
$xmlReader->readUntilNodeFound('mergeCell');
$this->assertEquals('C3:K3', $xmlReader->expand()->getAttribute('ref'), 'Merge ref for second range is not valid.');
}
/**
* @return void
*/
public function testGeneratedFileShouldBeValidForEmptySheets()
{
$fileName = 'test_empty_sheet.xlsx';
$this->createGeneratedFolderIfNeeded($fileName);
$resourcePath = $this->getGeneratedResourcePath($fileName);
$writer = WriterEntityFactory::createXLSXWriter();
$writer->openToFile($resourcePath);
$writer->addNewSheetAndMakeItCurrent();
$writer->close();
$xmlReader = $this->getXmlReaderForSheetFromXmlFile($fileName, 1);
$xmlReader->setParserProperty(XMLReader::VALIDATE, true);
$this->assertTrue($xmlReader->isValid(), 'worksheet xml is not valid');
$xmlReader->setParserProperty(XMLReader::VALIDATE, false);
$xmlReader->readUntilNodeFound('sheetData');
$this->assertEquals('sheetData', $xmlReader->getCurrentNodeName(), 'worksheet xml does not have sheetData');
}
/**
* @return void
*/
@ -641,4 +741,42 @@ class WriterTest extends TestCase
$this->assertContains($sharedString, $xmlContents, $message);
}
/**
* @param $fileName
* @param $sheetIndex - 1 based
* @return XMLReader
*/
private function getXmlReaderForSheetFromXmlFile($fileName, $sheetIndex)
{
$resourcePath = $this->getGeneratedResourcePath($fileName);
$xmlReader = new XMLReader();
$xmlReader->openFileInZip($resourcePath, 'xl/worksheets/sheet' . $sheetIndex . '.xml');
return $xmlReader;
}
/**
* @param $fileName
* @param $sheetIndex - 1 based
* @param $rowIndex - 1 based
* @throws \Box\Spout\Reader\Exception\XMLProcessingException
* @return \DOMNode|null
*/
private function getXmlRowFromXmlFile($fileName, $sheetIndex, $rowIndex)
{
$xmlReader = $this->getXmlReaderForSheetFromXmlFile($fileName, $sheetIndex);
$xmlReader->readUntilNodeFound('sheetData');
for ($i = 0; $i < $rowIndex; $i++) {
$xmlReader->readUntilNodeFound('row');
}
$row = $xmlReader->expand();
$xmlReader->close();
return $row;
}
}

View File

@ -306,6 +306,24 @@ class WriterWithStyleTest extends TestCase
$this->assertFirstChildHasAttributeEquals(CellAlignment::RIGHT, $xfElement, 'alignment', 'horizontal');
}
/**
* @return void
*/
public function testAddRowShouldApplyShrinkToFit()
{
$fileName = 'test_add_row_should_apply_shrink_to_fit.xlsx';
$shrinkToFitStyle = (new StyleBuilder())->setShouldShrinkToFit()->build();
$dataRows = $this->createStyledRowsFromValues([['xlsx--11']], $shrinkToFitStyle);
$this->writeToXLSXFile($dataRows, $fileName);
$cellXfsDomElement = $this->getXmlSectionFromStylesXmlFile($fileName, 'cellXfs');
$xfElement = $cellXfsDomElement->getElementsByTagName('xf')->item(1);
$this->assertEquals(1, $xfElement->getAttribute('applyAlignment'));
$this->assertFirstChildHasAttributeEquals('true', $xfElement, 'alignment', 'shrinkToFit');
}
/**
* @return void
*/