[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/phpexcel/PHPExcel/ -> Style.php (source)

   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  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1