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