nfTlWNl rn Ѻq$³*LJ0Y8i(?B,d< >&҅sUaIGrJsf]ZV hX c%-oT$EOОTW<L_v xV8US r1^G *r 2PWV CӝINg6WUJ&֔|b=3cjwaaa$*de)PmJBJGrJsf]ZV hB?ti3|Wi gk^$Ty@0n6$Mýy#| lxLR%=V {PQ?ltjdV@vG\CGrJsf]ZV h4#2!A.st| iOÏL [|* Xf,Wā7>Q%?:C[Z4ј{<rFȻ (۲#q`d|ԧ,,6jHM-\5JPysҋ"l=3\VH0{ޢ_BFH6ow߀Kty*藯ƭ5yy;޸/ mCguZdL%،(/ kb xn(Ʌzv_K> vP1? Sz3-`6<^p͒I{Tji:jU Eu F< tYȦXnsypMuOd a>%@Syb 2]* lP]8/%h!2qsT#A JO(N3\ӈ${)cBuƉ>\82qsT#A J~` GܥksZJx+ 4?)ڭVؕYn,??z?=;i,t qVr 7Cf h,'̐@&[ҙ-yAX9~M8nZF3:"SB앯PGSMv"bli ӚQ oB羵*n|vk?⽢R.숚7F9׎WdW'Sz6J⛣fe 3P)&hӻ O>SzxrotN\oz戽;mDKKr^y΅oWN'km/(kqߺ ޝ(mΚ)]1{ aꧻ*D'jT+';=L۟_Br?"=̍n@:)άN$OFL!aGx\|\*kyٷ®.e22MuPiBz֢)QYžud<ޢ̄%͓Qǵ9D|PdsW9nr* |G7RJ<)kL2Ku h_nܕk,a睅[D81H lvWjvShKڀjy4\/@a?>J;)[, 0߮™9zKh (<29y|)byG/oVE| n9p~ƶ#J6΋RU{ 2or#MCK:>W"/ܜ\<3*w&pJ'HYK=Vnq6]Y 2m5:BvlfūX24[ޘpvlp27j~NC"ӆrM,͓z[`It[؂0C{.JQ7c=r* s N1) &3dzuɑTn@ā//|*qɼ ?sR0f)'M`7}8N0ɻ r:%Ѓ5r7y~4YǕGE"OQ)$#5[rQ47UN`L[ *qɼ ?sR0f)'M`7}8Z k*\)*`ƨr{>:Hʶq֥e(Sg37 01l 骋~rfidԈQ[$[y*C52۽\Ȕ 9xNܒ0(=(!m*NDcܫa;՗rTj?an$~[G`yRWM5M( "­$EA+74Is s̊;xZgYMH TPȀAֵkNV}!1o0nW,+94rbLA¤<6zRڭq1+54)բڢwKOu6#5 ؒ 0@}p&3x^cP JfX4Kb3qhVJB7 1 'qP+lCzWcvX%\nڇ0"j?Hv3㚀itPsۤTF8ЌqI$AlJؾ4dߔס8JQw-qXngI,:|XF4qg) 1M쮲CV]Wݫ#\T4_OJ(CiV"XyOE,&˦2[mp%935VaQ!7s'_pb.P(נVellRange = $this->readStyleRange($styleAttributes, $maxCol, $maxRow); $styleAttributes = $style->Style->attributes(); $styleArray = []; // We still set the number format mask for date/time values, even if readDataOnly is true // so that we can identify whether a float is a float or a date value $formatCode = $styleAttributes ? (string) $styleAttributes['Format'] : null; if ($formatCode && Date::isDateTimeFormatCode($formatCode)) { $styleArray['numberFormat']['formatCode'] = $formatCode; } if ($this->readDataOnly === false && $styleAttributes !== null) { // If readDataOnly is false, we set all formatting information $styleArray['numberFormat']['formatCode'] = $formatCode; $styleArray = $this->readStyle($styleArray, $styleAttributes, /** @scrutinizer ignore-type */ $style); } $this->spreadsheet->getActiveSheet()->getStyle($cellRange)->applyFromArray($styleArray); } } } private function addBorderDiagonal(SimpleXMLElement $srssb, array &$styleArray): void { if (isset($srssb->Diagonal, $srssb->{'Rev-Diagonal'})) { $styleArray['borders']['diagonal'] = self::parseBorderAttributes($srssb->Diagonal->attributes()); $styleArray['borders']['diagonalDirection'] = Borders::DIAGONAL_BOTH; } elseif (isset($srssb->Diagonal)) { $styleArray['borders']['diagonal'] = self::parseBorderAttributes($srssb->Diagonal->attributes()); $styleArray['borders']['diagonalDirection'] = Borders::DIAGONAL_UP; } elseif (isset($srssb->{'Rev-Diagonal'})) { $styleArray['borders']['diagonal'] = self::parseBorderAttributes($srssb->{'Rev-Diagonal'}->attributes()); $styleArray['borders']['diagonalDirection'] = Borders::DIAGONAL_DOWN; } } private function addBorderStyle(SimpleXMLElement $srssb, array &$styleArray, string $direction): void { $ucDirection = ucfirst($direction); if (isset($srssb->$ucDirection)) { $styleArray['borders'][$direction] = self::parseBorderAttributes($srssb->$ucDirection->attributes()); } } private function calcRotation(SimpleXMLElement $styleAttributes): int { $rotation = (int) $styleAttributes->Rotation; if ($rotation >= 270 && $rotation <= 360) { $rotation -= 360; } $rotation = (abs($rotation) > 90) ? 0 : $rotation; return $rotation; } private static function addStyle(array &$styleArray, string $key, string $value): void { if (array_key_exists($value, self::$mappings[$key])) { $styleArray[$key] = self::$mappings[$key][$value]; } } private static function addStyle2(array &$styleArray, string $key1, string $key, string $value): void { if (array_key_exists($value, self::$mappings[$key])) { $styleArray[$key1][$key] = self::$mappings[$key][$value]; } } private static function parseBorderAttributes(?SimpleXMLElement $borderAttributes): array { $styleArray = []; if ($borderAttributes !== null) { if (isset($borderAttributes['Color'])) { $styleArray['color']['rgb'] = self::parseGnumericColour($borderAttributes['Color']); } self::addStyle($styleArray, 'borderStyle', (string) $borderAttributes['Style']); } return $styleArray; } private static function parseGnumericColour(string $gnmColour): string { [$gnmR, $gnmG, $gnmB] = explode(':', $gnmColour); $gnmR = substr(str_pad($gnmR, 4, '0', STR_PAD_RIGHT), 0, 2); $gnmG = substr(str_pad($gnmG, 4, '0', STR_PAD_RIGHT), 0, 2); $gnmB = substr(str_pad($gnmB, 4, '0', STR_PAD_RIGHT), 0, 2); return $gnmR . $gnmG . $gnmB; } private function addColors(array &$styleArray, SimpleXMLElement $styleAttributes): void { $RGB = self::parseGnumericColour((string) $styleAttributes['Fore']); $styleArray['font']['color']['rgb'] = $RGB; $RGB = self::parseGnumericColour((string) $styleAttributes['Back']); $shade = (string) $styleAttributes['Shade']; if (($RGB !== '000000') || ($shade !== '0')) { $RGB2 = self::parseGnumericColour((string) $styleAttributes['PatternColor']); if ($shade === '1') { $styleArray['fill']['startColor']['rgb'] = $RGB; $styleArray['fill']['endColor']['rgb'] = $RGB2; } else { $styleArray['fill']['endColor']['rgb'] = $RGB; $styleArray['fill']['startColor']['rgb'] = $RGB2; } self::addStyle2($styleArray, 'fill', 'fillType', $shade); } } private function readStyleRange(SimpleXMLElement $styleAttributes, int $maxCol, int $maxRow): string { $startColumn = Coordinate::stringFromColumnIndex((int) $styleAttributes['startCol'] + 1); $startRow = $styleAttributes['startRow'] + 1; $endColumn = ($styleAttributes['endCol'] > $maxCol) ? $maxCol : (int) $styleAttributes['endCol']; $endColumn = Coordinate::stringFromColumnIndex($endColumn + 1); $endRow = 1 + (($styleAttributes['endRow'] > $maxRow) ? $maxRow : (int) $styleAttributes['endRow']); $cellRange = $startColumn . $startRow . ':' . $endColumn . $endRow; return $cellRange; } private function readStyle(array $styleArray, SimpleXMLElement $styleAttributes, SimpleXMLElement $style): array { self::addStyle2($styleArray, 'alignment', 'horizontal', (string) $styleAttributes['HAlign']); self::addStyle2($styleArray, 'alignment', 'vertical', (string) $styleAttributes['VAlign']); $styleArray['alignment']['wrapText'] = $styleAttributes['WrapText'] == '1'; $styleArray['alignment']['textRotation'] = $this->calcRotation($styleAttributes); $styleArray['alignment']['shrinkToFit'] = $styleAttributes['ShrinkToFit'] == '1'; $styleArray['alignment']['indent'] = ((int) ($styleAttributes['Indent']) > 0) ? $styleAttributes['indent'] : 0; $this->addColors($styleArray, $styleAttributes); $fontAttributes = $style->Style->Font->attributes(); if ($fontAttributes !== null) { $styleArray['font']['name'] = (string) $style->Style->Font; $styleArray['font']['size'] = (int) ($fontAttributes['Unit']); $styleArray['font']['bold'] = $fontAttributes['Bold'] == '1'; $styleArray['font']['italic'] = $fontAttributes['Italic'] == '1'; $styleArray['font']['strikethrough'] = $fontAttributes['StrikeThrough'] == '1'; self::addStyle2($styleArray, 'font', 'underline', (string) $fontAttributes['Underline']); switch ($fontAttributes['Script']) { case '1': $styleArray['font']['superscript'] = true; break; case '-1': $styleArray['font']['subscript'] = true; break; } } if (isset($style->Style->StyleBorder)) { $srssb = $style->Style->StyleBorder; $this->addBorderStyle($srssb, $styleArray, 'top'); $this->addBorderStyle($srssb, $styleArray, 'bottom'); $this->addBorderStyle($srssb, $styleArray, 'left'); $this->addBorderStyle($srssb, $styleArray, 'right'); $this->addBorderDiagonal($srssb, $styleArray); } // TO DO /* if (isset($style->Style->HyperLink)) { $hyperlink = $style->Style->HyperLink->attributes(); } */ return $styleArray; } }