ODS writer

Added ODS writer
Refactored XLSX writer to abstract some pieces into an abstract multi-sheets writer
Created an abstract style helper
Moved shared components around
This commit is contained in:
Adrien Loison committed 2015-08-28 20:19:45 -07:00
1 parent a8f1fba854
commit 5949cb2442
39 files changed
+2924 -533

No files matched your search

+14 -112
View File
@@ -2,122 +2,20 @@
namespace Box\Spout\Writer\XLSX\Helper;
use Box\Spout\Writer\Common\Helper\AbstractStyleHelper;
use Box\Spout\Writer\Style\Color;
/**
* Class StyleHelper
* This class provides helper functions to manage styles
*
* @package Box\Spout\Writer\XLSX\Helper
*/
class StyleHelper
class StyleHelper extends AbstractStyleHelper
{
/** @var array [SERIALIZED_STYLE] => [STYLE_ID] mapping table, keeping track of the registered styles */
protected $serializedStyleToStyleIdMappingTable = [];
/** @var array [STYLE_ID] => [STYLE] mapping table, keeping track of the registered styles */
protected $styleIdToStyleMappingTable = [];
/**
* @param \Box\Spout\Writer\Style\Style $defaultStyle
*/
public function __construct($defaultStyle)
{
// This ensures that the default style is the first one to be registered
$this->registerStyle($defaultStyle);
}
/**
* Registers the given style as a used style.
* Duplicate styles won't be registered more than once.
*
* @param \Box\Spout\Writer\Style\Style $style The style to be registered
* @return \Box\Spout\Writer\Style\Style The registered style, updated with an internal ID.
*/
public function registerStyle($style)
{
$serializedStyle = $style->serialize();
if (!$this->hasStyleAlreadyBeenRegistered($style)) {
$nextStyleId = count($this->serializedStyleToStyleIdMappingTable);
$style->setId($nextStyleId);
$this->serializedStyleToStyleIdMappingTable[$serializedStyle] = $nextStyleId;
$this->styleIdToStyleMappingTable[$nextStyleId] = $style;
}
return $this->getStyleFromSerializedStyle($serializedStyle);
}
/**
* Returns whether the given style has already been registered.
*
* @param \Box\Spout\Writer\Style\Style $style
* @return bool
*/
protected function hasStyleAlreadyBeenRegistered($style)
{
$serializedStyle = $style->serialize();
return array_key_exists($serializedStyle, $this->serializedStyleToStyleIdMappingTable);
}
/**
* Returns the registered style associated to the given serialization.
*
* @param string $serializedStyle The serialized style from which the actual style should be fetched from
* @return \Box\Spout\Writer\Style\Style
*/
protected function getStyleFromSerializedStyle($serializedStyle)
{
$styleId = $this->serializedStyleToStyleIdMappingTable[$serializedStyle];
return $this->styleIdToStyleMappingTable[$styleId];
}
/**
* Apply additional styles if the given row needs it.
* Typically, set "wrap text" if a cell contains a new line.
*
* @param \Box\Spout\Writer\Style\Style $style The original style
* @param array $dataRow The row the style will be applied to
* @return \Box\Spout\Writer\Style\Style The updated style
*/
public function applyExtraStylesIfNeeded($style, $dataRow)
{
$updatedStyle = $this->applyWrapTextIfCellContainsNewLine($style, $dataRow);
return $updatedStyle;
}
/**
* Set the "wrap text" option if a cell of the given row contains a new line.
*
* @NOTE: There is a bug on the Mac version of Excel (2011 and below) where new lines
* are ignored even when the "wrap text" option is set. This only occurs with
* inline strings (shared strings do work fine).
* A workaround would be to encode "\n" as "_x000D_" but it does not work
* on the Windows version of Excel...
*
* @param \Box\Spout\Writer\Style\Style $style The original style
* @param array $dataRow The row the style will be applied to
* @return \Box\Spout\Writer\Style\Style The eventually updated style
*/
protected function applyWrapTextIfCellContainsNewLine($style, $dataRow)
{
// if the "wrap text" option is already set, no-op
if ($style->shouldWrapText()) {
return $style;
}
foreach ($dataRow as $cell) {
if (is_string($cell) && strpos($cell, "\n") !== false) {
$style->setShouldWrapText();
break;
}
}
return $style;
}
/**
* Returns the content of the "styles.xml" file, given a list of styles.
*
* @return string
*/
public function getStylesXMLFileContent()
@@ -144,6 +42,7 @@ EOD;
/**
* Returns the content of the "<fonts>" section.
*
* @return string
*/
protected function getFontsSectionContent()
@@ -151,11 +50,11 @@ EOD;
$content = ' <fonts count="' . count($this->styleIdToStyleMappingTable) . '">' . PHP_EOL;
/** @var \Box\Spout\Writer\Style\Style $style */
foreach ($this->styleIdToStyleMappingTable as $style) {
foreach ($this->getRegisteredStyles() as $style) {
$content .= ' <font>' . PHP_EOL;
$content .= ' <sz val="' . $style->getFontSize() . '"/>' . PHP_EOL;
$content .= ' <color rgb="' . $style->getFontColor() . '"/>' . PHP_EOL;
$content .= ' <color rgb="' . Color::toARGB($style->getFontColor()) . '"/>' . PHP_EOL;
$content .= ' <name val="' . $style->getFontName() . '"/>' . PHP_EOL;
if ($style->isFontBold()) {
@@ -234,14 +133,17 @@ EOD;
/**
* Returns the content of the "<cellXfs>" section.
*
* @return string
*/
protected function getCellXfsSectionContent()
{
$content = ' <cellXfs count="' . count($this->styleIdToStyleMappingTable) . '">' . PHP_EOL;
$registeredStyles = $this->getRegisteredStyles();
foreach ($this->styleIdToStyleMappingTable as $styleId => $style) {
$content .= ' <xf numFmtId="0" fontId="' . $styleId . '" fillId="0" borderId="0" xfId="0"';
$content = ' <cellXfs count="' . count($registeredStyles) . '">' . PHP_EOL;
foreach ($registeredStyles as $style) {
$content .= ' <xf numFmtId="0" fontId="' . $style->getId() . '" fillId="0" borderId="0" xfId="0"';
if ($style->shouldApplyFont()) {
$content .= ' applyFont="1"';