ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Styles.php
Go to the documentation of this file.
1<?php
2
4
13use SimpleXMLElement;
14
15class Styles
16{
20 private $spreadsheet;
21
25 protected $readDataOnly = false;
26
28 public static $mappings = [
29 'borderStyle' => [
44 ],
45 'fillType' => [
46 '1' => Fill::FILL_SOLID,
52 '7' => Fill::FILL_PATTERN_DARKHORIZONTAL, // horizontal stripe
53 '8' => Fill::FILL_PATTERN_DARKVERTICAL, // vertical stripe
54 '9' => Fill::FILL_PATTERN_DARKDOWN, // diagonal stripe
55 '10' => Fill::FILL_PATTERN_DARKUP, // reverse diagonal stripe
56 '11' => Fill::FILL_PATTERN_DARKGRID, // diagoanl crosshatch
57 '12' => Fill::FILL_PATTERN_DARKTRELLIS, // thick diagonal crosshatch
62 '17' => Fill::FILL_PATTERN_LIGHTGRID, // thin horizontal crosshatch
63 '18' => Fill::FILL_PATTERN_LIGHTTRELLIS, // thin diagonal crosshatch
64 ],
65 'horizontal' => [
73 ],
74 'underline' => [
79 ],
80 'vertical' => [
85 ],
86 ];
87
89 {
90 $this->spreadsheet = $spreadsheet;
91 $this->readDataOnly = $readDataOnly;
92 }
93
94 public function read(SimpleXMLElement $sheet, int $maxRow, int $maxCol): void
95 {
96 if ($sheet->Styles->StyleRegion !== null) {
97 $this->readStyles($sheet->Styles->StyleRegion, $maxRow, $maxCol);
98 }
99 }
100
101 private function readStyles(SimpleXMLElement $styleRegion, int $maxRow, int $maxCol): void
102 {
103 foreach ($styleRegion as $style) {
104 if ($style === null) {
105 continue;
106 }
107
108 $styleAttributes = $style->attributes();
109 if ($styleAttributes !== null && ($styleAttributes['startRow'] <= $maxRow) && ($styleAttributes['startCol'] <= $maxCol)) {
110 $cellRange = $this->readStyleRange($styleAttributes, $maxCol, $maxRow);
111
112 $styleAttributes = $style->Style->attributes();
113
114 $styleArray = [];
115 // We still set the number format mask for date/time values, even if readDataOnly is true
116 // so that we can identify whether a float is a float or a date value
117 $formatCode = (string) $styleAttributes['Format'];
118 if (Date::isDateTimeFormatCode($formatCode)) {
119 $styleArray['numberFormat']['formatCode'] = $formatCode;
120 }
121 if ($this->readDataOnly === false && $styleAttributes !== null) {
122 // If readDataOnly is false, we set all formatting information
123 $styleArray['numberFormat']['formatCode'] = $formatCode;
124 $styleArray = $this->readStyle($styleArray, $styleAttributes, $style);
125 }
126 $this->spreadsheet->getActiveSheet()->getStyle($cellRange)->applyFromArray($styleArray);
127 }
128 }
129 }
130
131 private function addBorderDiagonal(SimpleXMLElement $srssb, array &$styleArray): void
132 {
133 if (isset($srssb->Diagonal, $srssb->{'Rev-Diagonal'})) {
134 $styleArray['borders']['diagonal'] = self::parseBorderAttributes($srssb->Diagonal->attributes());
135 $styleArray['borders']['diagonalDirection'] = Borders::DIAGONAL_BOTH;
136 } elseif (isset($srssb->Diagonal)) {
137 $styleArray['borders']['diagonal'] = self::parseBorderAttributes($srssb->Diagonal->attributes());
138 $styleArray['borders']['diagonalDirection'] = Borders::DIAGONAL_UP;
139 } elseif (isset($srssb->{'Rev-Diagonal'})) {
140 $styleArray['borders']['diagonal'] = self::parseBorderAttributes($srssb->{'Rev-Diagonal'}->attributes());
141 $styleArray['borders']['diagonalDirection'] = Borders::DIAGONAL_DOWN;
142 }
143 }
144
145 private function addBorderStyle(SimpleXMLElement $srssb, array &$styleArray, string $direction): void
146 {
147 $ucDirection = ucfirst($direction);
148 if (isset($srssb->$ucDirection)) {
149 $styleArray['borders'][$direction] = self::parseBorderAttributes($srssb->$ucDirection->attributes());
150 }
151 }
152
153 private function calcRotation(SimpleXMLElement $styleAttributes): int
154 {
155 $rotation = (int) $styleAttributes->Rotation;
156 if ($rotation >= 270 && $rotation <= 360) {
157 $rotation -= 360;
158 }
159 $rotation = (abs($rotation) > 90) ? 0 : $rotation;
160
161 return $rotation;
162 }
163
164 private static function addStyle(array &$styleArray, string $key, string $value): void
165 {
166 if (array_key_exists($value, self::$mappings[$key])) {
167 $styleArray[$key] = self::$mappings[$key][$value];
168 }
169 }
170
171 private static function addStyle2(array &$styleArray, string $key1, string $key, string $value): void
172 {
173 if (array_key_exists($value, self::$mappings[$key])) {
174 $styleArray[$key1][$key] = self::$mappings[$key][$value];
175 }
176 }
177
178 private static function parseBorderAttributes(?SimpleXMLElement $borderAttributes): array
179 {
180 $styleArray = [];
181 if ($borderAttributes !== null) {
182 if (isset($borderAttributes['Color'])) {
183 $styleArray['color']['rgb'] = self::parseGnumericColour($borderAttributes['Color']);
184 }
185
186 self::addStyle($styleArray, 'borderStyle', $borderAttributes['Style']);
187 }
188
189 return $styleArray;
190 }
191
192 private static function parseGnumericColour(string $gnmColour): string
193 {
194 [$gnmR, $gnmG, $gnmB] = explode(':', $gnmColour);
195 $gnmR = substr(str_pad($gnmR, 4, '0', STR_PAD_RIGHT), 0, 2);
196 $gnmG = substr(str_pad($gnmG, 4, '0', STR_PAD_RIGHT), 0, 2);
197 $gnmB = substr(str_pad($gnmB, 4, '0', STR_PAD_RIGHT), 0, 2);
198
199 return $gnmR . $gnmG . $gnmB;
200 }
201
202 private function addColors(array &$styleArray, SimpleXMLElement $styleAttributes): void
203 {
204 $RGB = self::parseGnumericColour($styleAttributes['Fore']);
205 $styleArray['font']['color']['rgb'] = $RGB;
206 $RGB = self::parseGnumericColour($styleAttributes['Back']);
207 $shade = (string) $styleAttributes['Shade'];
208 if (($RGB !== '000000') || ($shade !== '0')) {
209 $RGB2 = self::parseGnumericColour($styleAttributes['PatternColor']);
210 if ($shade === '1') {
211 $styleArray['fill']['startColor']['rgb'] = $RGB;
212 $styleArray['fill']['endColor']['rgb'] = $RGB2;
213 } else {
214 $styleArray['fill']['endColor']['rgb'] = $RGB;
215 $styleArray['fill']['startColor']['rgb'] = $RGB2;
216 }
217 self::addStyle2($styleArray, 'fill', 'fillType', $shade);
218 }
219 }
220
221 private function readStyleRange(SimpleXMLElement $styleAttributes, int $maxCol, int $maxRow): string
222 {
223 $startColumn = Coordinate::stringFromColumnIndex((int) $styleAttributes['startCol'] + 1);
224 $startRow = $styleAttributes['startRow'] + 1;
225
226 $endColumn = ($styleAttributes['endCol'] > $maxCol) ? $maxCol : (int) $styleAttributes['endCol'];
227 $endColumn = Coordinate::stringFromColumnIndex($endColumn + 1);
228
229 $endRow = 1 + (($styleAttributes['endRow'] > $maxRow) ? $maxRow : (int) $styleAttributes['endRow']);
230 $cellRange = $startColumn . $startRow . ':' . $endColumn . $endRow;
231
232 return $cellRange;
233 }
234
235 private function readStyle(array $styleArray, SimpleXMLElement $styleAttributes, SimpleXMLElement $style): array
236 {
237 self::addStyle2($styleArray, 'alignment', 'horizontal', $styleAttributes['HAlign']);
238 self::addStyle2($styleArray, 'alignment', 'vertical', $styleAttributes['VAlign']);
239 $styleArray['alignment']['wrapText'] = $styleAttributes['WrapText'] == '1';
240 $styleArray['alignment']['textRotation'] = $this->calcRotation($styleAttributes);
241 $styleArray['alignment']['shrinkToFit'] = $styleAttributes['ShrinkToFit'] == '1';
242 $styleArray['alignment']['indent'] = ((int) ($styleAttributes['Indent']) > 0) ? $styleAttributes['indent'] : 0;
243
244 $this->addColors($styleArray, $styleAttributes);
245
246 $fontAttributes = $style->Style->Font->attributes();
247 if ($fontAttributes !== null) {
248 $styleArray['font']['name'] = (string) $style->Style->Font;
249 $styleArray['font']['size'] = (int) ($fontAttributes['Unit']);
250 $styleArray['font']['bold'] = $fontAttributes['Bold'] == '1';
251 $styleArray['font']['italic'] = $fontAttributes['Italic'] == '1';
252 $styleArray['font']['strikethrough'] = $fontAttributes['StrikeThrough'] == '1';
253 self::addStyle2($styleArray, 'font', 'underline', $fontAttributes['Underline']);
254
255 switch ($fontAttributes['Script']) {
256 case '1':
257 $styleArray['font']['superscript'] = true;
258
259 break;
260 case '-1':
261 $styleArray['font']['subscript'] = true;
262
263 break;
264 }
265 }
266
267 if (isset($style->Style->StyleBorder)) {
268 $srssb = $style->Style->StyleBorder;
269 $this->addBorderStyle($srssb, $styleArray, 'top');
270 $this->addBorderStyle($srssb, $styleArray, 'bottom');
271 $this->addBorderStyle($srssb, $styleArray, 'left');
272 $this->addBorderStyle($srssb, $styleArray, 'right');
273 $this->addBorderDiagonal($srssb, $styleArray);
274 }
275 if (isset($style->Style->HyperLink)) {
276 // TO DO
277 $hyperlink = $style->Style->HyperLink->attributes();
278 }
279
280 return $styleArray;
281 }
282}
An exception for terminatinating execution or to throw for unit testing.
Helper class to manipulate cell coordinates.
Definition: Coordinate.php:15
calcRotation(SimpleXMLElement $styleAttributes)
Definition: Styles.php:153
addBorderStyle(SimpleXMLElement $srssb, array &$styleArray, string $direction)
Definition: Styles.php:145
static parseGnumericColour(string $gnmColour)
Definition: Styles.php:192
static addStyle2(array &$styleArray, string $key1, string $key, string $value)
Definition: Styles.php:171
__construct(Spreadsheet $spreadsheet, bool $readDataOnly)
Definition: Styles.php:88
addColors(array &$styleArray, SimpleXMLElement $styleAttributes)
Definition: Styles.php:202
readStyle(array $styleArray, SimpleXMLElement $styleAttributes, SimpleXMLElement $style)
Definition: Styles.php:235
static parseBorderAttributes(?SimpleXMLElement $borderAttributes)
Definition: Styles.php:178
static addStyle(array &$styleArray, string $key, string $value)
Definition: Styles.php:164
read(SimpleXMLElement $sheet, int $maxRow, int $maxCol)
Definition: Styles.php:94
readStyles(SimpleXMLElement $styleRegion, int $maxRow, int $maxCol)
Definition: Styles.php:101
readStyleRange(SimpleXMLElement $styleAttributes, int $maxCol, int $maxRow)
Definition: Styles.php:221
addBorderDiagonal(SimpleXMLElement $srssb, array &$styleArray)
Definition: Styles.php:131
static isDateTimeFormatCode($pFormatCode)
Is a given number format code a date/time?
Definition: Date.php:360
if(!file_exists(getcwd() . '/ilias.ini.php'))
registration confirmation script for ilias
Definition: confirmReg.php:12
$key
Definition: croninfo.php:18
$style
Definition: example_012.php:70