diff --git a/src/Spout/Common/Entity/Style/Style.php b/src/Spout/Common/Entity/Style/Style.php index 261e9bf..d544007 100644 --- a/src/Spout/Common/Entity/Style/Style.php +++ b/src/Spout/Common/Entity/Style/Style.php @@ -72,6 +72,9 @@ class Style private $hasSetBackgroundColor = false; private $numberFormat; + /** @var bool Whether border properties should be applied */ + private $shouldApplyNumberFormat = false; + /** * @return int|null @@ -117,7 +120,7 @@ class Style */ public function getNumberFormat() { - return $this->numberFormat ?? null; + return $this->numberFormat; } /** @@ -126,6 +129,7 @@ class Style */ public function setNumberFormat(NumberFormat $format) { + $this->shouldApplyNumberFormat = true; $this->numberFormat = $format; return $this; @@ -138,6 +142,13 @@ class Style { return $this->shouldApplyBorder; } + /** + * @return bool + */ + public function shouldApplyNumberFormat() + { + return $this->shouldApplyNumberFormat; + } /** * @return bool diff --git a/src/Spout/Writer/Common/Manager/Style/StyleRegistry.php b/src/Spout/Writer/Common/Manager/Style/StyleRegistry.php index d33b3f2..d2f5bc3 100644 --- a/src/Spout/Writer/Common/Manager/Style/StyleRegistry.php +++ b/src/Spout/Writer/Common/Manager/Style/StyleRegistry.php @@ -2,7 +2,6 @@ namespace Box\Spout\Writer\Common\Manager\Style; -use Box\Spout\Common\Entity\Style\NumberFormat; use Box\Spout\Common\Entity\Style\Style; /** @@ -38,11 +37,6 @@ class StyleRegistry */ public function registerStyle(Style $style) { - $format = $style->getNumberFormat(); - if (!empty($format)) { - $registeredFormat = $this->registerNumberFormat($format); - $style->setNumberFormat($registeredFormat); - } $serializedStyle = $this->serialize($style); if (!$this->hasStyleAlreadyBeenRegistered($style)) { @@ -56,18 +50,6 @@ class StyleRegistry return $this->getStyleFromSerializedStyle($serializedStyle); } - public function registerNumberFormat(NumberFormat $format) - { - $serializedFormat = $this->serializeFormat($format); - if (!$this->hasFormatAlreadyBeenRegistered($format)) { - $nextFormatId = count($this->serializedNumberFormatToFormatIdMappingTable); - $format->setId($nextFormatId); - - $this->serializedNumberFormatToFormatIdMappingTable[$serializedFormat] = $nextFormatId; - $this->numberFormats[$nextFormatId] = $format; - } - return $this->getFormatFromSerializedFormat($serializedFormat); - } /** * Returns whether the given style has already been registered. @@ -83,19 +65,6 @@ class StyleRegistry return isset($this->serializedStyleToStyleIdMappingTable[$serializedStyle]); } - /** - * Returns whether the given number format has already been registered. - * - * @param NumberFormat $format - * @return bool - */ - protected function hasFormatAlreadyBeenRegistered(NumberFormat $format) - { - $serializedFormat = $this->serializeFormat($format); - - // Using isset here because it is way faster than array_key_exists... - return isset($this->serializedNumberFormatToFormatIdMappingTable[$serializedFormat]); - } /** * Returns the registered style associated to the given serialization. @@ -110,19 +79,6 @@ class StyleRegistry return $this->styleIdToStyleMappingTable[$styleId]; } - /** - * Returns the registered number format associated to the given serialization. - * - * @param string $serializedFormat The serialized number format from which the actual format should be fetched from - * @return NumberFormat - */ - protected function getFormatFromSerializedFormat($serializedFormat) - { - $formatId = $this->serializedNumberFormatToFormatIdMappingTable[$serializedFormat]; - - return $this->numberFormats[$formatId]; - } - /** * @return Style[] List of registered styles */ @@ -131,14 +87,6 @@ class StyleRegistry return array_values($this->styleIdToStyleMappingTable); } - /** - * @return NumberFormat[] List of registered number formats - */ - public function getRegisteredNumberFormats() - { - return array_values($this->numberFormats); - } - /** * @param int $styleId * @return Style @@ -168,25 +116,4 @@ class StyleRegistry return $serializedStyle; } - - /** - * Serializes the number format for future comparison with other formats. - * The ID is excluded from the comparison, as we only care about - * actual number format properties. - * - * @param Style $style - * @return string The serialized style - */ - public function serializeFormat(NumberFormat $format) - { - // In order to be able to properly compare style, set static ID value - $currentId = $format->getId(); - $format->setId(0); - - $serializedFormat = serialize($format); - - $format->setId($currentId); - - return $serializedFormat; - } } diff --git a/src/Spout/Writer/XLSX/Manager/Style/StyleManager.php b/src/Spout/Writer/XLSX/Manager/Style/StyleManager.php index 83b26a9..f8365c9 100644 --- a/src/Spout/Writer/XLSX/Manager/Style/StyleManager.php +++ b/src/Spout/Writer/XLSX/Manager/Style/StyleManager.php @@ -3,6 +3,7 @@ namespace Box\Spout\Writer\XLSX\Manager\Style; use Box\Spout\Common\Entity\Style\Color; +use Box\Spout\Common\Entity\Style\NumberFormat; use Box\Spout\Common\Entity\Style\Style; use Box\Spout\Writer\XLSX\Helper\BorderHelper; @@ -70,6 +71,7 @@ EOD; } $content = ''; + /** @var NumberFormat $format */ foreach ($registeredFormats as $format) { $content .= ''; diff --git a/src/Spout/Writer/XLSX/Manager/Style/StyleRegistry.php b/src/Spout/Writer/XLSX/Manager/Style/StyleRegistry.php index abd89f1..9b61acd 100644 --- a/src/Spout/Writer/XLSX/Manager/Style/StyleRegistry.php +++ b/src/Spout/Writer/XLSX/Manager/Style/StyleRegistry.php @@ -20,6 +20,10 @@ class StyleRegistry extends \Box\Spout\Writer\Common\Manager\Style\StyleRegistry */ protected $styleIdToFillMappingTable = []; + protected $registeredNumberFormats = []; + + protected $styleIdToNumberFormatMappingTable = []; + /** * Excel preserves two default fills with index 0 and 1 * Since Excel is the dominant vendor - we play along here @@ -49,6 +53,7 @@ class StyleRegistry extends \Box\Spout\Writer\Common\Manager\Style\StyleRegistry $registeredStyle = parent::registerStyle($style); $this->registerFill($registeredStyle); $this->registerBorder($registeredStyle); + $this->registerNumberFormat($registeredStyle); return $registeredStyle; } @@ -96,6 +101,47 @@ class StyleRegistry extends \Box\Spout\Writer\Common\Manager\Style\StyleRegistry null; } + /** + * Register a number format definition + * + * @param Style $style + */ + private function registerNumberFormat(Style $style) + { + $styleId = $style->getId(); + + if ($style->shouldApplyNumberFormat()) { + $format = $style->getNumberFormat(); + $serializedFormat = serialize($format); + $isNumberFormatRegistered = isset($this->registeredNumberFormats[$serializedFormat]); + + // We need to track the already registered background definitions + if ($isNumberFormatRegistered) { + $registeredStyleId = $this->registeredFills[$serializedFormat]; + $registeredFormatId = $this->styleIdToNumberFormatMappingTable[$registeredStyleId]; + $this->styleIdToNumberFormatMappingTable[$styleId] = $registeredFormatId; + } else { + $this->registeredFills[$serializedFormat] = $styleId; + $this->styleIdToNumberFormatMappingTable[$styleId] = $this->fillIndex++; + } + } else { + // The fillId maps a style to a fill declaration + // When there is no background color definition - we default to 0 + $this->styleIdToNumberFormatMappingTable[$styleId] = 0; + } + } + + /** + * @param int $styleId + * @return int|null Number Format ID associated to the given style ID + */ + public function getNumberFormatIdForStyleId($styleId) + { + return (isset($this->styleIdToNumberFormatMappingTable[$styleId])) ? + $this->styleIdToNumberFormatMappingTable[$styleId] : + null; + } + /** * Register a border definition * @@ -151,4 +197,11 @@ class StyleRegistry extends \Box\Spout\Writer\Common\Manager\Style\StyleRegistry { return $this->registeredBorders; } + /** + * @return array + */ + public function getRegisteredNumberFormats() + { + return $this->registeredNumberFormats; + } }