Merge 06c53995dbd3c9c97798ba789116e23a6bd3ee43 into fec27e9056858cda1bcde8148fd3b3f6b2bc6f06

This commit is contained in:
madflow 2017-11-04 17:48:28 +00:00 committed by GitHub
commit 9fb0f91421
30 changed files with 1032 additions and 395 deletions

View File

@ -5,6 +5,7 @@ namespace Box\Spout\Writer\CSV;
use Box\Spout\Common\Exception\IOException; use Box\Spout\Common\Exception\IOException;
use Box\Spout\Common\Helper\EncodingHelper; use Box\Spout\Common\Helper\EncodingHelper;
use Box\Spout\Writer\Common\Entity\Options; use Box\Spout\Writer\Common\Entity\Options;
use Box\Spout\Writer\Common\Entity\Row;
use Box\Spout\Writer\WriterAbstract; use Box\Spout\Writer\WriterAbstract;
/** /**
@ -78,20 +79,20 @@ class Writer extends WriterAbstract
} }
/** /**
* Adds data to the currently opened writer. * Adds a row to the currently opened writer.
* *
* @param array $dataRow Array containing data to be written. * @param Row $row The row containing cells and styles
* Example $dataRow = ['data1', 1234, null, '', 'data5']; *
* @param \Box\Spout\Writer\Common\Entity\Style\Style $style Ignored here since CSV does not support styling. * @throws IOException If unable to write data
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
* @return void * @return void
* @internal param \Box\Spout\Writer\Common\Entity\Style\Style $style Ignored here since CSV does not support styling.
*/ */
protected function addRowToWriter(array $dataRow, $style) protected function addRowToWriter(Row $row)
{ {
$fieldDelimiter = $this->optionsManager->getOption(Options::FIELD_DELIMITER); $fieldDelimiter = $this->optionsManager->getOption(Options::FIELD_DELIMITER);
$fieldEnclosure = $this->optionsManager->getOption(Options::FIELD_ENCLOSURE); $fieldEnclosure = $this->optionsManager->getOption(Options::FIELD_ENCLOSURE);
$wasWriteSuccessful = $this->globalFunctionsHelper->fputcsv($this->filePointer, $dataRow, $fieldDelimiter, $fieldEnclosure); $wasWriteSuccessful = $this->globalFunctionsHelper->fputcsv($this->filePointer, $row->getCells(), $fieldDelimiter, $fieldEnclosure);
if ($wasWriteSuccessful === false) { if ($wasWriteSuccessful === false) {
throw new IOException('Unable to write data'); throw new IOException('Unable to write data');
} }

View File

@ -3,10 +3,14 @@
namespace Box\Spout\Writer\Common\Creator; namespace Box\Spout\Writer\Common\Creator;
use Box\Spout\Writer\Common\Entity\Cell; use Box\Spout\Writer\Common\Entity\Cell;
use Box\Spout\Writer\Common\Entity\Row;
use Box\Spout\Writer\Common\Entity\Sheet; use Box\Spout\Writer\Common\Entity\Sheet;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\Common\Entity\Workbook; use Box\Spout\Writer\Common\Entity\Workbook;
use Box\Spout\Writer\Common\Entity\Worksheet; use Box\Spout\Writer\Common\Entity\Worksheet;
use Box\Spout\Writer\Common\Manager\RowManager;
use Box\Spout\Writer\Common\Manager\SheetManager; use Box\Spout\Writer\Common\Manager\SheetManager;
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
/** /**
* Class EntityFactory * Class EntityFactory
@ -47,7 +51,7 @@ class EntityFactory
* @param mixed $cellValue * @param mixed $cellValue
* @return Cell * @return Cell
*/ */
public function createCell($cellValue) public static function createCell($cellValue)
{ {
return new Cell($cellValue); return new Cell($cellValue);
} }
@ -59,4 +63,17 @@ class EntityFactory
{ {
return new \ZipArchive(); return new \ZipArchive();
} }
/**
* @param array $cells
* @param Style|null $style
* @return Row
*/
public static function createRow(array $cells, Style $style = null)
{
$styleMerger = new StyleMerger();
$rowManager = new RowManager($styleMerger);
return new Row($cells, $style, $rowManager);
}
} }

View File

@ -2,7 +2,9 @@
namespace Box\Spout\Writer\Common\Entity; namespace Box\Spout\Writer\Common\Entity;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\Common\Helper\CellHelper; use Box\Spout\Writer\Common\Helper\CellHelper;
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
/** /**
* Class Cell * Class Cell
@ -53,16 +55,29 @@ class Cell
protected $type; protected $type;
/** /**
* Cell constructor. * The cell style
* @param $value mixed * @var Style
*/ */
public function __construct($value) protected $style;
/**
* @var StyleMerger
*/
protected $styleMerger;
/**
* @param $value mixed
* @param Style|null $style
*/
public function __construct($value, Style $style = null)
{ {
$this->setValue($value); $this->setValue($value);
$this->setStyle($style);
$this->styleMerger = new StyleMerger();
} }
/** /**
* @param $value mixed|null * @param mixed|null $value
*/ */
public function setValue($value) public function setValue($value)
{ {
@ -78,6 +93,22 @@ class Cell
return $this->value; return $this->value;
} }
/**
* @param Style|null $style
*/
public function setStyle($style)
{
$this->style = $style ?: new Style();
}
/**
* @return Style
*/
public function getStyle()
{
return $this->style;
}
/** /**
* @return int|null * @return int|null
*/ */
@ -88,6 +119,7 @@ class Cell
/** /**
* Get the current value type * Get the current value type
*
* @param mixed|null $value * @param mixed|null $value
* @return int * @return int
*/ */
@ -127,6 +159,7 @@ class Cell
/** /**
* Not used at the moment * Not used at the moment
*
* @return bool * @return bool
*/ */
public function isFormula() public function isFormula()
@ -165,4 +198,20 @@ class Cell
{ {
return (string) $this->value; return (string) $this->value;
} }
/**
* @param Style|null $style
* @return Cell
*/
public function applyStyle($style)
{
if ($style === null) {
return $this;
}
$mergedStyle = $this->styleMerger->merge($this->style, $style);
$this->setStyle($mergedStyle);
return $this;
}
} }

View File

@ -0,0 +1,126 @@
<?php
namespace Box\Spout\Writer\Common\Entity;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\Common\Manager\RowManager;
class Row
{
/**
* The cells in this row
* @var Cell[]
*/
protected $cells = [];
/**
* The row style
* @var Style
*/
protected $style;
/**
* Thw row manager
* @var RowManager
*/
protected $rowManager;
/**
* Row constructor.
* @param Cell[] $cells
* @param Style|null $style
* @param RowManager $rowManager
*/
public function __construct(array $cells, $style, RowManager $rowManager)
{
$this
->setCells($cells)
->setStyle($style);
$this->rowManager = $rowManager;
}
/**
* @return Cell[] $cells
*/
public function getCells()
{
return $this->cells;
}
/**
* @param Cell[] $cells
* @return $this
*/
public function setCells(array $cells)
{
$this->cells = [];
foreach ($cells as $cell) {
$this->addCell($cell);
}
return $this;
}
/**
* @return Style
*/
public function getStyle()
{
return $this->style;
}
/**
* @param Style|null $style
* @return Row
*/
public function setStyle($style)
{
$this->style = $style ?: new Style();
return $this;
}
/**
* @param Style $style
* @return Row
*/
public function applyStyle($style)
{
$this->rowManager->applyStyle($this, $style);
return $this;
}
/**
* @param Cell $cell
* @return Row
*/
public function addCell(Cell $cell)
{
$this->cells[] = $cell;
return $this;
}
/**
* Returns whether a row has cells
*
* @return bool
*/
public function hasCells()
{
return $this->rowManager->hasCells($this);
}
/**
* Detect whether this row is considered empty.
* An empty row has either no cells at all - or only empty cells
*
* @return bool
*/
public function isEmpty()
{
return $this->rowManager->isEmpty($this);
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace Box\Spout\Writer\Common\Manager;
use Box\Spout\Writer\Common\Entity\Cell;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
class CellManager
{
/**
* @var StyleMerger
*/
protected $styleMerger;
/**
* @param StyleMerger $styleMerger
*/
public function __construct(StyleMerger $styleMerger)
{
$this->styleMerger = $styleMerger;
}
/**
* Merges a Style into a cell's Style.
*
* @param Cell $cell
* @param Style $style
* @return $this
*/
public function applyStyle(Cell $cell, Style $style)
{
$mergedStyle = $this->styleMerger->merge($cell->getStyle(), $style);
$cell->setStyle($mergedStyle);
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace Box\Spout\Writer\Common\Manager;
use Box\Spout\Writer\Common\Entity\Row;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
class RowManager
{
/**
* @var StyleMerger
*/
protected $styleMerger;
/**
* @param StyleMerger $styleMerger
*/
public function __construct(StyleMerger $styleMerger)
{
$this->styleMerger = $styleMerger;
}
/**
* @param Row $row
* @param Style $style
* @return $this
*/
public function applyStyle(Row $row, Style $style)
{
$mergedStyle = $this->styleMerger->merge($row->getStyle(), $style);
$row->setStyle($mergedStyle);
}
/**
* Returns whether a row has cells
*
* @param Row $row
* @return bool
*/
public function hasCells(Row $row)
{
return count($row->getCells()) !== 0;
}
/**
* Detect whether a row is considered empty.
* An empty row has either no cells at all - or only one empty cell
*
* @param Row $row
* @return bool
*/
public function isEmpty(Row $row)
{
$cells = $row->getCells();
return count($cells) === 0 || (count($cells) === 1 && $cells[0]->isEmpty());
}
}

View File

@ -2,6 +2,7 @@
namespace Box\Spout\Writer\Common\Manager\Style; namespace Box\Spout\Writer\Common\Manager\Style;
use Box\Spout\Writer\Common\Entity\Cell;
use Box\Spout\Writer\Common\Entity\Style\Style; use Box\Spout\Writer\Common\Entity\Style\Style;
/** /**
@ -48,13 +49,12 @@ class StyleManager implements StyleManagerInterface
* Apply additional styles if the given row needs it. * Apply additional styles if the given row needs it.
* Typically, set "wrap text" if a cell contains a new line. * Typically, set "wrap text" if a cell contains a new line.
* *
* @param Style $style The original style * @param Cell $cell
* @param array $dataRow The row the style will be applied to * @return Style
* @return Style The updated style
*/ */
public function applyExtraStylesIfNeeded($style, $dataRow) public function applyExtraStylesIfNeeded(Cell $cell)
{ {
$updatedStyle = $this->applyWrapTextIfCellContainsNewLine($style, $dataRow); $updatedStyle = $this->applyWrapTextIfCellContainsNewLine($cell);
return $updatedStyle; return $updatedStyle;
} }
@ -68,24 +68,22 @@ class StyleManager implements StyleManagerInterface
* A workaround would be to encode "\n" as "_x000D_" but it does not work * A workaround would be to encode "\n" as "_x000D_" but it does not work
* on the Windows version of Excel... * on the Windows version of Excel...
* *
* @param Style $style The original style * @param Cell $cell The cell the style should be applied to
* @param array $dataRow The row the style will be applied to * @return \Box\Spout\Writer\Common\Entity\Style\Style The eventually updated style
* @return Style The eventually updated style
*/ */
protected function applyWrapTextIfCellContainsNewLine($style, $dataRow) protected function applyWrapTextIfCellContainsNewLine(Cell $cell)
{ {
$cellStyle = $cell->getStyle();
// if the "wrap text" option is already set, no-op // if the "wrap text" option is already set, no-op
if ($style->hasSetWrapText()) { if ($cellStyle->hasSetWrapText()) {
return $style; return $cellStyle;
} }
foreach ($dataRow as $cell) { if ($cell->isString() && strpos($cell->getValue(), "\n") !== false) {
if (is_string($cell) && strpos($cell, "\n") !== false) { $cellStyle->setShouldWrapText();
$style->setShouldWrapText();
break;
}
} }
return $style; return $cellStyle;
} }
} }

View File

@ -2,6 +2,7 @@
namespace Box\Spout\Writer\Common\Manager\Style; namespace Box\Spout\Writer\Common\Manager\Style;
use Box\Spout\Writer\Common\Entity\Cell;
use Box\Spout\Writer\Common\Entity\Style\Style; use Box\Spout\Writer\Common\Entity\Style\Style;
/** /**
@ -22,9 +23,8 @@ interface StyleManagerInterface
* Apply additional styles if the given row needs it. * Apply additional styles if the given row needs it.
* Typically, set "wrap text" if a cell contains a new line. * Typically, set "wrap text" if a cell contains a new line.
* *
* @param Style $style The original style * @param Cell $cell
* @param array $dataRow The row the style will be applied to * @return \Box\Spout\Writer\Common\Entity\Style\Style The updated style
* @return Style The updated style
*/ */
public function applyExtraStylesIfNeeded($style, $dataRow); public function applyExtraStylesIfNeeded(Cell $cell);
} }

View File

@ -7,8 +7,8 @@ use Box\Spout\Common\Manager\OptionsManagerInterface;
use Box\Spout\Writer\Common\Creator\EntityFactory; use Box\Spout\Writer\Common\Creator\EntityFactory;
use Box\Spout\Writer\Common\Creator\ManagerFactoryInterface; use Box\Spout\Writer\Common\Creator\ManagerFactoryInterface;
use Box\Spout\Writer\Common\Entity\Options; use Box\Spout\Writer\Common\Entity\Options;
use Box\Spout\Writer\Common\Entity\Row;
use Box\Spout\Writer\Common\Entity\Sheet; use Box\Spout\Writer\Common\Entity\Sheet;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\Common\Entity\Workbook; use Box\Spout\Writer\Common\Entity\Workbook;
use Box\Spout\Writer\Common\Entity\Worksheet; use Box\Spout\Writer\Common\Entity\Worksheet;
use Box\Spout\Writer\Common\Helper\FileSystemWithRootFolderHelperInterface; use Box\Spout\Writer\Common\Helper\FileSystemWithRootFolderHelperInterface;
@ -198,21 +198,20 @@ abstract class WorkbookManagerAbstract implements WorkbookManagerInterface
} }
/** /**
* Adds data to the current sheet. * Adds a row to the current sheet.
* If shouldCreateNewSheetsAutomatically option is set to true, it will handle pagination * If shouldCreateNewSheetsAutomatically option is set to true, it will handle pagination
* with the creation of new worksheets if one worksheet has reached its maximum capicity. * with the creation of new worksheets if one worksheet has reached its maximum capicity.
* *
* @param array $dataRow Array containing data to be written. Cannot be empty. * @param Row $row The row to added
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
* @param Style $style Style to be applied to the row.
* @throws IOException If trying to create a new sheet and unable to open the sheet for writing * @throws IOException If trying to create a new sheet and unable to open the sheet for writing
* @throws WriterException If unable to write data * @throws WriterException If unable to write data
* @return void * @return void
* @return void
*/ */
public function addRowToCurrentWorksheet($dataRow, Style $style) public function addRowToCurrentWorksheet(Row $row)
{ {
$currentWorksheet = $this->getCurrentWorksheet(); $currentWorksheet = $this->getCurrentWorksheet();
$hasReachedMaxRows = $this->hasCurrentWorkseetReachedMaxRows(); $hasReachedMaxRows = $this->hasCurrentWorksheetReachedMaxRows();
// if we reached the maximum number of rows for the current sheet... // if we reached the maximum number of rows for the current sheet...
if ($hasReachedMaxRows) { if ($hasReachedMaxRows) {
@ -220,19 +219,19 @@ abstract class WorkbookManagerAbstract implements WorkbookManagerInterface
if ($this->optionManager->getOption(Options::SHOULD_CREATE_NEW_SHEETS_AUTOMATICALLY)) { if ($this->optionManager->getOption(Options::SHOULD_CREATE_NEW_SHEETS_AUTOMATICALLY)) {
$currentWorksheet = $this->addNewSheetAndMakeItCurrent(); $currentWorksheet = $this->addNewSheetAndMakeItCurrent();
$this->addRowWithStyleToWorksheet($currentWorksheet, $dataRow, $style); $this->addRowToWorksheet($currentWorksheet, $row);
} else { } else {
// otherwise, do nothing as the data won't be written anyways // otherwise, do nothing as the data won't be written anyways
} }
} else { } else {
$this->addRowWithStyleToWorksheet($currentWorksheet, $dataRow, $style); $this->addRowToWorksheet($currentWorksheet, $row);
} }
} }
/** /**
* @return bool Whether the current worksheet has reached the maximum number of rows per sheet. * @return bool Whether the current worksheet has reached the maximum number of rows per sheet.
*/ */
private function hasCurrentWorkseetReachedMaxRows() private function hasCurrentWorksheetReachedMaxRows()
{ {
$currentWorksheet = $this->getCurrentWorksheet(); $currentWorksheet = $this->getCurrentWorksheet();
@ -243,21 +242,18 @@ abstract class WorkbookManagerAbstract implements WorkbookManagerInterface
* Adds data with the given style to the given sheet. * Adds data with the given style to the given sheet.
* *
* @param Worksheet $worksheet Worksheet to write the row to * @param Worksheet $worksheet Worksheet to write the row to
* @param array $dataRow Array containing data to be written. Cannot be empty. * @param Row $row The row to be added
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
* @param Style $style Style to be applied to the row.
* @throws WriterException If unable to write data * @throws WriterException If unable to write data
* @return void * @return void
* @return void
*/ */
private function addRowWithStyleToWorksheet(Worksheet $worksheet, $dataRow, Style $style) private function addRowToWorksheet(Worksheet $worksheet, Row $row)
{ {
$updatedStyle = $this->styleManager->applyExtraStylesIfNeeded($style, $dataRow); $this->worksheetManager->addRow($worksheet, $row);
$registeredStyle = $this->styleManager->registerStyle($updatedStyle);
$this->worksheetManager->addRow($worksheet, $dataRow, $registeredStyle);
// update max num columns for the worksheet // update max num columns for the worksheet
$currentMaxNumColumns = $worksheet->getMaxNumColumns(); $currentMaxNumColumns = $worksheet->getMaxNumColumns();
$cellsCount = count($dataRow); $cellsCount = count($row->getCells());
$worksheet->setMaxNumColumns(max($currentMaxNumColumns, $cellsCount)); $worksheet->setMaxNumColumns(max($currentMaxNumColumns, $cellsCount));
} }

View File

@ -3,8 +3,8 @@
namespace Box\Spout\Writer\Common\Manager; namespace Box\Spout\Writer\Common\Manager;
use Box\Spout\Common\Exception\IOException; use Box\Spout\Common\Exception\IOException;
use Box\Spout\Writer\Common\Entity\Row;
use Box\Spout\Writer\Common\Entity\Sheet; use Box\Spout\Writer\Common\Entity\Sheet;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\Common\Entity\Workbook; use Box\Spout\Writer\Common\Entity\Workbook;
use Box\Spout\Writer\Common\Entity\Worksheet; use Box\Spout\Writer\Common\Entity\Worksheet;
use Box\Spout\Writer\Exception\SheetNotFoundException; use Box\Spout\Writer\Exception\SheetNotFoundException;
@ -53,18 +53,17 @@ interface WorkbookManagerInterface
public function setCurrentSheet(Sheet $sheet); public function setCurrentSheet(Sheet $sheet);
/** /**
* Adds data to the current sheet. * Adds a row to the current sheet.
* If shouldCreateNewSheetsAutomatically option is set to true, it will handle pagination * If shouldCreateNewSheetsAutomatically option is set to true, it will handle pagination
* with the creation of new worksheets if one worksheet has reached its maximum capicity. * with the creation of new worksheets if one worksheet has reached its maximum capicity.
* *
* @param array $dataRow Array containing data to be written. Cannot be empty. * @param Row $row The row to added
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
* @param Style $style Style to be applied to the row.
* @throws IOException If trying to create a new sheet and unable to open the sheet for writing * @throws IOException If trying to create a new sheet and unable to open the sheet for writing
* @throws WriterException If unable to write data * @throws WriterException If unable to write data
* @return void * @return void
* @return void
*/ */
public function addRowToCurrentWorksheet($dataRow, Style $style); public function addRowToCurrentWorksheet(Row $row);
/** /**
* Closes the workbook and all its associated sheets. * Closes the workbook and all its associated sheets.

View File

@ -2,7 +2,7 @@
namespace Box\Spout\Writer\Common\Manager; namespace Box\Spout\Writer\Common\Manager;
use Box\Spout\Writer\Common\Entity\Style\Style; use Box\Spout\Writer\Common\Entity\Row;
use Box\Spout\Writer\Common\Entity\Worksheet; use Box\Spout\Writer\Common\Entity\Worksheet;
/** /**
@ -12,17 +12,16 @@ use Box\Spout\Writer\Common\Entity\Worksheet;
interface WorksheetManagerInterface interface WorksheetManagerInterface
{ {
/** /**
* Adds data to the worksheet. * Adds a row to the worksheet.
* *
* @param Worksheet $worksheet The worksheet to add the row to * @param Worksheet $worksheet The worksheet to add the row to
* @param array $dataRow Array containing data to be written. Cannot be empty. * @param Row $row The row to be added
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
* @param Style $rowStyle Style to be applied to the row. NULL means use default style.
* @throws \Box\Spout\Common\Exception\IOException If the data cannot be written * @throws \Box\Spout\Common\Exception\IOException If the data cannot be written
* @throws \Box\Spout\Common\Exception\InvalidArgumentException If a cell value's type is not supported * @throws \Box\Spout\Common\Exception\InvalidArgumentException If a cell value's type is not supported
* @return void * @return void
* @return void
*/ */
public function addRow(Worksheet $worksheet, $dataRow, $rowStyle); public function addRow(Worksheet $worksheet, Row $row);
/** /**
* Prepares the worksheet to accept data * Prepares the worksheet to accept data

View File

@ -46,7 +46,7 @@ class ManagerFactory implements ManagerFactoryInterface
$fileSystemHelper->createBaseFilesAndFolders(); $fileSystemHelper->createBaseFilesAndFolders();
$styleManager = $this->createStyleManager($optionsManager); $styleManager = $this->createStyleManager($optionsManager);
$worksheetManager = $this->createWorksheetManager(); $worksheetManager = $this->createWorksheetManager($styleManager);
return new WorkbookManager( return new WorkbookManager(
$workbook, $workbook,
@ -60,14 +60,15 @@ class ManagerFactory implements ManagerFactoryInterface
} }
/** /**
* @param StyleManager $styleManager
* @return WorksheetManager * @return WorksheetManager
*/ */
private function createWorksheetManager() private function createWorksheetManager(StyleManager $styleManager)
{ {
$stringsEscaper = $this->helperFactory->createStringsEscaper(); $stringsEscaper = $this->helperFactory->createStringsEscaper();
$stringsHelper = $this->helperFactory->createStringHelper(); $stringsHelper = $this->helperFactory->createStringHelper();
return new WorksheetManager($stringsEscaper, $stringsHelper, $this->entityFactory); return new WorksheetManager($styleManager, $stringsEscaper, $stringsHelper);
} }
/** /**

View File

@ -4,12 +4,13 @@ namespace Box\Spout\Writer\ODS\Manager;
use Box\Spout\Common\Exception\InvalidArgumentException; use Box\Spout\Common\Exception\InvalidArgumentException;
use Box\Spout\Common\Exception\IOException; use Box\Spout\Common\Exception\IOException;
use Box\Spout\Common\Helper\Escaper\ODS as ODSEscaper;
use Box\Spout\Common\Helper\StringHelper; use Box\Spout\Common\Helper\StringHelper;
use Box\Spout\Writer\Common\Creator\EntityFactory;
use Box\Spout\Writer\Common\Entity\Cell; use Box\Spout\Writer\Common\Entity\Cell;
use Box\Spout\Writer\Common\Entity\Style\Style; use Box\Spout\Writer\Common\Entity\Row;
use Box\Spout\Writer\Common\Entity\Worksheet; use Box\Spout\Writer\Common\Entity\Worksheet;
use Box\Spout\Writer\Common\Manager\WorksheetManagerInterface; use Box\Spout\Writer\Common\Manager\WorksheetManagerInterface;
use Box\Spout\Writer\ODS\Manager\Style\StyleManager;
/** /**
* Class WorksheetManager * Class WorksheetManager
@ -23,24 +24,23 @@ class WorksheetManager implements WorksheetManagerInterface
/** @var StringHelper String helper */ /** @var StringHelper String helper */
private $stringHelper; private $stringHelper;
/** @var EntityFactory Factory to create entities */ /** @var StyleManager Manages styles */
private $entityFactory; private $styleManager;
/** /**
* WorksheetManager constructor. * WorksheetManager constructor.
* * @param StyleManager $styleManager
* @param \Box\Spout\Common\Helper\Escaper\ODS $stringsEscaper * @param ODSEscaper $stringsEscaper
* @param StringHelper $stringHelper * @param StringHelper $stringHelper
* @param EntityFactory $entityFactory
*/ */
public function __construct( public function __construct(
\Box\Spout\Common\Helper\Escaper\ODS $stringsEscaper, StyleManager $styleManager,
StringHelper $stringHelper, ODSEscaper $stringsEscaper,
EntityFactory $entityFactory StringHelper $stringHelper
) { ) {
$this->stringsEscaper = $stringsEscaper; $this->stringsEscaper = $stringsEscaper;
$this->stringHelper = $stringHelper; $this->stringHelper = $stringHelper;
$this->entityFactory = $entityFactory; $this->styleManager = $styleManager;
} }
/** /**
@ -91,24 +91,20 @@ class WorksheetManager implements WorksheetManagerInterface
} }
/** /**
* Adds data to the given worksheet. * Adds a row to the worksheet.
* *
* @param Worksheet $worksheet The worksheet to add the row to * @param Worksheet $worksheet The worksheet to add the row to
* @param array $dataRow Array containing data to be written. Cannot be empty. * @param Row $row The row to be added
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
* @param Style $rowStyle Style to be applied to the row. NULL means use default style.
* @throws IOException If the data cannot be written * @throws IOException If the data cannot be written
* @throws InvalidArgumentException If a cell value's type is not supported * @throws InvalidArgumentException If a cell value's type is not supported
* @return void * @return void
*
* @return void
*/ */
public function addRow(Worksheet $worksheet, $dataRow, $rowStyle) public function addRow(Worksheet $worksheet, Row $row)
{ {
// $dataRow can be an associative array. We need to transform $cells = $row->getCells();
// it into a regular array, as we'll use the numeric indexes. $cellsCount = count($cells);
$dataRowWithNumericIndexes = array_values($dataRow);
$styleIndex = ($rowStyle->getId() + 1); // 1-based
$cellsCount = count($dataRow);
$data = '<table:table-row table:style-name="ro1">'; $data = '<table:table-row table:style-name="ro1">';
@ -116,14 +112,21 @@ class WorksheetManager implements WorksheetManagerInterface
$nextCellIndex = 1; $nextCellIndex = 1;
for ($i = 0; $i < $cellsCount; $i++) { for ($i = 0; $i < $cellsCount; $i++) {
$currentCellValue = $dataRowWithNumericIndexes[$currentCellIndex]; /** @var Cell $cell */
$cell = $cells[$currentCellIndex];
/** @var Cell|null $nextCell */
$nextCell = isset($cells[$nextCellIndex]) ? $cells[$nextCellIndex] : null;
// @TODO refactoring: move this to its own method
if ($nextCell === null || $cell->getValue() !== $nextCell->getValue()) {
// Apply styles - the row style is merged at this point
$cell->applyStyle($row->getStyle());
$this->styleManager->applyExtraStylesIfNeeded($cell);
$registeredStyle = $this->styleManager->registerStyle($cell->getStyle());
$styleIndex = $registeredStyle->getId() + 1; // 1-based
// Using isset here because it is way faster than array_key_exists...
if (!isset($dataRowWithNumericIndexes[$nextCellIndex]) ||
$currentCellValue !== $dataRowWithNumericIndexes[$nextCellIndex]) {
$numTimesValueRepeated = ($nextCellIndex - $currentCellIndex); $numTimesValueRepeated = ($nextCellIndex - $currentCellIndex);
$data .= $this->getCellXML($currentCellValue, $styleIndex, $numTimesValueRepeated); $data .= $this->getCellXML($cell, $styleIndex, $numTimesValueRepeated);
$currentCellIndex = $nextCellIndex; $currentCellIndex = $nextCellIndex;
} }
@ -145,13 +148,13 @@ class WorksheetManager implements WorksheetManagerInterface
/** /**
* Returns the cell XML content, given its value. * Returns the cell XML content, given its value.
* *
* @param mixed $cellValue The value to be written * @param Cell $cell The cell to be written
* @param int $styleIndex Index of the used style * @param int $styleIndex Index of the used style
* @param int $numTimesValueRepeated Number of times the value is consecutively repeated * @param int $numTimesValueRepeated Number of times the value is consecutively repeated
* @throws \Box\Spout\Common\Exception\InvalidArgumentException If a cell value's type is not supported * @throws \Box\Spout\Common\Exception\InvalidArgumentException If a cell value's type is not supported
* @return string The cell XML content * @return string The cell XML content
*/ */
private function getCellXML($cellValue, $styleIndex, $numTimesValueRepeated) protected function getCellXML(Cell $cell, $styleIndex, $numTimesValueRepeated)
{ {
$data = '<table:table-cell table:style-name="ce' . $styleIndex . '"'; $data = '<table:table-cell table:style-name="ce' . $styleIndex . '"';
@ -159,13 +162,6 @@ class WorksheetManager implements WorksheetManagerInterface
$data .= ' table:number-columns-repeated="' . $numTimesValueRepeated . '"'; $data .= ' table:number-columns-repeated="' . $numTimesValueRepeated . '"';
} }
/* @TODO Remove code duplication with XLSX writer: https://github.com/box/spout/pull/383#discussion_r113292746 */
if ($cellValue instanceof Cell) {
$cell = $cellValue;
} else {
$cell = $this->entityFactory->createCell($cellValue);
}
if ($cell->isString()) { if ($cell->isString()) {
$data .= ' office:value-type="string" calcext:value-type="string">'; $data .= ' office:value-type="string" calcext:value-type="string">';

View File

@ -9,6 +9,7 @@ use Box\Spout\Common\Exception\SpoutException;
use Box\Spout\Common\Helper\GlobalFunctionsHelper; use Box\Spout\Common\Helper\GlobalFunctionsHelper;
use Box\Spout\Common\Manager\OptionsManagerInterface; use Box\Spout\Common\Manager\OptionsManagerInterface;
use Box\Spout\Writer\Common\Entity\Options; use Box\Spout\Writer\Common\Entity\Options;
use Box\Spout\Writer\Common\Entity\Row;
use Box\Spout\Writer\Common\Entity\Style\Style; use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\Common\Manager\Style\StyleMerger; use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
use Box\Spout\Writer\Exception\WriterAlreadyOpenedException; use Box\Spout\Writer\Exception\WriterAlreadyOpenedException;
@ -42,9 +43,6 @@ abstract class WriterAbstract implements WriterInterface
/** @var StyleMerger Helps merge styles together */ /** @var StyleMerger Helps merge styles together */
protected $styleMerger; protected $styleMerger;
/** @var Style Style to be applied to the next written row(s) */
protected $rowStyle;
/** @var string Content-Type value for the header - to be defined by child class */ /** @var string Content-Type value for the header - to be defined by child class */
protected static $headerContentType; protected static $headerContentType;
@ -64,8 +62,6 @@ abstract class WriterAbstract implements WriterInterface
$this->styleMerger = $styleMerger; $this->styleMerger = $styleMerger;
$this->globalFunctionsHelper = $globalFunctionsHelper; $this->globalFunctionsHelper = $globalFunctionsHelper;
$this->helperFactory = $helperFactory; $this->helperFactory = $helperFactory;
$this->resetRowStyleToDefault();
} }
/** /**
@ -77,14 +73,12 @@ abstract class WriterAbstract implements WriterInterface
abstract protected function openWriter(); abstract protected function openWriter();
/** /**
* Adds data to the currently openned writer. * Adds a row to the currently opened writer.
* *
* @param array $dataRow Array containing data to be streamed. * @param Row $row The row containing cells and styles
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
* @param Style $style Style to be applied to the written row
* @return void * @return void
*/ */
abstract protected function addRowToWriter(array $dataRow, $style); abstract protected function addRowToWriter(Row $row);
/** /**
* Closes the streamer, preventing any additional writing. * Closes the streamer, preventing any additional writing.
@ -94,9 +88,7 @@ abstract class WriterAbstract implements WriterInterface
abstract protected function closeWriter(); abstract protected function closeWriter();
/** /**
* Sets the default styles for all rows added with "addRow". * Sets the default styles for all rows added with "addRow"
* Overriding the default style instead of using "addRowWithStyle" improves performance by 20%.
* @see https://github.com/box/spout/issues/272
* *
* @param Style $defaultStyle * @param Style $defaultStyle
* @return WriterAbstract * @return WriterAbstract
@ -104,19 +96,12 @@ abstract class WriterAbstract implements WriterInterface
public function setDefaultRowStyle($defaultStyle) public function setDefaultRowStyle($defaultStyle)
{ {
$this->optionsManager->setOption(Options::DEFAULT_ROW_STYLE, $defaultStyle); $this->optionsManager->setOption(Options::DEFAULT_ROW_STYLE, $defaultStyle);
$this->resetRowStyleToDefault();
return $this; return $this;
} }
/** /**
* Inits the writer and opens it to accept data. * {@inheritdoc}
* By using this method, the data will be written to a file.
*
* @api
* @param string $outputFilePath Path of the output file that will contain the data
* @throws \Box\Spout\Common\Exception\IOException If the writer cannot be opened or if the given path is not writable
* @return WriterAbstract
*/ */
public function openToFile($outputFilePath) public function openToFile($outputFilePath)
{ {
@ -132,15 +117,9 @@ abstract class WriterAbstract implements WriterInterface
} }
/** /**
* Inits the writer and opens it to accept data.
* By using this method, the data will be outputted directly to the browser.
*
* @codeCoverageIgnore * @codeCoverageIgnore
* *
* @api * {@inheritdoc}
* @param string $outputFileName Name of the output file that will contain the data. If a path is passed in, only the file name will be kept
* @throws \Box\Spout\Common\Exception\IOException If the writer cannot be opened
* @return WriterAbstract
*/ */
public function openToBrowser($outputFileName) public function openToBrowser($outputFileName)
{ {
@ -203,24 +182,15 @@ abstract class WriterAbstract implements WriterInterface
} }
/** /**
* Write given data to the output. New data will be appended to end of stream. * {@inheritdoc}
*
* @param array $dataRow Array containing data to be streamed.
* If empty, no data is added (i.e. not even as a blank row)
* Example: $dataRow = ['data1', 1234, null, '', 'data5', false];
* @api
* @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If this function is called before opening the writer
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
* @throws \Box\Spout\Common\Exception\SpoutException If anything else goes wrong while writing data
* @return WriterAbstract
*/ */
public function addRow(array $dataRow) public function addRow(Row $row)
{ {
if ($this->isWriterOpened) { if ($this->isWriterOpened) {
// empty $dataRow should not add an empty line if ($row->hasCells()) {
if (!empty($dataRow)) {
try { try {
$this->addRowToWriter($dataRow, $this->rowStyle); $this->applyDefaultRowStyle($row);
$this->addRowToWriter($row);
} catch (SpoutException $e) { } catch (SpoutException $e) {
// if an exception occurs while writing data, // if an exception occurs while writing data,
// close the writer and remove all files created so far. // close the writer and remove all files created so far.
@ -238,115 +208,43 @@ abstract class WriterAbstract implements WriterInterface
} }
/** /**
* Write given data to the output and apply the given style. * {@inheritdoc}
* @see addRow
*
* @api
* @param array $dataRow Array of array containing data to be streamed.
* @param Style $style Style to be applied to the row.
* @throws \Box\Spout\Common\Exception\InvalidArgumentException If the input param is not valid
* @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If this function is called before opening the writer
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
* @return WriterAbstract
*/
public function addRowWithStyle(array $dataRow, $style)
{
if (!$style instanceof Style) {
throw new InvalidArgumentException('The "$style" argument must be a Style instance and cannot be NULL.');
}
$this->setRowStyle($style);
$this->addRow($dataRow);
$this->resetRowStyleToDefault();
return $this;
}
/**
* Write given data to the output. New data will be appended to end of stream.
*
* @api
* @param array $dataRows Array of array containing data to be streamed.
* If a row is empty, it won't be added (i.e. not even as a blank row)
* Example: $dataRows = [
* ['data11', 12, , '', 'data13'],
* ['data21', 'data22', null, false],
* ];
* @throws \Box\Spout\Common\Exception\InvalidArgumentException If the input param is not valid
* @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If this function is called before opening the writer
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
* @return WriterAbstract
*/ */
public function addRows(array $dataRows) public function addRows(array $dataRows)
{ {
if (!empty($dataRows)) { foreach ($dataRows as $dataRow) {
$firstRow = reset($dataRows); if (!$dataRow instanceof Row) {
if (!is_array($firstRow)) { $this->closeAndAttemptToCleanupAllFiles();
throw new InvalidArgumentException('The input should be an array of arrays'); throw new InvalidArgumentException();
} }
foreach ($dataRows as $dataRow) {
$this->addRow($dataRow); $this->addRow($dataRow);
} }
}
return $this; return $this;
} }
/** /**
* Write given data to the output and apply the given style. * @TODO: Move this into styleMerger
* @see addRows
* *
* @api * @param Row $row
* @param array $dataRows Array of array containing data to be streamed. * @return $this
* @param Style $style Style to be applied to the rows.
* @throws \Box\Spout\Common\Exception\InvalidArgumentException If the input param is not valid
* @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If this function is called before opening the writer
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
* @return WriterAbstract
*/ */
public function addRowsWithStyle(array $dataRows, $style) private function applyDefaultRowStyle(Row $row)
{ {
if (!$style instanceof Style) {
throw new InvalidArgumentException('The "$style" argument must be a Style instance and cannot be NULL.');
}
$this->setRowStyle($style);
$this->addRows($dataRows);
$this->resetRowStyleToDefault();
return $this;
}
/**
* Sets the style to be applied to the next written rows
* until it is changed or reset.
*
* @param Style $style
* @return void
*/
private function setRowStyle($style)
{
// Merge given style with the default one to inherit custom properties
$defaultRowStyle = $this->optionsManager->getOption(Options::DEFAULT_ROW_STYLE); $defaultRowStyle = $this->optionsManager->getOption(Options::DEFAULT_ROW_STYLE);
$this->rowStyle = $this->styleMerger->merge($style, $defaultRowStyle); if ($defaultRowStyle === null) {
return $this;
} }
/** $mergedStyle = $this->styleMerger->merge($row->getStyle(), $defaultRowStyle);
* Resets the style to be applied to the next written rows. $row->setStyle($mergedStyle);
*
* @return void
*/
private function resetRowStyleToDefault()
{
$this->rowStyle = $this->optionsManager->getOption(Options::DEFAULT_ROW_STYLE);
} }
/** /**
* Closes the writer. This will close the streamer as well, preventing new data * Closes the writer. This will close the streamer as well, preventing new data
* to be written to the file. * to be written to the file.
* *
* @api
* @return void * @return void
*/ */
public function close() public function close()

View File

@ -2,7 +2,7 @@
namespace Box\Spout\Writer; namespace Box\Spout\Writer;
use Box\Spout\Writer\Common\Entity\Style\Style; use Box\Spout\Writer\Common\Entity\Row;
/** /**
* Interface WriterInterface * Interface WriterInterface
@ -10,7 +10,7 @@ use Box\Spout\Writer\Common\Entity\Style\Style;
interface WriterInterface interface WriterInterface
{ {
/** /**
* Inits the writer and opens it to accept data. * Initializes the writer and opens it to accept data.
* By using this method, the data will be written to a file. * By using this method, the data will be written to a file.
* *
* @param string $outputFilePath Path of the output file that will contain the data * @param string $outputFilePath Path of the output file that will contain the data
@ -20,7 +20,7 @@ interface WriterInterface
public function openToFile($outputFilePath); public function openToFile($outputFilePath);
/** /**
* Inits the writer and opens it to accept data. * Initializes the writer and opens it to accept data.
* By using this method, the data will be outputted directly to the browser. * By using this method, the data will be outputted directly to the browser.
* *
* @param string $outputFileName Name of the output file that will contain the data. If a path is passed in, only the file name will be kept * @param string $outputFileName Name of the output file that will contain the data. If a path is passed in, only the file name will be kept
@ -30,56 +30,24 @@ interface WriterInterface
public function openToBrowser($outputFileName); public function openToBrowser($outputFileName);
/** /**
* Write given data to the output. New data will be appended to end of stream. * Append a row to the end of the stream.
* *
* @param array $dataRow Array containing data to be streamed. * @param Row $row The row to be appended to the stream
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
* @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If the writer has not been opened yetthe writer
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
* @return WriterInterface * @return WriterInterface
*/ */
public function addRow(array $dataRow); public function addRow(Row $row);
/** /**
* Write given data to the output and apply the given style. * Write a given array of rows to the output. New data will be appended to the end of the stream.
* @see addRow
* *
* @param array $dataRow Array of array containing data to be streamed. * @param Row[] $rows Array of rows be appended to the stream
* @param Style $style Style to be applied to the row.
* @throws \Box\Spout\Common\Exception\InvalidArgumentException If the input param is not valid
* @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If this function is called before opening the writer
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
* @return WriterInterface
*/
public function addRowWithStyle(array $dataRow, $style);
/**
* Write given data to the output. New data will be appended to end of stream.
*
* @param array $dataRows Array of array containing data to be streamed.
* Example $dataRow = [
* ['data11', 12, , '', 'data13'],
* ['data21', 'data22', null],
* ];
* @throws \Box\Spout\Common\Exception\InvalidArgumentException If the input param is not valid * @throws \Box\Spout\Common\Exception\InvalidArgumentException If the input param is not valid
* @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If the writer has not been opened yet * @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If the writer has not been opened yet
* @throws \Box\Spout\Common\Exception\IOException If unable to write data * @throws \Box\Spout\Common\Exception\IOException If unable to write data
* @return WriterInterface * @return WriterInterface
*/
public function addRows(array $dataRows);
/**
* Write given data to the output and apply the given style.
* @see addRows
*
* @param array $dataRows Array of array containing data to be streamed.
* @param Style $style Style to be applied to the rows.
* @throws \Box\Spout\Common\Exception\InvalidArgumentException If the input param is not valid
* @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If this function is called before opening the writer
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
* @return WriterInterface * @return WriterInterface
*/ */
public function addRowsWithStyle(array $dataRows, $style); public function addRows(array $rows);
/** /**
* Closes the writer. This will close the streamer as well, preventing new data * Closes the writer. This will close the streamer as well, preventing new data

View File

@ -7,6 +7,7 @@ use Box\Spout\Common\Helper\GlobalFunctionsHelper;
use Box\Spout\Common\Manager\OptionsManagerInterface; use Box\Spout\Common\Manager\OptionsManagerInterface;
use Box\Spout\Writer\Common\Creator\ManagerFactoryInterface; use Box\Spout\Writer\Common\Creator\ManagerFactoryInterface;
use Box\Spout\Writer\Common\Entity\Options; use Box\Spout\Writer\Common\Entity\Options;
use Box\Spout\Writer\Common\Entity\Row;
use Box\Spout\Writer\Common\Entity\Sheet; use Box\Spout\Writer\Common\Entity\Sheet;
use Box\Spout\Writer\Common\Entity\Worksheet; use Box\Spout\Writer\Common\Entity\Worksheet;
use Box\Spout\Writer\Common\Manager\Style\StyleMerger; use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
@ -163,17 +164,16 @@ abstract class WriterMultiSheetsAbstract extends WriterAbstract
* If shouldCreateNewSheetsAutomatically option is set to true, it will handle pagination * If shouldCreateNewSheetsAutomatically option is set to true, it will handle pagination
* with the creation of new worksheets if one worksheet has reached its maximum capicity. * with the creation of new worksheets if one worksheet has reached its maximum capicity.
* *
* @param array $dataRow Array containing data to be written. * @param Row $row
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
* @param \Box\Spout\Writer\Common\Entity\Style\Style $style Style to be applied to the row.
* @throws WriterNotOpenedException If the book is not created yet * @throws WriterNotOpenedException If the book is not created yet
* @throws \Box\Spout\Common\Exception\IOException If unable to write data * @throws \Box\Spout\Common\Exception\IOException If unable to write data
* @return void * @return void
* @return void
*/ */
protected function addRowToWriter(array $dataRow, $style) protected function addRowToWriter(Row $row)
{ {
$this->throwIfWorkbookIsNotAvailable(); $this->throwIfWorkbookIsNotAvailable();
$this->workbookManager->addRowToCurrentWorksheet($dataRow, $style); $this->workbookManager->addRowToCurrentWorksheet($row);
} }
/** /**

View File

@ -9,6 +9,7 @@ use Box\Spout\Common\Manager\OptionsManagerInterface;
use Box\Spout\Writer\Common\Creator\EntityFactory; use Box\Spout\Writer\Common\Creator\EntityFactory;
use Box\Spout\Writer\Common\Entity\Cell; use Box\Spout\Writer\Common\Entity\Cell;
use Box\Spout\Writer\Common\Entity\Options; use Box\Spout\Writer\Common\Entity\Options;
use Box\Spout\Writer\Common\Entity\Row;
use Box\Spout\Writer\Common\Entity\Style\Style; use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\Common\Entity\Worksheet; use Box\Spout\Writer\Common\Entity\Worksheet;
use Box\Spout\Writer\Common\Helper\CellHelper; use Box\Spout\Writer\Common\Helper\CellHelper;
@ -119,60 +120,47 @@ EOD;
} }
/** /**
* Adds data to the given worksheet. * Adds a row to the worksheet.
* *
* @param Worksheet $worksheet The worksheet to add the row to * @param Worksheet $worksheet The worksheet to add the row to
* @param array $dataRow Array containing data to be written. Cannot be empty. * @param Row $row The row to be added
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
* @param Style $rowStyle Style to be applied to the row. NULL means use default style.
* @throws IOException If the data cannot be written * @throws IOException If the data cannot be written
* @throws InvalidArgumentException If a cell value's type is not supported * @throws InvalidArgumentException If a cell value's type is not supported
* @return void * @return void
*/ */
public function addRow(Worksheet $worksheet, $dataRow, $rowStyle) public function addRow(Worksheet $worksheet, Row $row)
{ {
if (!$this->isEmptyRow($dataRow)) { if (!$row->isEmpty()) {
$this->addNonEmptyRow($worksheet, $dataRow, $rowStyle); $this->addNonEmptyRow($worksheet, $row);
} }
$worksheet->setLastWrittenRowIndex($worksheet->getLastWrittenRowIndex() + 1); $worksheet->setLastWrittenRowIndex($worksheet->getLastWrittenRowIndex() + 1);
} }
/**
* Returns whether the given row is empty
*
* @param array $dataRow Array containing data to be written. Cannot be empty.
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
* @return bool Whether the given row is empty
*/
private function isEmptyRow($dataRow)
{
$numCells = count($dataRow);
// using "reset()" instead of "$dataRow[0]" because $dataRow can be an associative array
return ($numCells === 1 && CellHelper::isEmpty(reset($dataRow)));
}
/** /**
* Adds non empty row to the worksheet. * Adds non empty row to the worksheet.
* *
* @param Worksheet $worksheet The worksheet to add the row to * @param Row $row The row to be written
* @param array $dataRow Array containing data to be written. Cannot be empty.
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
* @param \Box\Spout\Writer\Common\Entity\Style\Style $style Style to be applied to the row. NULL means use default style.
* @throws \Box\Spout\Common\Exception\IOException If the data cannot be written * @throws \Box\Spout\Common\Exception\IOException If the data cannot be written
* @throws \Box\Spout\Common\Exception\InvalidArgumentException If a cell value's type is not supported * @throws \Box\Spout\Common\Exception\InvalidArgumentException If a cell value's type is not supported
* @return void * @return void
*/ */
private function addNonEmptyRow(Worksheet $worksheet, $dataRow, $style) private function addNonEmptyRow(Worksheet $worksheet, Row $row)
{ {
$cellNumber = 0; $cellNumber = 0;
$rowIndex = $worksheet->getLastWrittenRowIndex() + 1; $rowIndex = $worksheet->getLastWrittenRowIndex() + 1;
$numCells = count($dataRow); $numCells = count($row->getCells());
$rowXML = '<row r="' . $rowIndex . '" spans="1:' . $numCells . '">'; $rowXML = '<row r="' . $rowIndex . '" spans="1:' . $numCells . '">';
foreach ($dataRow as $cellValue) { // @TODO refactoring: move this to its own method
$rowXML .= $this->getCellXML($rowIndex, $cellNumber, $cellValue, $style->getId()); /** @var Cell $cell */
foreach ($row->getCells() as $cell) {
// Apply styles - the row style is merged at this point
$cell->applyStyle($row->getStyle());
$this->styleManager->applyExtraStylesIfNeeded($cell);
$registeredStyle = $this->styleManager->registerStyle($cell->getStyle());
$rowXML .= $this->getCellXML($rowIndex, $cellNumber, $cell, $registeredStyle->getId());
$cellNumber++; $cellNumber++;
} }
@ -189,24 +177,17 @@ EOD;
* *
* @param int $rowIndex * @param int $rowIndex
* @param int $cellNumber * @param int $cellNumber
* @param mixed $cellValue * @param Cell $cell
* @param int $styleId * @param int $styleId
* @throws InvalidArgumentException If the given value cannot be processed * @throws InvalidArgumentException If the given value cannot be processed
* @return string * @return string
*/ */
private function getCellXML($rowIndex, $cellNumber, $cellValue, $styleId) private function getCellXML($rowIndex, $cellNumber, Cell $cell, $styleId)
{ {
$columnIndex = CellHelper::getCellIndexFromColumnIndex($cellNumber); $columnIndex = CellHelper::getCellIndexFromColumnIndex($cellNumber);
$cellXML = '<c r="' . $columnIndex . $rowIndex . '"'; $cellXML = '<c r="' . $columnIndex . $rowIndex . '"';
$cellXML .= ' s="' . $styleId . '"'; $cellXML .= ' s="' . $styleId . '"';
/* @TODO Remove code duplication with ODS writer: https://github.com/box/spout/pull/383#discussion_r113292746 */
if ($cellValue instanceof Cell) {
$cell = $cellValue;
} else {
$cell = $this->entityFactory->createCell($cellValue);
}
if ($cell->isString()) { if ($cell->isString()) {
$cellXML .= $this->getCellXMLFragmentForNonEmptyString($cell->getValue()); $cellXML .= $this->getCellXMLFragmentForNonEmptyString($cell->getValue());
} elseif ($cell->isBoolean()) { } elseif ($cell->isBoolean()) {

View File

@ -3,6 +3,7 @@
namespace Box\Spout\Reader\XLSX\Helper; namespace Box\Spout\Reader\XLSX\Helper;
use Box\Spout\Common\Helper\Escaper; use Box\Spout\Common\Helper\Escaper;
use Box\Spout\Reader\XLSX\Manager\StyleManager;
/** /**
* Class CellValueFormatterTest * Class CellValueFormatterTest
@ -61,7 +62,7 @@ class CellValueFormatterTest extends \PHPUnit_Framework_TestCase
*/ */
public function testExcelDate($shouldUse1904Dates, $nodeValue, $expectedDateAsString) public function testExcelDate($shouldUse1904Dates, $nodeValue, $expectedDateAsString)
{ {
$nodeListMock = $this->getMockBuilder('DOMNodeList')->disableOriginalConstructor()->getMock(); $nodeListMock = $this->createMock('DOMNodeList');
$nodeListMock $nodeListMock
->expects($this->atLeastOnce()) ->expects($this->atLeastOnce())
@ -69,7 +70,7 @@ class CellValueFormatterTest extends \PHPUnit_Framework_TestCase
->with(0) ->with(0)
->will($this->returnValue((object) ['nodeValue' => $nodeValue])); ->will($this->returnValue((object) ['nodeValue' => $nodeValue]));
$nodeMock = $this->getMockBuilder('DOMElement')->disableOriginalConstructor()->getMock(); $nodeMock = $this->createMock('DOMElement');
$nodeMock $nodeMock
->expects($this->atLeastOnce()) ->expects($this->atLeastOnce())
@ -86,7 +87,7 @@ class CellValueFormatterTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue($nodeListMock)); ->will($this->returnValue($nodeListMock));
/** @var \Box\Spout\Reader\XLSX\Manager\StyleManager|\PHPUnit_Framework_MockObject_MockObject $styleManagerMock */ /** @var \Box\Spout\Reader\XLSX\Manager\StyleManager|\PHPUnit_Framework_MockObject_MockObject $styleManagerMock */
$styleManagerMock = $this->getMockBuilder('Box\Spout\Reader\XLSX\Manager\StyleManager')->disableOriginalConstructor()->getMock(); $styleManagerMock = $this->createMock(StyleManager::class);
$styleManagerMock $styleManagerMock
->expects($this->once()) ->expects($this->once())
@ -142,7 +143,7 @@ class CellValueFormatterTest extends \PHPUnit_Framework_TestCase
public function testFormatNumericCellValueWithNumbers($value, $expectedFormattedValue, $expectedType) public function testFormatNumericCellValueWithNumbers($value, $expectedFormattedValue, $expectedType)
{ {
/** @var \Box\Spout\Reader\XLSX\Manager\StyleManager|\PHPUnit_Framework_MockObject_MockObject $styleManagerMock */ /** @var \Box\Spout\Reader\XLSX\Manager\StyleManager|\PHPUnit_Framework_MockObject_MockObject $styleManagerMock */
$styleManagerMock = $this->getMockBuilder('Box\Spout\Reader\XLSX\Manager\StyleManager')->disableOriginalConstructor()->getMock(); $styleManagerMock = $this->createMock(StyleManager::class);
$styleManagerMock $styleManagerMock
->expects($this->once()) ->expects($this->once())
->method('shouldFormatNumericValueAsDate') ->method('shouldFormatNumericValueAsDate')
@ -177,14 +178,14 @@ class CellValueFormatterTest extends \PHPUnit_Framework_TestCase
*/ */
public function testFormatInlineStringCellValue($value, $expectedFormattedValue) public function testFormatInlineStringCellValue($value, $expectedFormattedValue)
{ {
$nodeListMock = $this->getMockBuilder('DOMNodeList')->disableOriginalConstructor()->getMock(); $nodeListMock = $this->createMock('DOMNodeList');
$nodeListMock $nodeListMock
->expects($this->atLeastOnce()) ->expects($this->atLeastOnce())
->method('item') ->method('item')
->with(0) ->with(0)
->will($this->returnValue((object) ['nodeValue' => $value])); ->will($this->returnValue((object) ['nodeValue' => $value]));
$nodeMock = $this->getMockBuilder('DOMElement')->disableOriginalConstructor()->getMock(); $nodeMock = $this->createMock('DOMElement');
$nodeMock $nodeMock
->expects($this->atLeastOnce()) ->expects($this->atLeastOnce())
->method('getElementsByTagName') ->method('getElementsByTagName')

View File

@ -5,7 +5,7 @@ namespace Box\Spout\Writer\CSV;
use Box\Spout\Common\Helper\EncodingHelper; use Box\Spout\Common\Helper\EncodingHelper;
use Box\Spout\Common\Type; use Box\Spout\Common\Type;
use Box\Spout\TestUsingResource; use Box\Spout\TestUsingResource;
use Box\Spout\Writer\Common\Entity\Cell; use Box\Spout\Writer\Common\Creator\EntityFactory;
use Box\Spout\Writer\WriterFactory; use Box\Spout\Writer\WriterFactory;
/** /**
@ -26,7 +26,11 @@ class WriterTest extends \PHPUnit_Framework_TestCase
$writer = WriterFactory::create(Type::CSV); $writer = WriterFactory::create(Type::CSV);
@$writer->openToFile($filePath); @$writer->openToFile($filePath);
$writer->addRow(['csv--11', 'csv--12']); $row = EntityFactory::createRow([
EntityFactory::createCell('csv--11'),
EntityFactory::createCell('csv--12'),
]);
$writer->addRow($row);
$writer->close(); $writer->close();
} }
@ -36,7 +40,11 @@ class WriterTest extends \PHPUnit_Framework_TestCase
public function testWriteShouldThrowExceptionIfCallAddRowBeforeOpeningWriter() public function testWriteShouldThrowExceptionIfCallAddRowBeforeOpeningWriter()
{ {
$writer = WriterFactory::create(Type::CSV); $writer = WriterFactory::create(Type::CSV);
$writer->addRow(['csv--11', 'csv--12']); $row = EntityFactory::createRow([
EntityFactory::createCell('csv--11'),
EntityFactory::createCell('csv--12'),
]);
$writer->addRow($row);
$writer->close(); $writer->close();
} }
@ -46,17 +54,22 @@ class WriterTest extends \PHPUnit_Framework_TestCase
public function testWriteShouldThrowExceptionIfCallAddRowsBeforeOpeningWriter() public function testWriteShouldThrowExceptionIfCallAddRowsBeforeOpeningWriter()
{ {
$writer = WriterFactory::create(Type::CSV); $writer = WriterFactory::create(Type::CSV);
$writer->addRows([['csv--11', 'csv--12']]); $row = EntityFactory::createRow([
EntityFactory::createCell('csv--11'),
EntityFactory::createCell('csv--12'),
]);
$writer->addRows([$row]);
$writer->close(); $writer->close();
} }
/** /**
* @expectedException \Box\Spout\Common\Exception\InvalidArgumentException * @expectedException \Box\Spout\Common\Exception\InvalidArgumentException
*/ */
public function testAddRowsShouldThrowExceptionIfRowsAreNotArrayOfArrays() public function testAddRowsShouldThrowExceptionIfRowsAreNotArrayOfRows()
{ {
$writer = WriterFactory::create(Type::CSV); $writer = WriterFactory::create(Type::CSV);
$writer->addRows(['csv--11', 'csv--12']); $row = new \stdClass();
$writer->addRows([$row]);
$writer->close(); $writer->close();
} }
@ -182,7 +195,7 @@ class WriterTest extends \PHPUnit_Framework_TestCase
public function testWriteShouldAcceptCellObjects() public function testWriteShouldAcceptCellObjects()
{ {
$allRows = [ $allRows = [
[new Cell('String Value'), new Cell(1)], [EntityFactory::createCell('String Value'), EntityFactory::createCell(1)],
]; ];
$writtenContent = $this->writeToCsvFileAndReturnWrittenContent($allRows, 'csv_with_cell_objects.csv'); $writtenContent = $this->writeToCsvFileAndReturnWrittenContent($allRows, 'csv_with_cell_objects.csv');
$writtenContent = $this->trimWrittenContent($writtenContent); $writtenContent = $this->trimWrittenContent($writtenContent);
@ -209,7 +222,13 @@ class WriterTest extends \PHPUnit_Framework_TestCase
$writer->setShouldAddBOM($shouldAddBOM); $writer->setShouldAddBOM($shouldAddBOM);
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
$writer->addRows($allRows);
$writer->addRows(array_map(function ($oneRow) {
return EntityFactory::createRow(array_map(function ($value) {
return EntityFactory::createCell($value);
}, $oneRow));
}, $allRows));
$writer->close(); $writer->close();
return file_get_contents($resourcePath); return file_get_contents($resourcePath);

View File

@ -0,0 +1,68 @@
<?php
namespace Box\Spout\Writer\Common\Entity;
use Box\Spout\Writer\Common\Entity\Style\Style;
use PHPUnit\Framework\TestCase;
class CellTest extends TestCase
{
/**
* @return void
*/
public function testValidInstance()
{
$this->assertInstanceOf(Cell::class, new Cell('cell'));
$this->assertInstanceOf(Cell::class, new Cell('cell-with-style', $this->createMock(Style::class)));
}
/**
* @return void
*/
public function testCellTypeNumeric()
{
$this->assertTrue((new Cell(0))->isNumeric());
$this->assertTrue((new Cell(1))->isNumeric());
}
/**
* @return void
*/
public function testCellTypeString()
{
$this->assertTrue((new Cell('String!'))->isString());
}
/**
* @return void
*/
public function testCellTypeEmptyString()
{
$this->assertTrue((new Cell(''))->isEmpty());
}
/**
* @return void
*/
public function testCellTypeEmptyNull()
{
$this->assertTrue((new Cell(null))->isEmpty());
}
/**
* @return void
*/
public function testCellTypeBool()
{
$this->assertTrue((new Cell(true))->isBoolean());
$this->assertTrue((new Cell(false))->isBoolean());
}
/**
* @return void
*/
public function testCellTypeError()
{
$this->assertTrue((new Cell([]))->isError());
}
}

View File

@ -0,0 +1,114 @@
<?php
namespace Box\Spout\Writer\Common\Entity;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\Common\Manager\RowManager;
use PHPUnit\Framework\TestCase;
class RowTest extends TestCase
{
/**
* @return \PHPUnit_Framework_MockObject_MockObject|Style
*/
private function getStyleMock()
{
return $this->createMock(Style::class);
}
/**
* @return \PHPUnit_Framework_MockObject_MockObject|Cell
*/
private function getCellMock()
{
return $this->createMock(Cell::class);
}
/**
* @return \PHPUnit_Framework_MockObject_MockObject|RowManager
*/
private function getRowManagerMock()
{
return $this->createMock(RowManager::class);
}
/**
* @return void
*/
public function testValidInstance()
{
$this->assertInstanceOf(
Row::class,
new Row([], null, $this->getRowManagerMock())
);
}
/**
* @return void
*/
public function testSetCells()
{
$row = new Row([], null, $this->getRowManagerMock());
$row->setCells([$this->getCellMock(), $this->getCellMock()]);
$this->assertEquals(2, count($row->getCells()));
}
/**
* @return void
*/
public function testSetCellsResets()
{
$row = new Row([], null, $this->getRowManagerMock());
$row->setCells([$this->getCellMock(), $this->getCellMock()]);
$this->assertEquals(2, count($row->getCells()));
$row->setCells([$this->getCellMock()]);
$this->assertEquals(1, count($row->getCells()));
}
/**
* @return void
*/
public function testGetCells()
{
$row = new Row([], null, $this->getRowManagerMock());
$this->assertEquals(0, count($row->getCells()));
$row->setCells([$this->getCellMock(), $this->getCellMock()]);
$this->assertEquals(2, count($row->getCells()));
}
/**
* @return void
*/
public function testAddCell()
{
$row = new Row([], null, $this->getRowManagerMock());
$row->setCells([$this->getCellMock(), $this->getCellMock()]);
$this->assertEquals(2, count($row->getCells()));
$row->addCell($this->getCellMock());
$this->assertEquals(3, count($row->getCells()));
}
/**
* @return void
*/
public function testFluentInterface()
{
$row = new Row([], null, $this->getRowManagerMock());
$row
->addCell($this->getCellMock())
->setStyle($this->getStyleMock())
->setCells([]);
$this->assertTrue(is_object($row));
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Spout\Writer\Common\Manager;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Writer\Common\Entity\Cell;
use Box\Spout\Writer\Common\Manager\CellManager;
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
use PHPUnit\Framework\TestCase;
class CellManagerTest extends TestCase
{
/**
* @return void
*/
public function testApplyStyle()
{
$cellManager = new CellManager(new StyleMerger());
$cell = new Cell('test');
$this->assertFalse($cell->getStyle()->isFontBold());
$style = (new StyleBuilder())->setFontBold()->build();
$cellManager->applyStyle($cell, $style);
$this->assertTrue($cell->getStyle()->isFontBold());
}
}

View File

@ -0,0 +1,86 @@
<?php
namespace Spout\Writer\Common\Manager;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Writer\Common\Entity\Cell;
use Box\Spout\Writer\Common\Entity\Row;
use Box\Spout\Writer\Common\Manager\RowManager;
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
use PHPUnit\Framework\TestCase;
class RowManagerTest extends TestCase
{
/**
* @return void
*/
public function testApplyStyle()
{
$rowManager = new RowManager(new StyleMerger());
$row = new Row([new Cell('test')], null, $rowManager);
$this->assertFalse($row->getStyle()->isFontBold());
$style = (new StyleBuilder())->setFontBold()->build();
$rowManager->applyStyle($row, $style);
$this->assertTrue($row->getStyle()->isFontBold());
}
/**
* @return array
*/
public function dataProviderForTestHasCells()
{
return [
// cells, expected hasCells
[[], false],
[[new Cell('')], true],
[[new Cell(null)], true],
[[new Cell('test')], true],
];
}
/**
* @dataProvider dataProviderForTestHasCells
*
* @param array $cells
* @param bool $expectedHasCells
* @return void
*/
public function testHasCells(array $cells, $expectedHasCells)
{
$rowManager = new RowManager(new StyleMerger());
$row = new Row($cells, null, $rowManager);
$this->assertEquals($expectedHasCells, $rowManager->hasCells($row));
}
/**
* @return array
*/
public function dataProviderForTestIsEmptyRow()
{
return [
// cells, expected isEmpty
[[], true],
[[new Cell('')], true],
[[new Cell(''), new Cell(''), new Cell('Okay')], false],
];
}
/**
* @dataProvider dataProviderForTestIsEmptyRow
*
* @param array $cells
* @param bool $expectedIsEmpty
* @return void
*/
public function testIsEmptyRow(array $cells, $expectedIsEmpty)
{
$rowManager = new RowManager(new StyleMerger());
$row = new Row($cells, null, $rowManager);
$this->assertEquals($expectedIsEmpty, $rowManager->isEmpty($row));
}
}

View File

@ -3,6 +3,7 @@
namespace Box\Spout\Writer\Common\Manager\Style; namespace Box\Spout\Writer\Common\Manager\Style;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder; use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Writer\Common\Entity\Cell;
/** /**
* Class StyleManagerTest * Class StyleManagerTest
@ -29,7 +30,7 @@ class StyleManagerTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($style->shouldWrapText()); $this->assertFalse($style->shouldWrapText());
$styleManager = $this->getStyleManager(); $styleManager = $this->getStyleManager();
$updatedStyle = $styleManager->applyExtraStylesIfNeeded($style, [12, 'single line', "multi\nlines", null]); $updatedStyle = $styleManager->applyExtraStylesIfNeeded(new Cell("multi\nlines", $style));
$this->assertTrue($updatedStyle->shouldWrapText()); $this->assertTrue($updatedStyle->shouldWrapText());
} }
@ -43,7 +44,7 @@ class StyleManagerTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($style->shouldWrapText()); $this->assertTrue($style->shouldWrapText());
$styleManager = $this->getStyleManager(); $styleManager = $this->getStyleManager();
$updatedStyle = $styleManager->applyExtraStylesIfNeeded($style, ["multi\nlines"]); $updatedStyle = $styleManager->applyExtraStylesIfNeeded(new Cell("multi\nlines"));
$this->assertTrue($updatedStyle->shouldWrapText()); $this->assertTrue($updatedStyle->shouldWrapText());
} }

View File

@ -4,6 +4,7 @@ namespace Box\Spout\Writer\ODS;
use Box\Spout\Common\Type; use Box\Spout\Common\Type;
use Box\Spout\TestUsingResource; use Box\Spout\TestUsingResource;
use Box\Spout\Writer\Common\Creator\EntityFactory;
use Box\Spout\Writer\Common\Entity\Sheet; use Box\Spout\Writer\Common\Entity\Sheet;
use Box\Spout\Writer\WriterFactory; use Box\Spout\Writer\WriterFactory;
@ -91,7 +92,11 @@ class SheetTest extends \PHPUnit_Framework_TestCase
$sheet = $writer->getCurrentSheet(); $sheet = $writer->getCurrentSheet();
$sheet->setName($sheetName); $sheet->setName($sheetName);
$writer->addRow(['ods--11', 'ods--12']); $row = EntityFactory::createRow([
EntityFactory::createCell('ods--11'),
EntityFactory::createCell('ods--12'),
]);
$writer->addRow($row);
$writer->close(); $writer->close();
} }
@ -108,9 +113,20 @@ class SheetTest extends \PHPUnit_Framework_TestCase
$writer = WriterFactory::create(Type::ODS); $writer = WriterFactory::create(Type::ODS);
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
$writer->addRow(['ods--sheet1--11', 'ods--sheet1--12']); $row = EntityFactory::createRow([
EntityFactory::createCell('ods--sheet1--11'),
EntityFactory::createCell('ods--sheet1--12'),
]);
$writer->addRow($row);
$writer->addNewSheetAndMakeItCurrent(); $writer->addNewSheetAndMakeItCurrent();
$writer->addRow(['ods--sheet2--11', 'ods--sheet2--12', 'ods--sheet2--13']);
$row = EntityFactory::createRow([
EntityFactory::createCell('ods--sheet2--11'),
EntityFactory::createCell('ods--sheet2--12'),
EntityFactory::createCell('ods--sheet2--13'),
]);
$writer->addRow($row);
$writer->close(); $writer->close();

View File

@ -6,6 +6,7 @@ use Box\Spout\Common\Exception\SpoutException;
use Box\Spout\Common\Type; use Box\Spout\Common\Type;
use Box\Spout\Reader\Wrapper\XMLReader; use Box\Spout\Reader\Wrapper\XMLReader;
use Box\Spout\TestUsingResource; use Box\Spout\TestUsingResource;
use Box\Spout\Writer\Common\Creator\EntityFactory;
use Box\Spout\Writer\Common\Entity\Cell; use Box\Spout\Writer\Common\Entity\Cell;
use Box\Spout\Writer\Common\Helper\ZipHelper; use Box\Spout\Writer\Common\Helper\ZipHelper;
use Box\Spout\Writer\WriterFactory; use Box\Spout\Writer\WriterFactory;
@ -17,6 +18,20 @@ class WriterTest extends \PHPUnit_Framework_TestCase
{ {
use TestUsingResource; use TestUsingResource;
/**
* @var EntityFactory
*/
protected $entityFactory;
/**
* @return void
*/
protected function setUp()
{
$this->entityFactory = new EntityFactory();
parent::setUp();
}
/** /**
* @expectedException \Box\Spout\Common\Exception\IOException * @expectedException \Box\Spout\Common\Exception\IOException
*/ */
@ -36,7 +51,11 @@ class WriterTest extends \PHPUnit_Framework_TestCase
public function testAddRowShouldThrowExceptionIfCallAddRowBeforeOpeningWriter() public function testAddRowShouldThrowExceptionIfCallAddRowBeforeOpeningWriter()
{ {
$writer = WriterFactory::create(Type::ODS); $writer = WriterFactory::create(Type::ODS);
$writer->addRow(['ods--11', 'ods--12']); $row = $this->entityFactory->createRow([
EntityFactory::createCell('csv--11'),
EntityFactory::createCell('csv--12'),
]);
$writer->addRow($row);
} }
/** /**
@ -45,7 +64,11 @@ class WriterTest extends \PHPUnit_Framework_TestCase
public function testAddRowShouldThrowExceptionIfCalledBeforeOpeningWriter() public function testAddRowShouldThrowExceptionIfCalledBeforeOpeningWriter()
{ {
$writer = WriterFactory::create(Type::ODS); $writer = WriterFactory::create(Type::ODS);
$writer->addRows([['ods--11', 'ods--12']]); $row = $this->entityFactory->createRow([
EntityFactory::createCell('csv--11'),
EntityFactory::createCell('csv--12'),
]);
$writer->addRows([$row]);
} }
/** /**
@ -98,8 +121,8 @@ class WriterTest extends \PHPUnit_Framework_TestCase
{ {
$fileName = 'test_add_row_should_cleanup_all_files_if_exception_thrown.ods'; $fileName = 'test_add_row_should_cleanup_all_files_if_exception_thrown.ods';
$dataRows = [ $dataRows = [
['wrong'], $this->entityFactory->createRow([]),
[new \stdClass()], new \stdClass(),
]; ];
$this->createGeneratedFolderIfNeeded($fileName); $this->createGeneratedFolderIfNeeded($fileName);
@ -191,6 +214,7 @@ class WriterTest extends \PHPUnit_Framework_TestCase
public function testAddRowShouldWriteGivenDataToSheet() public function testAddRowShouldWriteGivenDataToSheet()
{ {
$fileName = 'test_add_row_should_write_given_data_to_sheet.ods'; $fileName = 'test_add_row_should_write_given_data_to_sheet.ods';
$dataRows = [ $dataRows = [
['ods--11', 'ods--12'], ['ods--11', 'ods--12'],
['ods--21', 'ods--22', 'ods--23'], ['ods--21', 'ods--22', 'ods--23'],
@ -313,6 +337,14 @@ class WriterTest extends \PHPUnit_Framework_TestCase
*/ */
public function testAddRowShouldWriteGivenDataToTheCorrectSheet() public function testAddRowShouldWriteGivenDataToTheCorrectSheet()
{ {
$arrayToRows = function (array $allRows) {
return array_map(function ($oneRow) {
return $this->entityFactory->createRow(array_map(function ($value) {
return EntityFactory::createCell($value);
}, $oneRow));
}, $allRows);
};
$fileName = 'test_add_row_should_write_given_data_to_the_correct_sheet.ods'; $fileName = 'test_add_row_should_write_given_data_to_the_correct_sheet.ods';
$dataRowsSheet1 = [ $dataRowsSheet1 = [
['ods--sheet1--11', 'ods--sheet1--12'], ['ods--sheet1--11', 'ods--sheet1--12'],
@ -334,15 +366,15 @@ class WriterTest extends \PHPUnit_Framework_TestCase
$writer = WriterFactory::create(Type::ODS); $writer = WriterFactory::create(Type::ODS);
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
$writer->addRows($dataRowsSheet1); $writer->addRows($arrayToRows($dataRowsSheet1));
$writer->addNewSheetAndMakeItCurrent(); $writer->addNewSheetAndMakeItCurrent();
$writer->addRows($dataRowsSheet2); $writer->addRows($arrayToRows($dataRowsSheet2));
$firstSheet = $writer->getSheets()[0]; $firstSheet = $writer->getSheets()[0];
$writer->setCurrentSheet($firstSheet); $writer->setCurrentSheet($firstSheet);
$writer->addRows($dataRowsSheet1Again); $writer->addRows($arrayToRows($dataRowsSheet1Again));
$writer->close(); $writer->close();
@ -471,8 +503,8 @@ class WriterTest extends \PHPUnit_Framework_TestCase
{ {
$fileName = 'test_writer_should_accept_cell_objects.ods'; $fileName = 'test_writer_should_accept_cell_objects.ods';
$dataRows = [ $dataRows = [
[new Cell('ods--11'), new Cell('ods--12')], [EntityFactory::createCell('ods--11'), EntityFactory::createCell('ods--12')],
[new Cell('ods--21'), new Cell('ods--22'), new Cell('ods--23')], [EntityFactory::createCell('ods--21'), EntityFactory::createCell('ods--22'), EntityFactory::createCell('ods--23')],
]; ];
$this->writeToODSFile($dataRows, $fileName); $this->writeToODSFile($dataRows, $fileName);
@ -492,7 +524,7 @@ class WriterTest extends \PHPUnit_Framework_TestCase
{ {
$fileName = 'test_writer_should_accept_cell_objects_with_types.ods'; $fileName = 'test_writer_should_accept_cell_objects_with_types.ods';
$dataRows = [ $dataRows = [
[new Cell('i am a string'), new Cell(51465), new Cell(true), new Cell(51465.5)], [EntityFactory::createCell('i am a string'), EntityFactory::createCell(51465), EntityFactory::createCell(true), EntityFactory::createCell(51465.5)],
]; ];
$this->writeToODSFile($dataRows, $fileName); $this->writeToODSFile($dataRows, $fileName);
@ -521,7 +553,16 @@ class WriterTest extends \PHPUnit_Framework_TestCase
$writer->setShouldCreateNewSheetsAutomatically($shouldCreateSheetsAutomatically); $writer->setShouldCreateNewSheetsAutomatically($shouldCreateSheetsAutomatically);
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
$writer->addRows($allRows); $writer->addRows(array_map(function ($oneRow) {
return $this->entityFactory->createRow(array_map(function ($value) {
// @TODO: always pass a Cell instance!
if (!$value instanceof Cell) {
return EntityFactory::createCell($value);
} else {
return $value;
}
}, $oneRow));
}, $allRows));
$writer->close(); $writer->close();
return $writer; return $writer;
@ -544,11 +585,19 @@ class WriterTest extends \PHPUnit_Framework_TestCase
$writer->setShouldCreateNewSheetsAutomatically($shouldCreateSheetsAutomatically); $writer->setShouldCreateNewSheetsAutomatically($shouldCreateSheetsAutomatically);
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
$writer->addRows($allRows); $writer->addRows(array_map(function ($oneRow) {
return $this->entityFactory->createRow(array_map(function ($value) {
return EntityFactory::createCell($value);
}, $oneRow));
}, $allRows));
for ($i = 1; $i < $numSheets; $i++) { for ($i = 1; $i < $numSheets; $i++) {
$writer->addNewSheetAndMakeItCurrent(); $writer->addNewSheetAndMakeItCurrent();
$writer->addRows($allRows); $writer->addRows(array_map(function ($oneRow) {
return $this->entityFactory->createRow(array_map(function ($value) {
return EntityFactory::createCell($value);
}, $oneRow));
}, $allRows));
} }
$writer->close(); $writer->close();

View File

@ -5,8 +5,10 @@ namespace Box\Spout\Writer\ODS;
use Box\Spout\Common\Type; use Box\Spout\Common\Type;
use Box\Spout\Reader\Wrapper\XMLReader; use Box\Spout\Reader\Wrapper\XMLReader;
use Box\Spout\TestUsingResource; use Box\Spout\TestUsingResource;
use Box\Spout\Writer\Common\Creator\EntityFactory;
use Box\Spout\Writer\Common\Creator\Style\BorderBuilder; use Box\Spout\Writer\Common\Creator\Style\BorderBuilder;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder; use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Writer\Common\Entity\Cell;
use Box\Spout\Writer\Common\Entity\Style\Border; use Box\Spout\Writer\Common\Entity\Style\Border;
use Box\Spout\Writer\Common\Entity\Style\Color; use Box\Spout\Writer\Common\Entity\Style\Color;
use Box\Spout\Writer\Common\Entity\Style\Style; use Box\Spout\Writer\Common\Entity\Style\Style;
@ -36,16 +38,24 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
public function testAddRowWithStyleShouldThrowExceptionIfCallAddRowBeforeOpeningWriter() public function testAddRowWithStyleShouldThrowExceptionIfCallAddRowBeforeOpeningWriter()
{ {
$writer = WriterFactory::create(Type::ODS); $writer = WriterFactory::create(Type::ODS);
$writer->addRowWithStyle(['ods--11', 'ods--12'], $this->defaultStyle); $row = EntityFactory::createRow([
EntityFactory::createCell('ods--11'),
EntityFactory::createCell('ods--12'),
], $this->defaultStyle);
$writer->addRow($row);
} }
/** /**
* @expectedException \Box\Spout\Writer\Exception\WriterNotOpenedException * @expectedException \Box\Spout\Writer\Exception\WriterNotOpenedException
*/ */
public function testAddRowWithStyleShouldThrowExceptionIfCalledBeforeOpeningWriter() public function testAddRowsWithStyleShouldThrowExceptionIfCalledBeforeOpeningWriter()
{ {
$writer = WriterFactory::create(Type::ODS); $writer = WriterFactory::create(Type::ODS);
$writer->addRowWithStyle(['ods--11', 'ods--12'], $this->defaultStyle); $row = EntityFactory::createRow([
EntityFactory::createCell('ods--11'),
EntityFactory::createCell('ods--12'),
], $this->defaultStyle);
$writer->addRows([$row]);
} }
/** /**
@ -56,42 +66,53 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
return [ return [
['style'], ['style'],
[new \stdClass()], [new \stdClass()],
[null],
]; ];
} }
/** /**
* @requires PHP 7
* @dataProvider dataProviderForInvalidStyle * @dataProvider dataProviderForInvalidStyle
* @expectedException \Box\Spout\Common\Exception\InvalidArgumentException
* *
* @param \Box\Spout\Writer\Common\Entity\Style\Style $style * @param \Box\Spout\Writer\Common\Entity\Style\Style $style
*/ */
public function testAddRowWithStyleShouldThrowExceptionIfInvalidStyleGiven($style) public function testAddRowWithStyleShouldThrowExceptionIfInvalidStyleGiven($style)
{ {
$this->expectException(\TypeError::class);
$fileName = 'test_add_row_with_style_should_throw_exception.ods'; $fileName = 'test_add_row_with_style_should_throw_exception.ods';
$this->createGeneratedFolderIfNeeded($fileName); $this->createGeneratedFolderIfNeeded($fileName);
$resourcePath = $this->getGeneratedResourcePath($fileName); $resourcePath = $this->getGeneratedResourcePath($fileName);
$writer = WriterFactory::create(Type::ODS); $writer = WriterFactory::create(Type::ODS);
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
$writer->addRowWithStyle(['ods--11', 'ods--12'], $style); $row = EntityFactory::createRow([
EntityFactory::createCell('ods--11'),
EntityFactory::createCell('ods--12'),
], $style);
$writer->addRow($row);
} }
/** /**
* @requires PHP 7
* @dataProvider dataProviderForInvalidStyle * @dataProvider dataProviderForInvalidStyle
* @expectedException \Box\Spout\Common\Exception\InvalidArgumentException
* *
* @param \Box\Spout\Writer\Common\Entity\Style\Style $style * @param \Box\Spout\Writer\Common\Entity\Style\Style $style
*/ */
public function testAddRowsWithStyleShouldThrowExceptionIfInvalidStyleGiven($style) public function testAddRowsWithStyleShouldThrowExceptionIfInvalidStyleGiven($style)
{ {
$this->expectException(\TypeError::class);
$fileName = 'test_add_row_with_style_should_throw_exception.ods'; $fileName = 'test_add_row_with_style_should_throw_exception.ods';
$this->createGeneratedFolderIfNeeded($fileName); $this->createGeneratedFolderIfNeeded($fileName);
$resourcePath = $this->getGeneratedResourcePath($fileName); $resourcePath = $this->getGeneratedResourcePath($fileName);
$writer = WriterFactory::create(Type::ODS); $writer = WriterFactory::create(Type::ODS);
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
$writer->addRowsWithStyle([['ods--11', 'ods--12']], $style); $row = EntityFactory::createRow([
EntityFactory::createCell('ods--11'),
EntityFactory::createCell('ods--12'),
], $style);
$writer->addRows([[$row]]);
} }
/** /**
@ -328,7 +349,10 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
public function testSetDefaultRowStyle() public function testSetDefaultRowStyle()
{ {
$fileName = 'test_set_default_row_style.ods'; $fileName = 'test_set_default_row_style.ods';
$dataRows = [['ods--11']]; $row = EntityFactory::createRow([
EntityFactory::createCell('ods--11'),
]);
$dataRows = [$row];
$defaultFontSize = 50; $defaultFontSize = 50;
$defaultStyle = (new StyleBuilder())->setFontSize($defaultFontSize)->build(); $defaultStyle = (new StyleBuilder())->setFontSize($defaultFontSize)->build();
@ -347,6 +371,14 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
*/ */
private function writeToODSFile($allRows, $fileName, $style) private function writeToODSFile($allRows, $fileName, $style)
{ {
$arrayToRows = function (array $allRows) use ($style) {
return array_map(function ($oneRow) use ($style) {
return EntityFactory::createRow(array_map(function ($value) {
return EntityFactory::createCell($value);
}, $oneRow), $style);
}, $allRows);
};
$this->createGeneratedFolderIfNeeded($fileName); $this->createGeneratedFolderIfNeeded($fileName);
$resourcePath = $this->getGeneratedResourcePath($fileName); $resourcePath = $this->getGeneratedResourcePath($fileName);
@ -354,7 +386,7 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
$writer = WriterFactory::create(Type::ODS); $writer = WriterFactory::create(Type::ODS);
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
$writer->addRowsWithStyle($allRows, $style); $writer->addRows($arrayToRows($allRows));
$writer->close(); $writer->close();
return $writer; return $writer;
@ -401,11 +433,12 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
for ($i = 0; $i < count($allRows); $i++) { for ($i = 0; $i < count($allRows); $i++) {
if ($styles[$i] === null) { $currentRow = $allRows[$i];
$writer->addRow($allRows[$i]); $currentStyle = $styles[$i];
} else { $row = EntityFactory::createRow(array_map(function ($value) {
$writer->addRowWithStyle($allRows[$i], $styles[$i]); return EntityFactory::createCell($value);
} }, $currentRow), $currentStyle);
$writer->addRow($row);
} }
$writer->close(); $writer->close();

View File

@ -4,6 +4,7 @@ namespace Box\Spout\Writer\XLSX;
use Box\Spout\Common\Type; use Box\Spout\Common\Type;
use Box\Spout\TestUsingResource; use Box\Spout\TestUsingResource;
use Box\Spout\Writer\Common\Creator\EntityFactory;
use Box\Spout\Writer\Common\Entity\Sheet; use Box\Spout\Writer\Common\Entity\Sheet;
use Box\Spout\Writer\WriterFactory; use Box\Spout\Writer\WriterFactory;
@ -91,7 +92,11 @@ class SheetTest extends \PHPUnit_Framework_TestCase
$sheet = $writer->getCurrentSheet(); $sheet = $writer->getCurrentSheet();
$sheet->setName($sheetName); $sheet->setName($sheetName);
$writer->addRow(['xlsx--11', 'xlsx--12']); $row = EntityFactory::createRow([
EntityFactory::createCell('xlsx--11'),
EntityFactory::createCell('xlsx--12'),
]);
$writer->addRow($row);
$writer->close(); $writer->close();
return $sheet; return $sheet;
@ -110,9 +115,20 @@ class SheetTest extends \PHPUnit_Framework_TestCase
$writer = WriterFactory::create(Type::XLSX); $writer = WriterFactory::create(Type::XLSX);
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
$writer->addRow(['xlsx--sheet1--11', 'xlsx--sheet1--12']); $row = EntityFactory::createRow([
EntityFactory::createCell('xlsx--sheet1--11'),
EntityFactory::createCell('xlsx--sheet1--12'),
]);
$writer->addRow($row);
$writer->addNewSheetAndMakeItCurrent(); $writer->addNewSheetAndMakeItCurrent();
$writer->addRow(['xlsx--sheet2--11', 'xlsx--sheet2--12', 'xlsx--sheet2--13']);
$row = EntityFactory::createRow([
EntityFactory::createCell('xlsx--sheet2--11'),
EntityFactory::createCell('xlsx--sheet2--12'),
EntityFactory::createCell('xlsx--sheet2--13'),
]);
$writer->addRow($row);
$writer->close(); $writer->close();

View File

@ -5,6 +5,7 @@ namespace Box\Spout\Writer\XLSX;
use Box\Spout\Common\Exception\SpoutException; use Box\Spout\Common\Exception\SpoutException;
use Box\Spout\Common\Type; use Box\Spout\Common\Type;
use Box\Spout\TestUsingResource; use Box\Spout\TestUsingResource;
use Box\Spout\Writer\Common\Creator\EntityFactory;
use Box\Spout\Writer\Common\Entity\Cell; use Box\Spout\Writer\Common\Entity\Cell;
use Box\Spout\Writer\WriterFactory; use Box\Spout\Writer\WriterFactory;
use Box\Spout\Writer\XLSX\Manager\WorksheetManager; use Box\Spout\Writer\XLSX\Manager\WorksheetManager;
@ -16,6 +17,20 @@ class WriterTest extends \PHPUnit_Framework_TestCase
{ {
use TestUsingResource; use TestUsingResource;
/**
* @var EntityFactory
*/
protected $entityFactory;
/**
* @return void
*/
protected function setUp()
{
$this->entityFactory = new EntityFactory();
parent::setUp();
}
/** /**
* @expectedException \Box\Spout\Common\Exception\IOException * @expectedException \Box\Spout\Common\Exception\IOException
*/ */
@ -35,7 +50,12 @@ class WriterTest extends \PHPUnit_Framework_TestCase
public function testAddRowShouldThrowExceptionIfCallAddRowBeforeOpeningWriter() public function testAddRowShouldThrowExceptionIfCallAddRowBeforeOpeningWriter()
{ {
$writer = WriterFactory::create(Type::XLSX); $writer = WriterFactory::create(Type::XLSX);
$writer->addRow(['xlsx--11', 'xlsx--12']);
$row = EntityFactory::createRow([
EntityFactory::createCell('xlsx--11'),
EntityFactory::createCell('xlsx--12'),
]);
$writer->addRow($row);
} }
/** /**
@ -44,7 +64,11 @@ class WriterTest extends \PHPUnit_Framework_TestCase
public function testAddRowShouldThrowExceptionIfCalledBeforeOpeningWriter() public function testAddRowShouldThrowExceptionIfCalledBeforeOpeningWriter()
{ {
$writer = WriterFactory::create(Type::XLSX); $writer = WriterFactory::create(Type::XLSX);
$writer->addRows([['xlsx--11', 'xlsx--12']]); $row = EntityFactory::createRow([
EntityFactory::createCell('xlsx--11'),
EntityFactory::createCell('xlsx--12'),
]);
$writer->addRows([$row]);
} }
/** /**
@ -361,6 +385,14 @@ class WriterTest extends \PHPUnit_Framework_TestCase
*/ */
public function testAddRowShouldWriteGivenDataToTheCorrectSheet() public function testAddRowShouldWriteGivenDataToTheCorrectSheet()
{ {
$arrayToRows = function (array $allRows) {
return array_map(function ($oneRow) {
return EntityFactory::createRow(array_map(function ($value) {
return EntityFactory::createCell($value);
}, $oneRow));
}, $allRows);
};
$fileName = 'test_add_row_should_write_given_data_to_the_correct_sheet.xlsx'; $fileName = 'test_add_row_should_write_given_data_to_the_correct_sheet.xlsx';
$dataRowsSheet1 = [ $dataRowsSheet1 = [
['xlsx--sheet1--11', 'xlsx--sheet1--12'], ['xlsx--sheet1--11', 'xlsx--sheet1--12'],
@ -384,15 +416,15 @@ class WriterTest extends \PHPUnit_Framework_TestCase
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
$writer->addRows($dataRowsSheet1); $writer->addRows($arrayToRows($dataRowsSheet1));
$writer->addNewSheetAndMakeItCurrent(); $writer->addNewSheetAndMakeItCurrent();
$writer->addRows($dataRowsSheet2); $writer->addRows($arrayToRows($dataRowsSheet2));
$firstSheet = $writer->getSheets()[0]; $firstSheet = $writer->getSheets()[0];
$writer->setCurrentSheet($firstSheet); $writer->setCurrentSheet($firstSheet);
$writer->addRows($dataRowsSheet1Again); $writer->addRows($arrayToRows($dataRowsSheet1Again));
$writer->close(); $writer->close();
@ -513,8 +545,8 @@ class WriterTest extends \PHPUnit_Framework_TestCase
{ {
$fileName = 'test_writer_should_accept_cell_objects.xlsx'; $fileName = 'test_writer_should_accept_cell_objects.xlsx';
$dataRows = [ $dataRows = [
[new Cell('xlsx--11'), new Cell('xlsx--12')], [EntityFactory::createCell('xlsx--11'), EntityFactory::createCell('xlsx--12')],
[new Cell('xlsx--21'), new Cell('xlsx--22'), new Cell('xlsx--23')], [EntityFactory::createCell('xlsx--21'), EntityFactory::createCell('xlsx--22'), EntityFactory::createCell('xlsx--23')],
]; ];
$this->writeToXLSXFile($dataRows, $fileName, $shouldUseInlineStrings = false); $this->writeToXLSXFile($dataRows, $fileName, $shouldUseInlineStrings = false);
@ -535,10 +567,10 @@ class WriterTest extends \PHPUnit_Framework_TestCase
$fileName = 'test_writer_should_accept_cell_objects_with_types.xlsx'; $fileName = 'test_writer_should_accept_cell_objects_with_types.xlsx';
$dataRowsShared = [ $dataRowsShared = [
[new Cell('i am a string')], [EntityFactory::createCell('i am a string')],
]; ];
$dataRowsInline = [ $dataRowsInline = [
[new Cell(51465), new Cell(true), new Cell(51465.5)], [EntityFactory::createCell(51465), EntityFactory::createCell(true), EntityFactory::createCell(51465.5)],
]; ];
$dataRows = array_merge($dataRowsShared, $dataRowsInline); $dataRows = array_merge($dataRowsShared, $dataRowsInline);
@ -578,7 +610,15 @@ class WriterTest extends \PHPUnit_Framework_TestCase
$writer->setShouldCreateNewSheetsAutomatically($shouldCreateSheetsAutomatically); $writer->setShouldCreateNewSheetsAutomatically($shouldCreateSheetsAutomatically);
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
$writer->addRows($allRows); $writer->addRows(array_map(function ($oneRow) {
return EntityFactory::createRow(array_map(function ($value) {
if (!$value instanceof Cell) {
return EntityFactory::createCell($value);
} else {
return $value;
}
}, $oneRow));
}, $allRows));
$writer->close(); $writer->close();
return $writer; return $writer;
@ -603,11 +643,19 @@ class WriterTest extends \PHPUnit_Framework_TestCase
$writer->setShouldCreateNewSheetsAutomatically($shouldCreateSheetsAutomatically); $writer->setShouldCreateNewSheetsAutomatically($shouldCreateSheetsAutomatically);
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
$writer->addRows($allRows); $writer->addRows(array_map(function ($oneRow) {
return EntityFactory::createRow(array_map(function ($value) {
return EntityFactory::createCell($value);
}, $oneRow));
}, $allRows));
for ($i = 1; $i < $numSheets; $i++) { for ($i = 1; $i < $numSheets; $i++) {
$writer->addNewSheetAndMakeItCurrent(); $writer->addNewSheetAndMakeItCurrent();
$writer->addRows($allRows); $writer->addRows(array_map(function ($oneRow) {
return EntityFactory::createRow(array_map(function ($value) {
return EntityFactory::createCell($value);
}, $oneRow));
}, $allRows));
} }
$writer->close(); $writer->close();

View File

@ -5,8 +5,10 @@ namespace Box\Spout\Writer\XLSX;
use Box\Spout\Common\Type; use Box\Spout\Common\Type;
use Box\Spout\Reader\Wrapper\XMLReader; use Box\Spout\Reader\Wrapper\XMLReader;
use Box\Spout\TestUsingResource; use Box\Spout\TestUsingResource;
use Box\Spout\Writer\Common\Creator\EntityFactory;
use Box\Spout\Writer\Common\Creator\Style\BorderBuilder; use Box\Spout\Writer\Common\Creator\Style\BorderBuilder;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder; use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Writer\Common\Entity\Cell;
use Box\Spout\Writer\Common\Entity\Style\Border; use Box\Spout\Writer\Common\Entity\Style\Border;
use Box\Spout\Writer\Common\Entity\Style\Color; use Box\Spout\Writer\Common\Entity\Style\Color;
use Box\Spout\Writer\Common\Entity\Style\Style; use Box\Spout\Writer\Common\Entity\Style\Style;
@ -38,16 +40,24 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
public function testAddRowWithStyleShouldThrowExceptionIfCallAddRowBeforeOpeningWriter() public function testAddRowWithStyleShouldThrowExceptionIfCallAddRowBeforeOpeningWriter()
{ {
$writer = WriterFactory::create(Type::XLSX); $writer = WriterFactory::create(Type::XLSX);
$writer->addRowWithStyle(['xlsx--11', 'xlsx--12'], $this->defaultStyle); $row = EntityFactory::createRow([
EntityFactory::createCell('xlsx--11'),
EntityFactory::createCell('xlsx--12'),
], $this->defaultStyle);
$writer->addRow($row);
} }
/** /**
* @expectedException \Box\Spout\Writer\Exception\WriterNotOpenedException * @expectedException \Box\Spout\Writer\Exception\WriterNotOpenedException
*/ */
public function testAddRowWithStyleShouldThrowExceptionIfCalledBeforeOpeningWriter() public function testAddRowsWithStyleShouldThrowExceptionIfCalledBeforeOpeningWriter()
{ {
$writer = WriterFactory::create(Type::XLSX); $writer = WriterFactory::create(Type::XLSX);
$writer->addRowWithStyle(['xlsx--11', 'xlsx--12'], $this->defaultStyle); $row = EntityFactory::createRow([
EntityFactory::createCell('xlsx--11'),
EntityFactory::createCell('xlsx--12'),
], $this->defaultStyle);
$writer->addRows([$row]);
} }
/** /**
@ -58,42 +68,53 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
return [ return [
['style'], ['style'],
[new \stdClass()], [new \stdClass()],
[null],
]; ];
} }
/** /**
* @requires PHP 7
* @dataProvider dataProviderForInvalidStyle * @dataProvider dataProviderForInvalidStyle
* @expectedException \Box\Spout\Common\Exception\InvalidArgumentException
* *
* @param \Box\Spout\Writer\Common\Entity\Style\Style $style * @param \Box\Spout\Writer\Common\Entity\Style\Style $style
*/ */
public function testAddRowWithStyleShouldThrowExceptionIfInvalidStyleGiven($style) public function testAddRowWithStyleShouldThrowExceptionIfInvalidStyleGiven($style)
{ {
$this->expectException(\TypeError::class);
$fileName = 'test_add_row_with_style_should_throw_exception.xlsx'; $fileName = 'test_add_row_with_style_should_throw_exception.xlsx';
$this->createGeneratedFolderIfNeeded($fileName); $this->createGeneratedFolderIfNeeded($fileName);
$resourcePath = $this->getGeneratedResourcePath($fileName); $resourcePath = $this->getGeneratedResourcePath($fileName);
$writer = WriterFactory::create(Type::XLSX); $writer = WriterFactory::create(Type::XLSX);
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
$writer->addRowWithStyle(['xlsx--11', 'xlsx--12'], $style); $row = EntityFactory::createRow([
EntityFactory::createCell('xlsx--11'),
EntityFactory::createCell('xlsx--12'),
], $style);
$writer->addRow($row);
} }
/** /**
* @requires PHP 7
* @dataProvider dataProviderForInvalidStyle * @dataProvider dataProviderForInvalidStyle
* @expectedException \Box\Spout\Common\Exception\InvalidArgumentException
* *
* @param \Box\Spout\Writer\Common\Entity\Style\Style $style * @param \Box\Spout\Writer\Common\Entity\Style\Style $style
*/ */
public function testAddRowsWithStyleShouldThrowExceptionIfInvalidStyleGiven($style) public function testAddRowsWithStyleShouldThrowExceptionIfInvalidStyleGiven($style)
{ {
$this->expectException(\TypeError::class);
$fileName = 'test_add_row_with_style_should_throw_exception.xlsx'; $fileName = 'test_add_row_with_style_should_throw_exception.xlsx';
$this->createGeneratedFolderIfNeeded($fileName); $this->createGeneratedFolderIfNeeded($fileName);
$resourcePath = $this->getGeneratedResourcePath($fileName); $resourcePath = $this->getGeneratedResourcePath($fileName);
$writer = WriterFactory::create(Type::XLSX); $writer = WriterFactory::create(Type::XLSX);
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
$writer->addRowsWithStyle([['xlsx--11', 'xlsx--12']], $style); $row = EntityFactory::createRow([
EntityFactory::createCell('xlsx--11'),
EntityFactory::createCell('xlsx--12'),
], $style);
$writer->addRows([$row]);
} }
/** /**
@ -429,7 +450,11 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
public function testSetDefaultRowStyle() public function testSetDefaultRowStyle()
{ {
$fileName = 'test_set_default_row_style.xlsx'; $fileName = 'test_set_default_row_style.xlsx';
$dataRows = [['xlsx--11']];
$row = EntityFactory::createRow([
EntityFactory::createCell('xlsx--11'),
]);
$dataRows = [$row];
$defaultFontSize = 50; $defaultFontSize = 50;
$defaultStyle = (new StyleBuilder())->setFontSize($defaultFontSize)->build(); $defaultStyle = (new StyleBuilder())->setFontSize($defaultFontSize)->build();
@ -521,6 +546,14 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
*/ */
private function writeToXLSXFile($allRows, $fileName, $style) private function writeToXLSXFile($allRows, $fileName, $style)
{ {
$arrayToRows = function (array $allRows) use ($style) {
return array_map(function ($oneRow) use ($style) {
return EntityFactory::createRow(array_map(function ($value) {
return EntityFactory::createCell($value);
}, $oneRow), $style);
}, $allRows);
};
$this->createGeneratedFolderIfNeeded($fileName); $this->createGeneratedFolderIfNeeded($fileName);
$resourcePath = $this->getGeneratedResourcePath($fileName); $resourcePath = $this->getGeneratedResourcePath($fileName);
@ -529,7 +562,7 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
$writer->setShouldUseInlineStrings(true); $writer->setShouldUseInlineStrings(true);
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
$writer->addRowsWithStyle($allRows, $style); $writer->addRows(($arrayToRows($allRows)));
$writer->close(); $writer->close();
return $writer; return $writer;
@ -578,11 +611,12 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
$writer->openToFile($resourcePath); $writer->openToFile($resourcePath);
for ($i = 0; $i < count($allRows); $i++) { for ($i = 0; $i < count($allRows); $i++) {
if ($styles[$i] === null) { $currentRow = $allRows[$i];
$writer->addRow($allRows[$i]); $currentStyle = $styles[$i];
} else { $row = EntityFactory::createRow(array_map(function ($value) {
$writer->addRowWithStyle($allRows[$i], $styles[$i]); return EntityFactory::createCell($value);
} }, $currentRow), $currentStyle);
$writer->addRow($row);
} }
$writer->close(); $writer->close();