implement cell styling and row objects
This commit is contained in:
parent
33c28dbf6c
commit
97cdd0c627
@ -6,6 +6,7 @@ use Box\Spout\Writer\WriterAbstract;
|
|||||||
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Writer
|
* Class Writer
|
||||||
@ -77,20 +78,20 @@ class Writer extends WriterAbstract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds data to the currently opened writer.
|
* Adds a row to the currently opened writer.
|
||||||
|
*
|
||||||
|
* @param Row $row The row containing cells and styles
|
||||||
*
|
*
|
||||||
* @param array $dataRow Array containing data to be written.
|
|
||||||
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
|
|
||||||
* @param \Box\Spout\Writer\Common\Entity\Style\Style $style Ignored here since CSV does not support styling.
|
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
|
* @throws IOException If unable to write data
|
||||||
|
* @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');
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
namespace Box\Spout\Writer\Common\Entity;
|
namespace Box\Spout\Writer\Common\Entity;
|
||||||
|
|
||||||
use Box\Spout\Writer\Common\Helper\CellHelper;
|
|
||||||
use Box\Spout\Writer\Common\Entity\Style\Style;
|
use Box\Spout\Writer\Common\Entity\Style\Style;
|
||||||
|
use Box\Spout\Writer\Common\Helper\CellHelper;
|
||||||
|
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Cell
|
* Class Cell
|
||||||
@ -61,6 +62,11 @@ class Cell
|
|||||||
*/
|
*/
|
||||||
protected $style = null;
|
protected $style = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var StyleMerger
|
||||||
|
*/
|
||||||
|
protected $styleMerger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cell constructor.
|
* Cell constructor.
|
||||||
* @param $value mixed
|
* @param $value mixed
|
||||||
@ -72,6 +78,8 @@ class Cell
|
|||||||
if ($style) {
|
if ($style) {
|
||||||
$this->setStyle($style);
|
$this->setStyle($style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->styleMerger = new StyleMerger();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,10 +108,13 @@ class Cell
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Style|null
|
* @return Style
|
||||||
*/
|
*/
|
||||||
public function getStyle()
|
public function getStyle()
|
||||||
{
|
{
|
||||||
|
if (!isset($this->style)) {
|
||||||
|
$this->setStyle(new Style());
|
||||||
|
}
|
||||||
return $this->style;
|
return $this->style;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,4 +202,18 @@ class Cell
|
|||||||
{
|
{
|
||||||
return (string)$this->value;
|
return (string)$this->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Style $style|null
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function applyStyle(Style $style = null)
|
||||||
|
{
|
||||||
|
if ($style === null) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
$merged = $this->styleMerger->merge($this->getStyle(), $style);
|
||||||
|
$this->setStyle($merged);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
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\Entity\Style\Style;
|
||||||
|
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
|
||||||
|
|
||||||
class Row
|
class Row
|
||||||
{
|
{
|
||||||
@ -18,6 +19,11 @@ class Row
|
|||||||
*/
|
*/
|
||||||
protected $style = null;
|
protected $style = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var StyleMerger
|
||||||
|
*/
|
||||||
|
protected $styleMerger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Row constructor.
|
* Row constructor.
|
||||||
* @param array $cells
|
* @param array $cells
|
||||||
@ -28,6 +34,8 @@ class Row
|
|||||||
$this
|
$this
|
||||||
->setCells($cells)
|
->setCells($cells)
|
||||||
->setStyle($style);
|
->setStyle($style);
|
||||||
|
|
||||||
|
$this->styleMerger = new StyleMerger();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,6 +64,9 @@ class Row
|
|||||||
*/
|
*/
|
||||||
public function getStyle()
|
public function getStyle()
|
||||||
{
|
{
|
||||||
|
if (!isset($this->style)) {
|
||||||
|
$this->setStyle(new Style());
|
||||||
|
}
|
||||||
return $this->style;
|
return $this->style;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,12 +80,38 @@ class Row
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Style $style|null
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function applyStyle(Style $style = null)
|
||||||
|
{
|
||||||
|
if ($style === null) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
$merged = $this->styleMerger->merge($this->getStyle(), $style);
|
||||||
|
$this->setStyle($merged);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Cell $cell
|
* @param Cell $cell
|
||||||
|
* @return Row
|
||||||
*/
|
*/
|
||||||
public function addCell(Cell $cell)
|
public function addCell(Cell $cell)
|
||||||
{
|
{
|
||||||
$this->cells[] = $cell;
|
$this->cells[] = $cell;
|
||||||
return $this;
|
return $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 count($this->cells) === 0 || (count($this->cells) === 1 && $this->cells[0]->isEmpty());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,17 +47,17 @@ class StyleManager implements StyleManagerInterface
|
|||||||
return $this->styleRegistry->registerStyle($style);
|
return $this->styleRegistry->registerStyle($style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,24 +70,18 @@ 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)
|
||||||
{
|
{
|
||||||
// if the "wrap text" option is already set, no-op
|
// if the "wrap text" option is already set, no-op
|
||||||
if ($style->hasSetWrapText()) {
|
if ($cell->getStyle()->hasSetWrapText()) {
|
||||||
return $style;
|
return $cell->getStyle();
|
||||||
}
|
}
|
||||||
|
if ($cell->isString() && strpos($cell->getValue(), "\n") !== false) {
|
||||||
foreach ($dataRow as $cell) {
|
$cell->getStyle()->setShouldWrapText();
|
||||||
if (is_string($cell) && strpos($cell, "\n") !== false) {
|
|
||||||
$style->setShouldWrapText();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return $cell->getStyle();
|
||||||
return $style;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface StyleHManagernterface
|
* Interface StyleHManagernterface
|
||||||
*
|
*
|
||||||
@ -24,9 +26,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);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ use Box\Spout\Writer\Common\Entity\Worksheet;
|
|||||||
use Box\Spout\Writer\Exception\SheetNotFoundException;
|
use Box\Spout\Writer\Exception\SheetNotFoundException;
|
||||||
use Box\Spout\Writer\Exception\WriterException;
|
use Box\Spout\Writer\Exception\WriterException;
|
||||||
use Box\Spout\Writer\Common\Creator\EntityFactory;
|
use Box\Spout\Writer\Common\Creator\EntityFactory;
|
||||||
use Box\Spout\Writer\Common\Entity\Style\Style;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class WorkbookManagerAbstract
|
* Class WorkbookManagerAbstract
|
||||||
@ -192,18 +191,16 @@ 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.
|
|
||||||
* @return void
|
* @return void
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
public function addRowToCurrentWorksheet($dataRow, Style $style)
|
public function addRowToCurrentWorksheet(Row $row)
|
||||||
{
|
{
|
||||||
$currentWorksheet = $this->getCurrentWorksheet();
|
$currentWorksheet = $this->getCurrentWorksheet();
|
||||||
$hasReachedMaxRows = $this->hasCurrentWorkseetReachedMaxRows();
|
$hasReachedMaxRows = $this->hasCurrentWorkseetReachedMaxRows();
|
||||||
@ -214,12 +211,12 @@ 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->addRowWithStyleToWorksheet($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->addRowWithStyleToWorksheet($currentWorksheet, $row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,19 +235,16 @@ abstract class WorkbookManagerAbstract implements WorkbookManagerInterface
|
|||||||
* @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 array $dataRow Array containing data to be written. Cannot be empty.
|
||||||
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
|
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
|
||||||
* @param Style $style Style to be applied to the row.
|
|
||||||
* @return void
|
* @return void
|
||||||
* @throws WriterException If unable to write data
|
* @throws WriterException If unable to write data
|
||||||
*/
|
*/
|
||||||
private function addRowWithStyleToWorksheet(Worksheet $worksheet, $dataRow, Style $style)
|
private function addRowWithStyleToWorksheet(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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,11 +4,12 @@ namespace Box\Spout\Writer\Common\Manager;
|
|||||||
|
|
||||||
use Box\Spout\Common\Exception\IOException;
|
use Box\Spout\Common\Exception\IOException;
|
||||||
use Box\Spout\Writer\Common\Entity\Sheet;
|
use Box\Spout\Writer\Common\Entity\Sheet;
|
||||||
|
use Box\Spout\Writer\Common\Entity\Row;
|
||||||
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\Sheet;
|
||||||
use Box\Spout\Writer\Exception\SheetNotFoundException;
|
use Box\Spout\Writer\Exception\SheetNotFoundException;
|
||||||
use Box\Spout\Writer\Exception\WriterException;
|
use Box\Spout\Writer\Exception\WriterException;
|
||||||
use Box\Spout\Writer\Common\Entity\Style\Style;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface WorkbookManagerInterface
|
* Interface WorkbookManagerInterface
|
||||||
@ -55,19 +56,16 @@ 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.
|
|
||||||
* @return void
|
* @return void
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
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.
|
||||||
* All the necessary files are written to disk and zipped together to create the final file.
|
* All the necessary files are written to disk and zipped together to create the final file.
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace Box\Spout\Writer\Common\Manager;
|
namespace Box\Spout\Writer\Common\Manager;
|
||||||
|
|
||||||
|
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\Entity\Style\Style;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface WorksheetManagerInterface
|
* Interface WorksheetManagerInterface
|
||||||
@ -14,17 +14,15 @@ use Box\Spout\Writer\Common\Entity\Style\Style;
|
|||||||
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.
|
|
||||||
* @return void
|
* @return void
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
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
|
||||||
|
@ -48,20 +48,22 @@ class InternalFactory implements InternalFactoryInterface
|
|||||||
$fileSystemHelper->createBaseFilesAndFolders();
|
$fileSystemHelper->createBaseFilesAndFolders();
|
||||||
|
|
||||||
$styleManager = $this->createStyleManager($optionsManager);
|
$styleManager = $this->createStyleManager($optionsManager);
|
||||||
$worksheetManager = $this->createWorksheetManager();
|
$worksheetManager = $this->createWorksheetManager($styleManager);
|
||||||
|
|
||||||
return new WorkbookManager($workbook, $optionsManager, $worksheetManager, $styleManager, $fileSystemHelper, $this->entityFactory);
|
return new WorkbookManager($workbook, $optionsManager, $worksheetManager, $styleManager, $fileSystemHelper, $this->entityFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param StyleManager $styleManager
|
||||||
* @return WorksheetManager
|
* @return WorksheetManager
|
||||||
*/
|
*/
|
||||||
private function createWorksheetManager()
|
private function createWorksheetManager(StyleManager $styleManager)
|
||||||
{
|
{
|
||||||
$stringsEscaper = $this->createStringsEscaper();
|
$stringsEscaper = $this->createStringsEscaper();
|
||||||
$stringsHelper = $this->createStringHelper();
|
$stringsHelper = $this->createStringHelper();
|
||||||
|
|
||||||
return new WorksheetManager($stringsEscaper, $stringsHelper);
|
|
||||||
|
return new WorksheetManager($styleManager, $stringsEscaper, $stringsHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,9 +6,9 @@ use Box\Spout\Common\Exception\InvalidArgumentException;
|
|||||||
use Box\Spout\Common\Exception\IOException;
|
use Box\Spout\Common\Exception\IOException;
|
||||||
use Box\Spout\Common\Helper\StringHelper;
|
use Box\Spout\Common\Helper\StringHelper;
|
||||||
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\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\Common\Entity\Style\Style;
|
|
||||||
use Box\Spout\Writer\ODS\Manager\Style\StyleManager;
|
use Box\Spout\Writer\ODS\Manager\Style\StyleManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,6 +25,9 @@ class WorksheetManager implements WorksheetManagerInterface
|
|||||||
/** @var StringHelper String helper */
|
/** @var StringHelper String helper */
|
||||||
private $stringHelper;
|
private $stringHelper;
|
||||||
|
|
||||||
|
/** @var StyleManager Manages styles */
|
||||||
|
private $styleManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WorksheetManager constructor.
|
* WorksheetManager constructor.
|
||||||
*
|
*
|
||||||
@ -32,11 +35,13 @@ class WorksheetManager implements WorksheetManagerInterface
|
|||||||
* @param StringHelper $stringHelper
|
* @param StringHelper $stringHelper
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
StyleManager $styleManager,
|
||||||
\Box\Spout\Common\Escaper\ODS $stringsEscaper,
|
\Box\Spout\Common\Escaper\ODS $stringsEscaper,
|
||||||
StringHelper $stringHelper)
|
StringHelper $stringHelper)
|
||||||
{
|
{
|
||||||
$this->stringsEscaper = $stringsEscaper;
|
$this->stringsEscaper = $stringsEscaper;
|
||||||
$this->stringHelper = $stringHelper;
|
$this->stringHelper = $stringHelper;
|
||||||
|
$this->styleManager = $styleManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,24 +92,21 @@ 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.
|
|
||||||
* @return void
|
* @return void
|
||||||
|
*
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
public function addRow(Worksheet $worksheet, $dataRow, $rowStyle)
|
public function addRow(Worksheet $worksheet, Row $row)
|
||||||
{
|
{
|
||||||
// $dataRow can be an associative array. We need to transform
|
|
||||||
// it into a regular array, as we'll use the numeric indexes.
|
|
||||||
$dataRowWithNumericIndexes = array_values($dataRow);
|
|
||||||
|
|
||||||
$styleIndex = ($rowStyle->getId() + 1); // 1-based
|
$cells = $row->getCells();
|
||||||
$cellsCount = count($dataRow);
|
$cellsCount = count($cells);
|
||||||
|
|
||||||
$data = '<table:table-row table:style-name="ro1">';
|
$data = '<table:table-row table:style-name="ro1">';
|
||||||
|
|
||||||
@ -112,15 +114,22 @@ class WorksheetManager implements WorksheetManagerInterface
|
|||||||
$nextCellIndex = 1;
|
$nextCellIndex = 1;
|
||||||
|
|
||||||
for ($i = 0; $i < $cellsCount; $i++) {
|
for ($i = 0; $i < $cellsCount; $i++) {
|
||||||
$currentCellValue = $dataRowWithNumericIndexes[$currentCellIndex];
|
|
||||||
|
|
||||||
// Using isset here because it is way faster than array_key_exists...
|
/** @var Cell $cell */
|
||||||
if (!isset($dataRowWithNumericIndexes[$nextCellIndex]) ||
|
$cell = $row->getCells()[$currentCellIndex];
|
||||||
$currentCellValue !== $dataRowWithNumericIndexes[$nextCellIndex]) {
|
/** @var Cell|null $nextCell */
|
||||||
|
$nextCell = isset($cells[$nextCellIndex]) ? $cells[$nextCellIndex] : null;
|
||||||
|
|
||||||
|
if (null === $nextCell || $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
|
||||||
|
|
||||||
$numTimesValueRepeated = ($nextCellIndex - $currentCellIndex);
|
$numTimesValueRepeated = ($nextCellIndex - $currentCellIndex);
|
||||||
$data .= $this->getCellXML($currentCellValue, $styleIndex, $numTimesValueRepeated);
|
$data .= $this->getCellXML($cell, $styleIndex, $numTimesValueRepeated);
|
||||||
|
|
||||||
$currentCellIndex = $nextCellIndex;
|
$currentCellIndex = $nextCellIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,13 +151,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
|
||||||
* @return string The cell XML content
|
* @return string The cell XML content
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
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 . '"';
|
||||||
|
|
||||||
@ -156,13 +165,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 = new Cell($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">';
|
||||||
|
|
||||||
|
@ -7,7 +7,9 @@ use Box\Spout\Common\Exception\IOException;
|
|||||||
use Box\Spout\Common\Exception\SpoutException;
|
use Box\Spout\Common\Exception\SpoutException;
|
||||||
use Box\Spout\Common\Helper\FileSystemHelper;
|
use Box\Spout\Common\Helper\FileSystemHelper;
|
||||||
use Box\Spout\Common\Helper\GlobalFunctionsHelper;
|
use Box\Spout\Common\Helper\GlobalFunctionsHelper;
|
||||||
|
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\Manager\OptionsManagerInterface;
|
use Box\Spout\Writer\Common\Manager\OptionsManagerInterface;
|
||||||
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
|
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
|
||||||
@ -40,9 +42,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;
|
||||||
|
|
||||||
@ -59,8 +58,6 @@ abstract class WriterAbstract implements WriterInterface
|
|||||||
$this->optionsManager = $optionsManager;
|
$this->optionsManager = $optionsManager;
|
||||||
$this->styleMerger = $styleMerger;
|
$this->styleMerger = $styleMerger;
|
||||||
$this->globalFunctionsHelper = $globalFunctionsHelper;
|
$this->globalFunctionsHelper = $globalFunctionsHelper;
|
||||||
|
|
||||||
$this->resetRowStyleToDefault();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,14 +69,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.
|
||||||
@ -99,7 +94,6 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,27 +193,37 @@ abstract class WriterAbstract implements WriterInterface
|
|||||||
/**
|
/**
|
||||||
* Write given data to the output. New data will be appended to end of stream.
|
* Write given data to the output. New data will be appended to end of stream.
|
||||||
*
|
*
|
||||||
* @param array $dataRow Array containing data to be streamed.
|
* @param array|\Box\Spout\Writer\Common\Entity\Row $row The row to be appended to the stream
|
||||||
* If empty, no data is added (i.e. not even as a blank row)
|
* @return WriterInterface
|
||||||
* Example: $dataRow = ['data1', 1234, null, '', 'data5', false];
|
* @internal param array $row Array containing data to be streamed.
|
||||||
|
* Example $row= ['data1', 1234, null, '', 'data5'];
|
||||||
|
* @internal param \Box\Spout\Writer\Common\Entity\Row $row A Row object with cells and styles
|
||||||
|
* Example $row = (new Row())->addCell('data1');
|
||||||
|
*
|
||||||
|
* @throws SpoutException If anything else goes wrong while writing data
|
||||||
|
* @throws WriterNotOpenedException If this function is called before opening the writer
|
||||||
|
*
|
||||||
* @api
|
* @api
|
||||||
* @return WriterAbstract
|
|
||||||
* @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
|
|
||||||
*/
|
*/
|
||||||
public function addRow(array $dataRow)
|
public function addRow($row)
|
||||||
{
|
{
|
||||||
|
if (!is_array($row) && !$row instanceof Row) {
|
||||||
|
throw new InvalidArgumentException('addRow accepts an array with scalar values or a Row object');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($row) && !empty($row)) {
|
||||||
|
$row = $this->createRowFromArray($row, null);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->isWriterOpened) {
|
if ($this->isWriterOpened) {
|
||||||
// empty $dataRow should not add an empty line
|
if (!empty($row)) {
|
||||||
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.
|
||||||
$this->closeAndAttemptToCleanupAllFiles();
|
$this->closeAndAttemptToCleanupAllFiles();
|
||||||
|
|
||||||
// re-throw the exception to alert developers of the error
|
// re-throw the exception to alert developers of the error
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
@ -227,35 +231,72 @@ abstract class WriterAbstract implements WriterInterface
|
|||||||
} else {
|
} else {
|
||||||
throw new WriterNotOpenedException('The writer needs to be opened before adding row.');
|
throw new WriterNotOpenedException('The writer needs to be opened before adding row.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
public function withRow(\Closure $callback)
|
||||||
|
{
|
||||||
|
return $this->addRow($callback(new Row()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write given data to the output and apply the given style.
|
* Write given data to the output and apply the given style.
|
||||||
* @see addRow
|
* @see addRow
|
||||||
*
|
*
|
||||||
* @api
|
* @param array|\Box\Spout\Writer\Common\Entity\Row $row The row to be appended to the stream
|
||||||
* @param array $dataRow Array of array containing data to be streamed.
|
|
||||||
* @param Style $style Style to be applied to the row.
|
* @param Style $style Style to be applied to the row.
|
||||||
* @return WriterAbstract
|
* @return WriterInterface
|
||||||
* @throws \Box\Spout\Common\Exception\InvalidArgumentException If the input param is not valid
|
* @internal param array $row Array containing data to be streamed.
|
||||||
* @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If this function is called before opening the writer
|
* Example $row= ['data1', 1234, null, '', 'data5'];
|
||||||
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
|
* @internal param \Box\Spout\Writer\Common\Entity\Row $row A Row object with cells and styles
|
||||||
|
* Example $row = (new Row())->addCell('data1');
|
||||||
|
* @api
|
||||||
|
* @throws InvalidArgumentException If the input param is not valid
|
||||||
*/
|
*/
|
||||||
public function addRowWithStyle(array $dataRow, $style)
|
public function addRowWithStyle($row, $style)
|
||||||
{
|
{
|
||||||
|
if (!is_array($row) && !$row instanceof Row) {
|
||||||
|
throw new InvalidArgumentException('addRowWithStyle accepts an array with scalar values or a Row object');
|
||||||
|
}
|
||||||
|
|
||||||
if (!$style instanceof Style) {
|
if (!$style instanceof Style) {
|
||||||
throw new InvalidArgumentException('The "$style" argument must be a Style instance and cannot be NULL.');
|
throw new InvalidArgumentException('The "$style" argument must be a Style instance and cannot be NULL.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setRowStyle($style);
|
if (is_array($row)) {
|
||||||
$this->addRow($dataRow);
|
$row = $this->createRowFromArray($row, $style);
|
||||||
$this->resetRowStyleToDefault();
|
}
|
||||||
|
|
||||||
|
$this->addRow($row);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $dataRows
|
||||||
|
* @param Style|null $style
|
||||||
|
* @return Row
|
||||||
|
*/
|
||||||
|
protected function createRowFromArray(array $dataRows, Style $style = null)
|
||||||
|
{
|
||||||
|
$row = (new Row())->setCells(array_map(function ($value) {
|
||||||
|
if ($value instanceof Cell) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
return new Cell($value);
|
||||||
|
}, $dataRows));
|
||||||
|
|
||||||
|
if ($style !== null) {
|
||||||
|
$row->setStyle($style);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $row;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write given data to the output. New data will be appended to end of stream.
|
* Write given data to the output. New data will be appended to end of stream.
|
||||||
*
|
*
|
||||||
@ -275,15 +316,13 @@ abstract class WriterAbstract implements WriterInterface
|
|||||||
{
|
{
|
||||||
if (!empty($dataRows)) {
|
if (!empty($dataRows)) {
|
||||||
$firstRow = reset($dataRows);
|
$firstRow = reset($dataRows);
|
||||||
if (!is_array($firstRow)) {
|
if (!is_array($firstRow) && !$firstRow instanceof Row) {
|
||||||
throw new InvalidArgumentException('The input should be an array of arrays');
|
throw new InvalidArgumentException('The input should be an array of arrays or row objects');
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($dataRows as $dataRow) {
|
foreach ($dataRows as $dataRow) {
|
||||||
$this->addRow($dataRow);
|
$this->addRow($dataRow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,35 +344,32 @@ abstract class WriterAbstract implements WriterInterface
|
|||||||
throw new InvalidArgumentException('The "$style" argument must be a Style instance and cannot be NULL.');
|
throw new InvalidArgumentException('The "$style" argument must be a Style instance and cannot be NULL.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setRowStyle($style);
|
$this->addRows(array_map(function ($row) use ($style) {
|
||||||
$this->addRows($dataRows);
|
if (is_array($row)) {
|
||||||
$this->resetRowStyleToDefault();
|
return $this->createRowFromArray($row, $style);
|
||||||
|
} elseif ($row instanceof Row) {
|
||||||
|
return $row;
|
||||||
|
} else {
|
||||||
|
throw new InvalidArgumentException();
|
||||||
|
}
|
||||||
|
}, $dataRows));
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the style to be applied to the next written rows
|
* @param Row $row
|
||||||
* until it is changed or reset.
|
* @return $this
|
||||||
*
|
|
||||||
* @param Style $style
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function setRowStyle($style)
|
private function applyDefaultRowStyle(Row $row)
|
||||||
{
|
{
|
||||||
// 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 (null === $defaultRowStyle) {
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
/**
|
$merged = $this->styleMerger->merge($row->getStyle(), $defaultRowStyle);
|
||||||
* Resets the style to be applied to the next written rows.
|
$row->setStyle($merged);
|
||||||
*
|
return $this;
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function resetRowStyleToDefault()
|
|
||||||
{
|
|
||||||
$this->rowStyle = $this->optionsManager->getOption(Options::DEFAULT_ROW_STYLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,26 +34,38 @@ interface WriterInterface
|
|||||||
/**
|
/**
|
||||||
* Write given data to the output. New data will be appended to end of stream.
|
* Write given data to the output. New data will be appended to end of stream.
|
||||||
*
|
*
|
||||||
* @param array $dataRow Array containing data to be streamed.
|
* @param array|\Box\Spout\Writer\Common\Entity\Row $row The row to be appended to the stream
|
||||||
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
|
|
||||||
* @return WriterInterface
|
* @return WriterInterface
|
||||||
* @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If the writer has not been opened yetthe writer
|
* @internal param array $row Array containing data to be streamed.
|
||||||
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
|
* Example $row= ['data1', 1234, null, '', 'data5'];
|
||||||
|
* @internal param \Box\Spout\Writer\Common\Entity\Row $row A Row object with cells and styles
|
||||||
|
* Example $row = (new Row())->addCell('data1');
|
||||||
*/
|
*/
|
||||||
public function addRow(array $dataRow);
|
public function addRow($row);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write given data to the output and apply the given style.
|
* Write given data to the output and apply the given style.
|
||||||
* @see addRow
|
* @see addRow
|
||||||
*
|
*
|
||||||
* @param array $dataRow Array of array containing data to be streamed.
|
* @param array|\Box\Spout\Writer\Common\Entity\Row $row The row to be appended to the stream
|
||||||
* @param Style $style Style to be applied to the row.
|
* @param Style $style Style to be applied to the row.
|
||||||
* @return WriterInterface
|
* @return WriterInterface
|
||||||
* @throws \Box\Spout\Common\Exception\InvalidArgumentException If the input param is not valid
|
* @internal param array $row Array containing data to be streamed.
|
||||||
* @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If this function is called before opening the writer
|
* Example $row= ['data1', 1234, null, '', 'data5'];
|
||||||
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
|
* @internal param \Box\Spout\Writer\Common\Entity\Row $row A Row object with cells and styles
|
||||||
|
* Example $row = (new Row())->addCell('data1');
|
||||||
*/
|
*/
|
||||||
public function addRowWithStyle(array $dataRow, $style);
|
public function addRowWithStyle($row, $style);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write given data to the output with a closure funtion. New data will be appended to end of stream.
|
||||||
|
*
|
||||||
|
* @param \Closure $callback A callback returning a Row object. A new Row object is injected into the callback.
|
||||||
|
* @return WriterInterface
|
||||||
|
* @internal param \Closure $callback
|
||||||
|
* Example withRow(function(Row $row) { return $row->addCell('data1'); })
|
||||||
|
*/
|
||||||
|
public function withRow(\Closure $callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write given data to the output. New data will be appended to end of stream.
|
* Write given data to the output. New data will be appended to end of stream.
|
||||||
|
@ -6,6 +6,7 @@ use Box\Spout\Common\Helper\GlobalFunctionsHelper;
|
|||||||
use Box\Spout\Writer\Common\Entity\Sheet;
|
use Box\Spout\Writer\Common\Entity\Sheet;
|
||||||
use Box\Spout\Writer\Common\Manager\OptionsManagerInterface;
|
use Box\Spout\Writer\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\Worksheet;
|
use Box\Spout\Writer\Common\Entity\Worksheet;
|
||||||
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
|
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
|
||||||
use Box\Spout\Writer\Exception\SheetNotFoundException;
|
use Box\Spout\Writer\Exception\SheetNotFoundException;
|
||||||
@ -159,17 +160,15 @@ 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.
|
|
||||||
* @return void
|
* @return void
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
protected function addRowToWriter(array $dataRow, $style)
|
protected function addRowToWriter(Row $row)
|
||||||
{
|
{
|
||||||
$this->throwIfWorkbookIsNotAvailable();
|
$this->throwIfWorkbookIsNotAvailable();
|
||||||
$this->workbookManager->addRowToCurrentWorksheet($dataRow, $style);
|
$this->workbookManager->addRowToCurrentWorksheet($row);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,9 +9,9 @@ use Box\Spout\Writer\Common\Helper\CellHelper;
|
|||||||
use Box\Spout\Writer\Common\Manager\OptionsManagerInterface;
|
use Box\Spout\Writer\Common\Manager\OptionsManagerInterface;
|
||||||
use Box\Spout\Writer\Common\Entity\Options;
|
use Box\Spout\Writer\Common\Entity\Options;
|
||||||
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\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\Common\Entity\Style\Style;
|
|
||||||
use Box\Spout\Writer\XLSX\Manager\Style\StyleManager;
|
use Box\Spout\Writer\XLSX\Manager\Style\StyleManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,60 +115,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.
|
|
||||||
* @return void
|
* @return void
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
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.
|
|
||||||
* @return void
|
* @return void
|
||||||
|
*
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
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) {
|
/** @var Cell $cell */
|
||||||
$rowXML .= $this->getCellXML($rowIndex, $cellNumber, $cellValue, $style->getId());
|
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++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,24 +172,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
|
||||||
* @return string
|
* @return string
|
||||||
* @throws InvalidArgumentException If the given value cannot be processed
|
* @throws InvalidArgumentException If the given value cannot be processed
|
||||||
*/
|
*/
|
||||||
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 = new Cell($cellValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($cell->isString()) {
|
if ($cell->isString()) {
|
||||||
$cellXML .= $this->getCellXMLFragmentForNonEmptyString($cell->getValue());
|
$cellXML .= $this->getCellXMLFragmentForNonEmptyString($cell->getValue());
|
||||||
} else if ($cell->isBoolean()) {
|
} else if ($cell->isBoolean()) {
|
||||||
|
@ -29,12 +29,6 @@ class RowTest extends TestCase
|
|||||||
$this->assertInstanceOf('Box\Spout\Writer\Common\Entity\Row', new Row([$this->cellMock()->getMock()]));
|
$this->assertInstanceOf('Box\Spout\Writer\Common\Entity\Row', new Row([$this->cellMock()->getMock()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInvalidInstanceCellType()
|
|
||||||
{
|
|
||||||
$this->expectException('TypeError');
|
|
||||||
$this->assertInstanceOf('Box\Spout\Writer\Common\Entity\Row', new Row(['string']));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testSetCells()
|
public function testSetCells()
|
||||||
{
|
{
|
||||||
$o = new Row();
|
$o = new Row();
|
||||||
|
@ -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
|
||||||
@ -31,7 +32,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());
|
||||||
}
|
}
|
||||||
@ -45,7 +46,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());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user