#529 - tests for column width, row height and cell merge + minor refact
Tests Added 'addOption' to OptionsManagerInterface Moved 'setColumnWidths' and 'mergeCells' methods to Xlsx Writer implementation since the actual feature only works for Xlsx at the moment
This commit is contained in:
parent
817e4f1f01
commit
41a9ae89ee
@ -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);
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ class WriterWithStyleTest extends TestCase
|
||||
$cellXfsDomElement = $this->getXmlSectionFromStylesXmlFile($fileName, 'cellXfs');
|
||||
$xfElement = $cellXfsDomElement->getElementsByTagName('xf')->item(1);
|
||||
$this->assertEquals(1, $xfElement->getAttribute('applyAlignment'));
|
||||
$this->assertFirstChildHasAttributeEquals("true", $xfElement, 'alignment', 'shrinkToFit');
|
||||
$this->assertFirstChildHasAttributeEquals('true', $xfElement, 'alignment', 'shrinkToFit');
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user