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