PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.0.3
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.0.3
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
visualizer / vendor / phpoffice / phpexcel / Classes / PHPExcel / Style.php

Style.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.0.3, at vendor/phpoffice/phpexcel/Classes/PHPExcel/Style.php

669 lines 23.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * PHPExcel
4 *
5 * Copyright (c) 2006 - 2014 PHPExcel
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 * @category PHPExcel
22 * @package PHPExcel_Style
23 * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
24 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
25 * @version ##VERSION##, ##DATE##
26 */
27
28
29 /**
30 * PHPExcel_Style
31 *
32 * @category PHPExcel
33 * @package PHPExcel_Style
34 * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
35 */
36 class PHPExcel_Style extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable
37 {
38 /**
39 * Font
40 *
41 * @var PHPExcel_Style_Font
42 */
43 protected $_font;
44
45 /**
46 * Fill
47 *
48 * @var PHPExcel_Style_Fill
49 */
50 protected $_fill;
51
52 /**
53 * Borders
54 *
55 * @var PHPExcel_Style_Borders
56 */
57 protected $_borders;
58
59 /**
60 * Alignment
61 *
62 * @var PHPExcel_Style_Alignment
63 */
64 protected $_alignment;
65
66 /**
67 * Number Format
68 *
69 * @var PHPExcel_Style_NumberFormat
70 */
71 protected $_numberFormat;
72
73 /**
74 * Conditional styles
75 *
76 * @var PHPExcel_Style_Conditional[]
77 */
78 protected $_conditionalStyles;
79
80 /**
81 * Protection
82 *
83 * @var PHPExcel_Style_Protection
84 */
85 protected $_protection;
86
87 /**
88 * Index of style in collection. Only used for real style.
89 *
90 * @var int
91 */
92 protected $_index;
93
94 /**
95 * Use Quote Prefix when displaying in cell editor. Only used for real style.
96 *
97 * @var boolean
98 */
99 protected $_quotePrefix = false;
100
101 /**
102 * Create a new PHPExcel_Style
103 *
104 * @param boolean $isSupervisor Flag indicating if this is a supervisor or not
105 * Leave this value at default unless you understand exactly what
106 * its ramifications are
107 * @param boolean $isConditional Flag indicating if this is a conditional style or not
108 * Leave this value at default unless you understand exactly what
109 * its ramifications are
110 */
111 public function __construct($isSupervisor = false, $isConditional = false)
112 {
113 // Supervisor?
114 $this->_isSupervisor = $isSupervisor;
115
116 // Initialise values
117 $this->_conditionalStyles = array();
118 $this->_font = new PHPExcel_Style_Font($isSupervisor, $isConditional);
119 $this->_fill = new PHPExcel_Style_Fill($isSupervisor, $isConditional);
120 $this->_borders = new PHPExcel_Style_Borders($isSupervisor, $isConditional);
121 $this->_alignment = new PHPExcel_Style_Alignment($isSupervisor, $isConditional);
122 $this->_numberFormat = new PHPExcel_Style_NumberFormat($isSupervisor, $isConditional);
123 $this->_protection = new PHPExcel_Style_Protection($isSupervisor, $isConditional);
124
125 // bind parent if we are a supervisor
126 if ($isSupervisor) {
127 $this->_font->bindParent($this);
128 $this->_fill->bindParent($this);
129 $this->_borders->bindParent($this);
130 $this->_alignment->bindParent($this);
131 $this->_numberFormat->bindParent($this);
132 $this->_protection->bindParent($this);
133 }
134 }
135
136 /**
137 * Get the shared style component for the currently active cell in currently active sheet.
138 * Only used for style supervisor
139 *
140 * @return PHPExcel_Style
141 */
142 public function getSharedComponent()
143 {
144 $activeSheet = $this->getActiveSheet();
145 $selectedCell = $this->getActiveCell(); // e.g. 'A1'
146
147 if ($activeSheet->cellExists($selectedCell)) {
148 $xfIndex = $activeSheet->getCell($selectedCell)->getXfIndex();
149 } else {
150 $xfIndex = 0;
151 }
152
153 return $this->_parent->getCellXfByIndex($xfIndex);
154 }
155
156 /**
157 * Get parent. Only used for style supervisor
158 *
159 * @return PHPExcel
160 */
161 public function getParent()
162 {
163 return $this->_parent;
164 }
165
166 /**
167 * Build style array from subcomponents
168 *
169 * @param array $array
170 * @return array
171 */
172 public function getStyleArray($array)
173 {
174 return array('quotePrefix' => $array);
175 }
176
177 /**
178 * Apply styles from array
179 *
180 * <code>
181 * $objPHPExcel->getActiveSheet()->getStyle('B2')->applyFromArray(
182 * array(
183 * 'font' => array(
184 * 'name' => 'Arial',
185 * 'bold' => true,
186 * 'italic' => false,
187 * 'underline' => PHPExcel_Style_Font::UNDERLINE_DOUBLE,
188 * 'strike' => false,
189 * 'color' => array(
190 * 'rgb' => '808080'
191 * )
192 * ),
193 * 'borders' => array(
194 * 'bottom' => array(
195 * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
196 * 'color' => array(
197 * 'rgb' => '808080'
198 * )
199 * ),
200 * 'top' => array(
201 * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
202 * 'color' => array(
203 * 'rgb' => '808080'
204 * )
205 * )
206 * ),
207 * 'quotePrefix' => true
208 * )
209 * );
210 * </code>
211 *
212 * @param array $pStyles Array containing style information
213 * @param boolean $pAdvanced Advanced mode for setting borders.
214 * @throws PHPExcel_Exception
215 * @return PHPExcel_Style
216 */
217 public function applyFromArray($pStyles = null, $pAdvanced = true)
218 {
219 if (is_array($pStyles)) {
220 if ($this->_isSupervisor) {
221
222 $pRange = $this->getSelectedCells();
223
224 // Uppercase coordinate
225 $pRange = strtoupper($pRange);
226
227 // Is it a cell range or a single cell?
228 if (strpos($pRange, ':') === false) {
229 $rangeA = $pRange;
230 $rangeB = $pRange;
231 } else {
232 list($rangeA, $rangeB) = explode(':', $pRange);
233 }
234
235 // Calculate range outer borders
236 $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA);
237 $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB);
238
239 // Translate column into index
240 $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1;
241 $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1;
242
243 // Make sure we can loop upwards on rows and columns
244 if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {
245 $tmp = $rangeStart;
246 $rangeStart = $rangeEnd;
247 $rangeEnd = $tmp;
248 }
249
250 // ADVANCED MODE:
251
252 if ($pAdvanced && isset($pStyles['borders'])) {
253
254 // 'allborders' is a shorthand property for 'outline' and 'inside' and
255 // it applies to components that have not been set explicitly
256 if (isset($pStyles['borders']['allborders'])) {
257 foreach (array('outline', 'inside') as $component) {
258 if (!isset($pStyles['borders'][$component])) {
259 $pStyles['borders'][$component] = $pStyles['borders']['allborders'];
260 }
261 }
262 unset($pStyles['borders']['allborders']); // not needed any more
263 }
264
265 // 'outline' is a shorthand property for 'top', 'right', 'bottom', 'left'
266 // it applies to components that have not been set explicitly
267 if (isset($pStyles['borders']['outline'])) {
268 foreach (array('top', 'right', 'bottom', 'left') as $component) {
269 if (!isset($pStyles['borders'][$component])) {
270 $pStyles['borders'][$component] = $pStyles['borders']['outline'];
271 }
272 }
273 unset($pStyles['borders']['outline']); // not needed any more
274 }
275
276 // 'inside' is a shorthand property for 'vertical' and 'horizontal'
277 // it applies to components that have not been set explicitly
278 if (isset($pStyles['borders']['inside'])) {
279 foreach (array('vertical', 'horizontal') as $component) {
280 if (!isset($pStyles['borders'][$component])) {
281 $pStyles['borders'][$component] = $pStyles['borders']['inside'];
282 }
283 }
284 unset($pStyles['borders']['inside']); // not needed any more
285 }
286
287 // width and height characteristics of selection, 1, 2, or 3 (for 3 or more)
288 $xMax = min($rangeEnd[0] - $rangeStart[0] + 1, 3);
289 $yMax = min($rangeEnd[1] - $rangeStart[1] + 1, 3);
290
291 // loop through up to 3 x 3 = 9 regions
292 for ($x = 1; $x <= $xMax; ++$x) {
293 // start column index for region
294 $colStart = ($x == 3) ?
295 PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0])
296 : PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $x - 1);
297
298 // end column index for region
299 $colEnd = ($x == 1) ?
300 PHPExcel_Cell::stringFromColumnIndex($rangeStart[0])
301 : PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] - $xMax + $x);
302
303 for ($y = 1; $y <= $yMax; ++$y) {
304
305 // which edges are touching the region
306 $edges = array();
307
308 // are we at left edge
309 if ($x == 1) {
310 $edges[] = 'left';
311 }
312
313 // are we at right edge
314 if ($x == $xMax) {
315 $edges[] = 'right';
316 }
317
318 // are we at top edge?
319 if ($y == 1) {
320 $edges[] = 'top';
321 }
322
323 // are we at bottom edge?
324 if ($y == $yMax) {
325 $edges[] = 'bottom';
326 }
327
328 // start row index for region
329 $rowStart = ($y == 3) ?
330 $rangeEnd[1] : $rangeStart[1] + $y - 1;
331
332 // end row index for region
333 $rowEnd = ($y == 1) ?
334 $rangeStart[1] : $rangeEnd[1] - $yMax + $y;
335
336 // build range for region
337 $range = $colStart . $rowStart . ':' . $colEnd . $rowEnd;
338
339 // retrieve relevant style array for region
340 $regionStyles = $pStyles;
341 unset($regionStyles['borders']['inside']);
342
343 // what are the inner edges of the region when looking at the selection
344 $innerEdges = array_diff( array('top', 'right', 'bottom', 'left'), $edges );
345
346 // inner edges that are not touching the region should take the 'inside' border properties if they have been set
347 foreach ($innerEdges as $innerEdge) {
348 switch ($innerEdge) {
349 case 'top':
350 case 'bottom':
351 // should pick up 'horizontal' border property if set
352 if (isset($pStyles['borders']['horizontal'])) {
353 $regionStyles['borders'][$innerEdge] = $pStyles['borders']['horizontal'];
354 } else {
355 unset($regionStyles['borders'][$innerEdge]);
356 }
357 break;
358 case 'left':
359 case 'right':
360 // should pick up 'vertical' border property if set
361 if (isset($pStyles['borders']['vertical'])) {
362 $regionStyles['borders'][$innerEdge] = $pStyles['borders']['vertical'];
363 } else {
364 unset($regionStyles['borders'][$innerEdge]);
365 }
366 break;
367 }
368 }
369
370 // apply region style to region by calling applyFromArray() in simple mode
371 $this->getActiveSheet()->getStyle($range)->applyFromArray($regionStyles, false);
372 }
373 }
374 return $this;
375 }
376
377 // SIMPLE MODE:
378
379 // Selection type, inspect
380 if (preg_match('/^[A-Z]+1:[A-Z]+1048576$/', $pRange)) {
381 $selectionType = 'COLUMN';
382 } else if (preg_match('/^A[0-9]+:XFD[0-9]+$/', $pRange)) {
383 $selectionType = 'ROW';
384 } else {
385 $selectionType = 'CELL';
386 }
387
388 // First loop through columns, rows, or cells to find out which styles are affected by this operation
389 switch ($selectionType) {
390 case 'COLUMN':
391 $oldXfIndexes = array();
392 for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
393 $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true;
394 }
395 break;
396
397 case 'ROW':
398 $oldXfIndexes = array();
399 for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
400 if ($this->getActiveSheet()->getRowDimension($row)->getXfIndex() == null) {
401 $oldXfIndexes[0] = true; // row without explicit style should be formatted based on default style
402 } else {
403 $oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()] = true;
404 }
405 }
406 break;
407
408 case 'CELL':
409 $oldXfIndexes = array();
410 for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
411 for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
412 $oldXfIndexes[$this->getActiveSheet()->getCellByColumnAndRow($col, $row)->getXfIndex()] = true;
413 }
414 }
415 break;
416 }
417
418 // clone each of the affected styles, apply the style array, and add the new styles to the workbook
419 $workbook = $this->getActiveSheet()->getParent();
420 foreach ($oldXfIndexes as $oldXfIndex => $dummy) {
421 $style = $workbook->getCellXfByIndex($oldXfIndex);
422 $newStyle = clone $style;
423 $newStyle->applyFromArray($pStyles);
424
425 if ($existingStyle = $workbook->getCellXfByHashCode($newStyle->getHashCode())) {
426 // there is already such cell Xf in our collection
427 $newXfIndexes[$oldXfIndex] = $existingStyle->getIndex();
428 } else {
429 // we don't have such a cell Xf, need to add
430 $workbook->addCellXf($newStyle);
431 $newXfIndexes[$oldXfIndex] = $newStyle->getIndex();
432 }
433 }
434
435 // Loop through columns, rows, or cells again and update the XF index
436 switch ($selectionType) {
437 case 'COLUMN':
438 for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
439 $columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col);
440 $oldXfIndex = $columnDimension->getXfIndex();
441 $columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
442 }
443 break;
444
445 case 'ROW':
446 for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
447 $rowDimension = $this->getActiveSheet()->getRowDimension($row);
448 $oldXfIndex = $rowDimension->getXfIndex() === null ?
449 0 : $rowDimension->getXfIndex(); // row without explicit style should be formatted based on default style
450 $rowDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
451 }
452 break;
453
454 case 'CELL':
455 for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
456 for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
457 $cell = $this->getActiveSheet()->getCellByColumnAndRow($col, $row);
458 $oldXfIndex = $cell->getXfIndex();
459 $cell->setXfIndex($newXfIndexes[$oldXfIndex]);
460 }
461 }
462 break;
463 }
464
465 } else {
466 // not a supervisor, just apply the style array directly on style object
467 if (array_key_exists('fill', $pStyles)) {
468 $this->getFill()->applyFromArray($pStyles['fill']);
469 }
470 if (array_key_exists('font', $pStyles)) {
471 $this->getFont()->applyFromArray($pStyles['font']);
472 }
473 if (array_key_exists('borders', $pStyles)) {
474 $this->getBorders()->applyFromArray($pStyles['borders']);
475 }
476 if (array_key_exists('alignment', $pStyles)) {
477 $this->getAlignment()->applyFromArray($pStyles['alignment']);
478 }
479 if (array_key_exists('numberformat', $pStyles)) {
480 $this->getNumberFormat()->applyFromArray($pStyles['numberformat']);
481 }
482 if (array_key_exists('protection', $pStyles)) {
483 $this->getProtection()->applyFromArray($pStyles['protection']);
484 }
485 if (array_key_exists('quotePrefix', $pStyles)) {
486 $this->_quotePrefix = $pStyles['quotePrefix'];
487 }
488 }
489 } else {
490 throw new PHPExcel_Exception("Invalid style array passed.");
491 }
492 return $this;
493 }
494
495 /**
496 * Get Fill
497 *
498 * @return PHPExcel_Style_Fill
499 */
500 public function getFill()
501 {
502 return $this->_fill;
503 }
504
505 /**
506 * Get Font
507 *
508 * @return PHPExcel_Style_Font
509 */
510 public function getFont()
511 {
512 return $this->_font;
513 }
514
515 /**
516 * Set font
517 *
518 * @param PHPExcel_Style_Font $font
519 * @return PHPExcel_Style
520 */
521 public function setFont(PHPExcel_Style_Font $font)
522 {
523 $this->_font = $font;
524 return $this;
525 }
526
527 /**
528 * Get Borders
529 *
530 * @return PHPExcel_Style_Borders
531 */
532 public function getBorders()
533 {
534 return $this->_borders;
535 }
536
537 /**
538 * Get Alignment
539 *
540 * @return PHPExcel_Style_Alignment
541 */
542 public function getAlignment()
543 {
544 return $this->_alignment;
545 }
546
547 /**
548 * Get Number Format
549 *
550 * @return PHPExcel_Style_NumberFormat
551 */
552 public function getNumberFormat()
553 {
554 return $this->_numberFormat;
555 }
556
557 /**
558 * Get Conditional Styles. Only used on supervisor.
559 *
560 * @return PHPExcel_Style_Conditional[]
561 */
562 public function getConditionalStyles()
563 {
564 return $this->getActiveSheet()->getConditionalStyles($this->getActiveCell());
565 }
566
567 /**
568 * Set Conditional Styles. Only used on supervisor.
569 *
570 * @param PHPExcel_Style_Conditional[] $pValue Array of condtional styles
571 * @return PHPExcel_Style
572 */
573 public function setConditionalStyles($pValue = null)
574 {
575 if (is_array($pValue)) {
576 $this->getActiveSheet()->setConditionalStyles($this->getSelectedCells(), $pValue);
577 }
578 return $this;
579 }
580
581 /**
582 * Get Protection
583 *
584 * @return PHPExcel_Style_Protection
585 */
586 public function getProtection()
587 {
588 return $this->_protection;
589 }
590
591 /**
592 * Get quote prefix
593 *
594 * @return boolean
595 */
596 public function getQuotePrefix()
597 {
598 if ($this->_isSupervisor) {
599 return $this->getSharedComponent()->getQuotePrefix();
600 }
601 return $this->_quotePrefix;
602 }
603
604 /**
605 * Set quote prefix
606 *
607 * @param boolean $pValue
608 */
609 public function setQuotePrefix($pValue)
610 {
611 if ($pValue == '') {
612 $pValue = false;
613 }
614 if ($this->_isSupervisor) {
615 $styleArray = array('quotePrefix' => $pValue);
616 $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
617 } else {
618 $this->_quotePrefix = (boolean) $pValue;
619 }
620 return $this;
621 }
622
623 /**
624 * Get hash code
625 *
626 * @return string Hash code
627 */
628 public function getHashCode()
629 {
630 $hashConditionals = '';
631 foreach ($this->_conditionalStyles as $conditional) {
632 $hashConditionals .= $conditional->getHashCode();
633 }
634
635 return md5(
636 $this->_fill->getHashCode()
637 . $this->_font->getHashCode()
638 . $this->_borders->getHashCode()
639 . $this->_alignment->getHashCode()
640 . $this->_numberFormat->getHashCode()
641 . $hashConditionals
642 . $this->_protection->getHashCode()
643 . ($this->_quotePrefix ? 't' : 'f')
644 . __CLASS__
645 );
646 }
647
648 /**
649 * Get own index in style collection
650 *
651 * @return int
652 */
653 public function getIndex()
654 {
655 return $this->_index;
656 }
657
658 /**
659 * Set own index in style collection
660 *
661 * @param int $pValue
662 */
663 public function setIndex($pValue)
664 {
665 $this->_index = $pValue;
666 }
667
668 }
669