See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx; 4 5 use PhpOffice\PhpSpreadsheet\Style\Alignment; 6 use PhpOffice\PhpSpreadsheet\Style\Border; 7 use PhpOffice\PhpSpreadsheet\Style\Borders; 8 use PhpOffice\PhpSpreadsheet\Style\Color; 9 use PhpOffice\PhpSpreadsheet\Style\Fill; 10 use PhpOffice\PhpSpreadsheet\Style\Font; 11 use PhpOffice\PhpSpreadsheet\Style\Protection; 12 use PhpOffice\PhpSpreadsheet\Style\Style; 13 14 class Styles extends BaseParserClass 15 { 16 /** 17 * Theme instance. 18 * 19 * @var Theme 20 */ 21 private static $theme = null; 22 23 private $styles = []; 24 25 private $cellStyles = []; 26 27 private $styleXml; 28 29 public function __construct(\SimpleXMLElement $styleXml) 30 { 31 $this->styleXml = $styleXml; 32 } 33 34 public function setStyleBaseData(Theme $theme = null, $styles = [], $cellStyles = []) 35 { 36 self::$theme = $theme; 37 $this->styles = $styles; 38 $this->cellStyles = $cellStyles; 39 } 40 41 private static function readFontStyle(Font $fontStyle, \SimpleXMLElement $fontStyleXml) 42 { 43 $fontStyle->setName((string) $fontStyleXml->name['val']); 44 $fontStyle->setSize((float) $fontStyleXml->sz['val']); 45 46 if (isset($fontStyleXml->b)) { 47 $fontStyle->setBold(!isset($fontStyleXml->b['val']) || self::boolean((string) $fontStyleXml->b['val'])); 48 } 49 if (isset($fontStyleXml->i)) { 50 $fontStyle->setItalic(!isset($fontStyleXml->i['val']) || self::boolean((string) $fontStyleXml->i['val'])); 51 } 52 if (isset($fontStyleXml->strike)) { 53 $fontStyle->setStrikethrough(!isset($fontStyleXml->strike['val']) || self::boolean((string) $fontStyleXml->strike['val'])); 54 } 55 $fontStyle->getColor()->setARGB(self::readColor($fontStyleXml->color)); 56 57 if (isset($fontStyleXml->u) && !isset($fontStyleXml->u['val'])) { 58 $fontStyle->setUnderline(Font::UNDERLINE_SINGLE); 59 } elseif (isset($fontStyleXml->u, $fontStyleXml->u['val'])) { 60 $fontStyle->setUnderline((string) $fontStyleXml->u['val']); 61 } 62 63 if (isset($fontStyleXml->vertAlign, $fontStyleXml->vertAlign['val'])) { 64 $verticalAlign = strtolower((string) $fontStyleXml->vertAlign['val']); 65 if ($verticalAlign === 'superscript') { 66 $fontStyle->setSuperscript(true); 67 } 68 if ($verticalAlign === 'subscript') { 69 $fontStyle->setSubscript(true); 70 } 71 } 72 } 73 74 private static function readFillStyle(Fill $fillStyle, \SimpleXMLElement $fillStyleXml) 75 { 76 if ($fillStyleXml->gradientFill) { 77 /** @var \SimpleXMLElement $gradientFill */ 78 $gradientFill = $fillStyleXml->gradientFill[0]; 79 if (!empty($gradientFill['type'])) { 80 $fillStyle->setFillType((string) $gradientFill['type']); 81 } 82 $fillStyle->setRotation((float) ($gradientFill['degree'])); 83 $gradientFill->registerXPathNamespace('sml', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); 84 $fillStyle->getStartColor()->setARGB(self::readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=0]'))->color)); 85 $fillStyle->getEndColor()->setARGB(self::readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=1]'))->color)); 86 } elseif ($fillStyleXml->patternFill) { 87 $patternType = (string) $fillStyleXml->patternFill['patternType'] != '' ? (string) $fillStyleXml->patternFill['patternType'] : 'solid'; 88 $fillStyle->setFillType($patternType); 89 if ($fillStyleXml->patternFill->fgColor) { 90 $fillStyle->getStartColor()->setARGB(self::readColor($fillStyleXml->patternFill->fgColor, true)); 91 } else { 92 $fillStyle->getStartColor()->setARGB('FF000000'); 93 } 94 if ($fillStyleXml->patternFill->bgColor) { 95 $fillStyle->getEndColor()->setARGB(self::readColor($fillStyleXml->patternFill->bgColor, true)); 96 } 97 } 98 } 99 100 private static function readBorderStyle(Borders $borderStyle, \SimpleXMLElement $borderStyleXml) 101 { 102 $diagonalUp = self::boolean((string) $borderStyleXml['diagonalUp']); 103 $diagonalDown = self::boolean((string) $borderStyleXml['diagonalDown']); 104 if (!$diagonalUp && !$diagonalDown) { 105 $borderStyle->setDiagonalDirection(Borders::DIAGONAL_NONE); 106 } elseif ($diagonalUp && !$diagonalDown) { 107 $borderStyle->setDiagonalDirection(Borders::DIAGONAL_UP); 108 } elseif (!$diagonalUp && $diagonalDown) { 109 $borderStyle->setDiagonalDirection(Borders::DIAGONAL_DOWN); 110 } else { 111 $borderStyle->setDiagonalDirection(Borders::DIAGONAL_BOTH); 112 } 113 114 self::readBorder($borderStyle->getLeft(), $borderStyleXml->left); 115 self::readBorder($borderStyle->getRight(), $borderStyleXml->right); 116 self::readBorder($borderStyle->getTop(), $borderStyleXml->top); 117 self::readBorder($borderStyle->getBottom(), $borderStyleXml->bottom); 118 self::readBorder($borderStyle->getDiagonal(), $borderStyleXml->diagonal); 119 } 120 121 private static function readBorder(Border $border, \SimpleXMLElement $borderXml) 122 { 123 if (isset($borderXml['style'])) { 124 $border->setBorderStyle((string) $borderXml['style']); 125 } 126 if (isset($borderXml->color)) { 127 $border->getColor()->setARGB(self::readColor($borderXml->color)); 128 } 129 } 130 131 private static function readAlignmentStyle(Alignment $alignment, \SimpleXMLElement $alignmentXml) 132 { 133 $alignment->setHorizontal((string) $alignmentXml->alignment['horizontal']); 134 $alignment->setVertical((string) $alignmentXml->alignment['vertical']); 135 136 $textRotation = 0; 137 if ((int) $alignmentXml->alignment['textRotation'] <= 90) { 138 $textRotation = (int) $alignmentXml->alignment['textRotation']; 139 } elseif ((int) $alignmentXml->alignment['textRotation'] > 90) { 140 $textRotation = 90 - (int) $alignmentXml->alignment['textRotation']; 141 } 142 143 $alignment->setTextRotation((int) $textRotation); 144 $alignment->setWrapText(self::boolean((string) $alignmentXml->alignment['wrapText'])); 145 $alignment->setShrinkToFit(self::boolean((string) $alignmentXml->alignment['shrinkToFit'])); 146 $alignment->setIndent((int) ((string) $alignmentXml->alignment['indent']) > 0 ? (int) ((string) $alignmentXml->alignment['indent']) : 0); 147 $alignment->setReadOrder((int) ((string) $alignmentXml->alignment['readingOrder']) > 0 ? (int) ((string) $alignmentXml->alignment['readingOrder']) : 0); 148 } 149 150 private function readStyle(Style $docStyle, $style) 151 { 152 $docStyle->getNumberFormat()->setFormatCode($style->numFmt); 153 154 if (isset($style->font)) { 155 self::readFontStyle($docStyle->getFont(), $style->font); 156 } 157 158 if (isset($style->fill)) { 159 self::readFillStyle($docStyle->getFill(), $style->fill); 160 } 161 162 if (isset($style->border)) { 163 self::readBorderStyle($docStyle->getBorders(), $style->border); 164 } 165 166 if (isset($style->alignment->alignment)) { 167 self::readAlignmentStyle($docStyle->getAlignment(), $style->alignment); 168 } 169 170 // protection 171 if (isset($style->protection)) { 172 $this->readProtectionLocked($docStyle, $style); 173 $this->readProtectionHidden($docStyle, $style); 174 } 175 176 // top-level style settings 177 if (isset($style->quotePrefix)) { 178 $docStyle->setQuotePrefix(true); 179 } 180 } 181 182 private function readProtectionLocked(Style $docStyle, $style) 183 { 184 if (isset($style->protection['locked'])) { 185 if (self::boolean((string) $style->protection['locked'])) { 186 $docStyle->getProtection()->setLocked(Protection::PROTECTION_PROTECTED); 187 } else { 188 $docStyle->getProtection()->setLocked(Protection::PROTECTION_UNPROTECTED); 189 } 190 } 191 } 192 193 private function readProtectionHidden(Style $docStyle, $style) 194 { 195 if (isset($style->protection['hidden'])) { 196 if (self::boolean((string) $style->protection['hidden'])) { 197 $docStyle->getProtection()->setHidden(Protection::PROTECTION_PROTECTED); 198 } else { 199 $docStyle->getProtection()->setHidden(Protection::PROTECTION_UNPROTECTED); 200 } 201 } 202 } 203 204 private static function readColor($color, $background = false) 205 { 206 if (isset($color['rgb'])) { 207 return (string) $color['rgb']; 208 } elseif (isset($color['indexed'])) { 209 return Color::indexedColor($color['indexed'] - 7, $background)->getARGB(); 210 } elseif (isset($color['theme'])) { 211 if (self::$theme !== null) { 212 $returnColour = self::$theme->getColourByIndex((int) $color['theme']); 213 if (isset($color['tint'])) { 214 $tintAdjust = (float) $color['tint']; 215 $returnColour = Color::changeBrightness($returnColour, $tintAdjust); 216 } 217 218 return 'FF' . $returnColour; 219 } 220 } 221 222 return ($background) ? 'FFFFFFFF' : 'FF000000'; 223 } 224 225 public function dxfs($readDataOnly = false) 226 { 227 $dxfs = []; 228 if (!$readDataOnly && $this->styleXml) { 229 // Conditional Styles 230 if ($this->styleXml->dxfs) { 231 foreach ($this->styleXml->dxfs->dxf as $dxf) { 232 $style = new Style(false, true); 233 $this->readStyle($style, $dxf); 234 $dxfs[] = $style; 235 } 236 } 237 // Cell Styles 238 if ($this->styleXml->cellStyles) { 239 foreach ($this->styleXml->cellStyles->cellStyle as $cellStyle) { 240 if ((int) ($cellStyle['builtinId']) == 0) { 241 if (isset($this->cellStyles[(int) ($cellStyle['xfId'])])) { 242 // Set default style 243 $style = new Style(); 244 $this->readStyle($style, $this->cellStyles[(int) ($cellStyle['xfId'])]); 245 246 // normal style, currently not using it for anything 247 } 248 } 249 } 250 } 251 } 252 253 return $dxfs; 254 } 255 256 public function styles() 257 { 258 return $this->styles; 259 } 260 261 private static function getArrayItem($array, $key = 0) 262 { 263 return $array[$key] ?? null; 264 } 265 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body