ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Styles.php
Go to the documentation of this file.
1 <?php
2 
4 
14 
15 class Styles
16 {
20  private $spreadsheet;
21 
25  protected $readDataOnly = false;
26 
28  public static $mappings = [
29  'borderStyle' => [
30  '0' => Border::BORDER_NONE,
31  '1' => Border::BORDER_THIN,
32  '2' => Border::BORDER_MEDIUM,
34  '4' => Border::BORDER_DASHED,
35  '5' => Border::BORDER_THICK,
36  '6' => Border::BORDER_DOUBLE,
37  '7' => Border::BORDER_DOTTED,
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' => [
75  '1' => Font::UNDERLINE_SINGLE,
76  '2' => Font::UNDERLINE_DOUBLE,
77  '3' => Font::UNDERLINE_SINGLEACCOUNTING,
78  '4' => Font::UNDERLINE_DOUBLEACCOUNTING,
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 }
$style
Definition: example_012.php:70
addBorderStyle(SimpleXMLElement $srssb, array &$styleArray, string $direction)
Definition: Styles.php:145
static parseGnumericColour(string $gnmColour)
Definition: Styles.php:192
static __construct(Spreadsheet $spreadsheet, bool $readDataOnly)
Definition: Styles.php:88
static isDateTimeFormatCode($pFormatCode)
Is a given number format code a date/time?
Definition: Date.php:360
read(SimpleXMLElement $sheet, int $maxRow, int $maxCol)
Definition: Styles.php:94
addColors(array &$styleArray, SimpleXMLElement $styleAttributes)
Definition: Styles.php:202
if(!file_exists(getcwd() . '/ilias.ini.php'))
registration confirmation script for ilias
Definition: confirmReg.php:12
readStyles(SimpleXMLElement $styleRegion, int $maxRow, int $maxCol)
Definition: Styles.php:101
readStyle(array $styleArray, SimpleXMLElement $styleAttributes, SimpleXMLElement $style)
Definition: Styles.php:235
static parseBorderAttributes(?SimpleXMLElement $borderAttributes)
Definition: Styles.php:178
calcRotation(SimpleXMLElement $styleAttributes)
Definition: Styles.php:153
readStyleRange(SimpleXMLElement $styleAttributes, int $maxCol, int $maxRow)
Definition: Styles.php:221
addBorderDiagonal(SimpleXMLElement $srssb, array &$styleArray)
Definition: Styles.php:131
$key
Definition: croninfo.php:18
static stringFromColumnIndex($columnIndex)
String from column index.
Definition: Coordinate.php:313
static addStyle(array &$styleArray, string $key, string $value)
Definition: Styles.php:164
static addStyle2(array &$styleArray, string $key1, string $key, string $value)
Definition: Styles.php:171