See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401]
1 <?php 2 3 namespace Box\Spout\Writer\XLSX\Manager\Style; 4 5 use Box\Spout\Common\Entity\Style\Style; 6 7 /** 8 * Class StyleRegistry 9 * Registry for all used styles 10 */ 11 class StyleRegistry extends \Box\Spout\Writer\Common\Manager\Style\StyleRegistry 12 { 13 /** 14 * @see https://msdn.microsoft.com/en-us/library/ff529597(v=office.12).aspx 15 * @var array Mapping between built-in format and the associated numFmtId 16 */ 17 protected static $builtinNumFormatToIdMapping = [ 18 'General' => 0, 19 '0' => 1, 20 '0.00' => 2, 21 '#,##0' => 3, 22 '#,##0.00' => 4, 23 '$#,##0,\-$#,##0' => 5, 24 '$#,##0,[Red]\-$#,##0' => 6, 25 '$#,##0.00,\-$#,##0.00' => 7, 26 '$#,##0.00,[Red]\-$#,##0.00' => 8, 27 '0%' => 9, 28 '0.00%' => 10, 29 '0.00E+00' => 11, 30 '# ?/?' => 12, 31 '# ??/??' => 13, 32 'mm-dd-yy' => 14, 33 'd-mmm-yy' => 15, 34 'd-mmm' => 16, 35 'mmm-yy' => 17, 36 'h:mm AM/PM' => 18, 37 'h:mm:ss AM/PM' => 19, 38 'h:mm' => 20, 39 'h:mm:ss' => 21, 40 'm/d/yy h:mm' => 22, 41 42 '#,##0 ,(#,##0)' => 37, 43 '#,##0 ,[Red](#,##0)' => 38, 44 '#,##0.00,(#,##0.00)' => 39, 45 '#,##0.00,[Red](#,##0.00)' => 40, 46 47 '_("$"* #,##0.00_),_("$"* \(#,##0.00\),_("$"* "-"??_),_(@_)' => 44, 48 'mm:ss' => 45, 49 '[h]:mm:ss' => 46, 50 'mm:ss.0' => 47, 51 52 '##0.0E+0' => 48, 53 '@' => 49, 54 55 '[$-404]e/m/d' => 27, 56 'm/d/yy' => 30, 57 't0' => 59, 58 't0.00' => 60, 59 't#,##0' => 61, 60 't#,##0.00' => 62, 61 't0%' => 67, 62 't0.00%' => 68, 63 't# ?/?' => 69, 64 't# ??/??' => 70, 65 ]; 66 67 /** 68 * @var array 69 */ 70 protected $registeredFormats = []; 71 72 /** 73 * @var array [STYLE_ID] => [FORMAT_ID] maps a style to a format declaration 74 */ 75 protected $styleIdToFormatsMappingTable = []; 76 77 /** 78 * If the numFmtId is lower than 0xA4 (164 in decimal) 79 * then it's a built-in number format. 80 * Since Excel is the dominant vendor - we play along here 81 * 82 * @var int The fill index counter for custom fills. 83 */ 84 protected $formatIndex = 164; 85 86 /** 87 * @var array 88 */ 89 protected $registeredFills = []; 90 91 /** 92 * @var array [STYLE_ID] => [FILL_ID] maps a style to a fill declaration 93 */ 94 protected $styleIdToFillMappingTable = []; 95 96 /** 97 * Excel preserves two default fills with index 0 and 1 98 * Since Excel is the dominant vendor - we play along here 99 * 100 * @var int The fill index counter for custom fills. 101 */ 102 protected $fillIndex = 2; 103 104 /** 105 * @var array 106 */ 107 protected $registeredBorders = []; 108 109 /** 110 * @var array [STYLE_ID] => [BORDER_ID] maps a style to a border declaration 111 */ 112 protected $styleIdToBorderMappingTable = []; 113 114 /** 115 * XLSX specific operations on the registered styles 116 * 117 * @param Style $style 118 * @return Style 119 */ 120 public function registerStyle(Style $style) 121 { 122 if ($style->isRegistered()) { 123 return $style; 124 } 125 126 $registeredStyle = parent::registerStyle($style); 127 $this->registerFill($registeredStyle); 128 $this->registerFormat($registeredStyle); 129 $this->registerBorder($registeredStyle); 130 131 return $registeredStyle; 132 } 133 134 /** 135 * Register a format definition 136 * 137 * @param Style $style 138 */ 139 protected function registerFormat(Style $style) 140 { 141 $styleId = $style->getId(); 142 143 $format = $style->getFormat(); 144 if ($format) { 145 $isFormatRegistered = isset($this->registeredFormats[$format]); 146 147 // We need to track the already registered format definitions 148 if ($isFormatRegistered) { 149 $registeredStyleId = $this->registeredFormats[$format]; 150 $registeredFormatId = $this->styleIdToFormatsMappingTable[$registeredStyleId]; 151 $this->styleIdToFormatsMappingTable[$styleId] = $registeredFormatId; 152 } else { 153 $this->registeredFormats[$format] = $styleId; 154 155 $id = self::$builtinNumFormatToIdMapping[$format] ?? $this->formatIndex++; 156 $this->styleIdToFormatsMappingTable[$styleId] = $id; 157 } 158 } else { 159 // The formatId maps a style to a format declaration 160 // When there is no format definition - we default to 0 ( General ) 161 $this->styleIdToFormatsMappingTable[$styleId] = 0; 162 } 163 } 164 165 /** 166 * @param int $styleId 167 * @return int|null Format ID associated to the given style ID 168 */ 169 public function getFormatIdForStyleId($styleId) 170 { 171 return $this->styleIdToFormatsMappingTable[$styleId] ?? null; 172 } 173 174 /** 175 * Register a fill definition 176 * 177 * @param Style $style 178 */ 179 private function registerFill(Style $style) 180 { 181 $styleId = $style->getId(); 182 183 // Currently - only solid backgrounds are supported 184 // so $backgroundColor is a scalar value (RGB Color) 185 $backgroundColor = $style->getBackgroundColor(); 186 187 if ($backgroundColor) { 188 $isBackgroundColorRegistered = isset($this->registeredFills[$backgroundColor]); 189 190 // We need to track the already registered background definitions 191 if ($isBackgroundColorRegistered) { 192 $registeredStyleId = $this->registeredFills[$backgroundColor]; 193 $registeredFillId = $this->styleIdToFillMappingTable[$registeredStyleId]; 194 $this->styleIdToFillMappingTable[$styleId] = $registeredFillId; 195 } else { 196 $this->registeredFills[$backgroundColor] = $styleId; 197 $this->styleIdToFillMappingTable[$styleId] = $this->fillIndex++; 198 } 199 } else { 200 // The fillId maps a style to a fill declaration 201 // When there is no background color definition - we default to 0 202 $this->styleIdToFillMappingTable[$styleId] = 0; 203 } 204 } 205 206 /** 207 * @param int $styleId 208 * @return int|null Fill ID associated to the given style ID 209 */ 210 public function getFillIdForStyleId($styleId) 211 { 212 return (isset($this->styleIdToFillMappingTable[$styleId])) ? 213 $this->styleIdToFillMappingTable[$styleId] : 214 null; 215 } 216 217 /** 218 * Register a border definition 219 * 220 * @param Style $style 221 */ 222 private function registerBorder(Style $style) 223 { 224 $styleId = $style->getId(); 225 226 if ($style->shouldApplyBorder()) { 227 $border = $style->getBorder(); 228 $serializedBorder = \serialize($border); 229 230 $isBorderAlreadyRegistered = isset($this->registeredBorders[$serializedBorder]); 231 232 if ($isBorderAlreadyRegistered) { 233 $registeredStyleId = $this->registeredBorders[$serializedBorder]; 234 $registeredBorderId = $this->styleIdToBorderMappingTable[$registeredStyleId]; 235 $this->styleIdToBorderMappingTable[$styleId] = $registeredBorderId; 236 } else { 237 $this->registeredBorders[$serializedBorder] = $styleId; 238 $this->styleIdToBorderMappingTable[$styleId] = \count($this->registeredBorders); 239 } 240 } else { 241 // If no border should be applied - the mapping is the default border: 0 242 $this->styleIdToBorderMappingTable[$styleId] = 0; 243 } 244 } 245 246 /** 247 * @param int $styleId 248 * @return int|null Fill ID associated to the given style ID 249 */ 250 public function getBorderIdForStyleId($styleId) 251 { 252 return (isset($this->styleIdToBorderMappingTable[$styleId])) ? 253 $this->styleIdToBorderMappingTable[$styleId] : 254 null; 255 } 256 257 /** 258 * @return array 259 */ 260 public function getRegisteredFills() 261 { 262 return $this->registeredFills; 263 } 264 265 /** 266 * @return array 267 */ 268 public function getRegisteredBorders() 269 { 270 return $this->registeredBorders; 271 } 272 273 /** 274 * @return array 275 */ 276 public function getRegisteredFormats() 277 { 278 return $this->registeredFormats; 279 } 280 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body