[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/phpexcel/PHPExcel/ -> Cell.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_Cell
  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_Cell
  31   *
  32   *    @category   PHPExcel
  33   *    @package    PHPExcel_Cell
  34   *    @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
  35   */
  36  class PHPExcel_Cell
  37  {
  38  
  39      /**
  40       *  Default range variable constant
  41       *
  42       *  @var  string
  43       */
  44      const DEFAULT_RANGE = 'A1:A1';
  45  
  46      /**
  47       *    Value binder to use
  48       *
  49       *    @var    PHPExcel_Cell_IValueBinder
  50       */
  51      private static $_valueBinder = NULL;
  52  
  53      /**
  54       *    Value of the cell
  55       *
  56       *    @var    mixed
  57       */
  58      private $_value;
  59  
  60      /**
  61       *    Calculated value of the cell (used for caching)
  62       *    This returns the value last calculated by MS Excel or whichever spreadsheet program was used to
  63       *        create the original spreadsheet file.
  64       *    Note that this value is not guaranteed to reflect the actual calculated value because it is
  65       *        possible that auto-calculation was disabled in the original spreadsheet, and underlying data
  66       *        values used by the formula have changed since it was last calculated.
  67       *
  68       *    @var mixed
  69       */
  70      private $_calculatedValue = NULL;
  71  
  72      /**
  73       *    Type of the cell data
  74       *
  75       *    @var    string
  76       */
  77      private $_dataType;
  78  
  79      /**
  80       *    Parent worksheet
  81       *
  82       *    @var    PHPExcel_CachedObjectStorage_CacheBase
  83       */
  84      private $_parent;
  85  
  86      /**
  87       *    Index to cellXf
  88       *
  89       *    @var    int
  90       */
  91      private $_xfIndex;
  92  
  93      /**
  94       *    Attributes of the formula
  95       *
  96       */
  97      private $_formulaAttributes;
  98  
  99  
 100      /**
 101       *    Send notification to the cache controller
 102       *
 103       *    @return void
 104       **/
 105  	public function notifyCacheController() {
 106          $this->_parent->updateCacheData($this);
 107  
 108          return $this;
 109      }
 110  
 111  	public function detach() {
 112          $this->_parent = NULL;
 113      }
 114  
 115  	public function attach(PHPExcel_CachedObjectStorage_CacheBase $parent) {
 116  
 117  
 118          $this->_parent = $parent;
 119      }
 120  
 121  
 122      /**
 123       *    Create a new Cell
 124       *
 125       *    @param    mixed                $pValue
 126       *    @param    string                $pDataType
 127       *    @param    PHPExcel_Worksheet    $pSheet
 128       *    @throws    PHPExcel_Exception
 129       */
 130  	public function __construct($pValue = NULL, $pDataType = NULL, PHPExcel_Worksheet $pSheet = NULL)
 131      {
 132          // Initialise cell value
 133          $this->_value = $pValue;
 134  
 135          // Set worksheet cache
 136          $this->_parent = $pSheet->getCellCacheController();
 137  
 138          // Set datatype?
 139          if ($pDataType !== NULL) {
 140              if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2)
 141                  $pDataType = PHPExcel_Cell_DataType::TYPE_STRING;
 142              $this->_dataType = $pDataType;
 143          } else {
 144              if (!self::getValueBinder()->bindValue($this, $pValue)) {
 145                  throw new PHPExcel_Exception("Value could not be bound to cell.");
 146              }
 147          }
 148  
 149          // set default index to cellXf
 150          $this->_xfIndex = 0;
 151      }
 152  
 153      /**
 154       *    Get cell coordinate column
 155       *
 156       *    @return    string
 157       */
 158  	public function getColumn()
 159      {
 160          return $this->_parent->getCurrentColumn();
 161      }
 162  
 163      /**
 164       *    Get cell coordinate row
 165       *
 166       *    @return    int
 167       */
 168  	public function getRow()
 169      {
 170          return $this->_parent->getCurrentRow();
 171      }
 172  
 173      /**
 174       *    Get cell coordinate
 175       *
 176       *    @return    string
 177       */
 178  	public function getCoordinate()
 179      {
 180          return $this->_parent->getCurrentAddress();
 181      }
 182  
 183      /**
 184       *    Get cell value
 185       *
 186       *    @return    mixed
 187       */
 188  	public function getValue()
 189      {
 190          return $this->_value;
 191      }
 192  
 193      /**
 194       *    Get cell value with formatting
 195       *
 196       *    @return    string
 197       */
 198  	public function getFormattedValue()
 199      {
 200          return (string) PHPExcel_Style_NumberFormat::toFormattedString(
 201                  $this->getCalculatedValue(),
 202                  $this->getWorksheet()->getParent()->getCellXfByIndex($this->getXfIndex())
 203                      ->getNumberFormat()->getFormatCode()
 204              );
 205      }
 206  
 207      /**
 208       *    Set cell value
 209       *
 210       *    Sets the value for a cell, automatically determining the datatype using the value binder
 211       *
 212       *    @param    mixed    $pValue                    Value
 213       *    @return    PHPExcel_Cell
 214       *    @throws    PHPExcel_Exception
 215       */
 216  	public function setValue($pValue = NULL)
 217      {
 218          if (!self::getValueBinder()->bindValue($this, $pValue)) {
 219              throw new PHPExcel_Exception("Value could not be bound to cell.");
 220          }
 221          return $this;
 222      }
 223  
 224      /**
 225       *    Set the value for a cell, with the explicit data type passed to the method (bypassing any use of the value binder)
 226       *
 227       *    @param    mixed    $pValue            Value
 228       *    @param    string    $pDataType        Explicit data type
 229       *    @return    PHPExcel_Cell
 230       *    @throws    PHPExcel_Exception
 231       */
 232  	public function setValueExplicit($pValue = NULL, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING)
 233      {
 234          // set the value according to data type
 235          switch ($pDataType) {
 236              case PHPExcel_Cell_DataType::TYPE_NULL:
 237                  $this->_value = $pValue;
 238                  break;
 239              case PHPExcel_Cell_DataType::TYPE_STRING2:
 240                  $pDataType = PHPExcel_Cell_DataType::TYPE_STRING;
 241              case PHPExcel_Cell_DataType::TYPE_STRING:
 242              case PHPExcel_Cell_DataType::TYPE_INLINE:
 243                  $this->_value = PHPExcel_Cell_DataType::checkString($pValue);
 244                  break;
 245              case PHPExcel_Cell_DataType::TYPE_NUMERIC:
 246                  $this->_value = (float)$pValue;
 247                  break;
 248              case PHPExcel_Cell_DataType::TYPE_FORMULA:
 249                  $this->_value = (string)$pValue;
 250                  break;
 251              case PHPExcel_Cell_DataType::TYPE_BOOL:
 252                  $this->_value = (bool)$pValue;
 253                  break;
 254              case PHPExcel_Cell_DataType::TYPE_ERROR:
 255                  $this->_value = PHPExcel_Cell_DataType::checkErrorCode($pValue);
 256                  break;
 257              default:
 258                  throw new PHPExcel_Exception('Invalid datatype: ' . $pDataType);
 259                  break;
 260          }
 261  
 262          // set the datatype
 263          $this->_dataType = $pDataType;
 264  
 265          return $this->notifyCacheController();
 266      }
 267  
 268      /**
 269       *    Get calculated cell value
 270       *
 271       *    @deprecated        Since version 1.7.8 for planned changes to cell for array formula handling
 272       *
 273       *    @param    boolean $resetLog  Whether the calculation engine logger should be reset or not
 274       *    @return    mixed
 275       *    @throws    PHPExcel_Exception
 276       */
 277  	public function getCalculatedValue($resetLog = TRUE)
 278      {
 279  //echo 'Cell '.$this->getCoordinate().' value is a '.$this->_dataType.' with a value of '.$this->getValue().PHP_EOL;
 280          if ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) {
 281              try {
 282  //echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value'.PHP_EOL;
 283                  $result = PHPExcel_Calculation::getInstance(
 284                      $this->getWorksheet()->getParent()
 285                  )->calculateCellValue($this,$resetLog);
 286  //echo $this->getCoordinate().' calculation result is '.$result.PHP_EOL;
 287                  //    We don't yet handle array returns
 288                  if (is_array($result)) {
 289                      while (is_array($result)) {
 290                          $result = array_pop($result);
 291                      }
 292                  }
 293              } catch ( PHPExcel_Exception $ex ) {
 294                  if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->_calculatedValue !== NULL)) {
 295  //echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL;
 296                      return $this->_calculatedValue; // Fallback for calculations referencing external files.
 297                  }
 298  //echo 'Calculation Exception: '.$ex->getMessage().PHP_EOL;
 299                  $result = '#N/A';
 300                  throw new PHPExcel_Calculation_Exception(
 301                      $this->getWorksheet()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage()
 302                  );
 303              }
 304  
 305              if ($result === '#Not Yet Implemented') {
 306  //echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL;
 307                  return $this->_calculatedValue; // Fallback if calculation engine does not support the formula.
 308              }
 309  //echo 'Returning calculated value of '.$result.' for cell '.$this->getCoordinate().PHP_EOL;
 310              return $result;
 311          } elseif($this->_value instanceof PHPExcel_RichText) {
 312  //        echo 'Cell value for '.$this->getCoordinate().' is rich text: Returning data value of '.$this->_value.'<br />';
 313              return $this->_value->getPlainText();
 314          }
 315  //        echo 'Cell value for '.$this->getCoordinate().' is not a formula: Returning data value of '.$this->_value.'<br />';
 316          return $this->_value;
 317      }
 318  
 319      /**
 320       *    Set old calculated value (cached)
 321       *
 322       *    @param    mixed $pValue    Value
 323       *    @return    PHPExcel_Cell
 324       */
 325  	public function setCalculatedValue($pValue = NULL)
 326      {
 327          if ($pValue !== NULL) {
 328              $this->_calculatedValue = (is_numeric($pValue)) ? (float) $pValue : $pValue;
 329          }
 330  
 331          return $this->notifyCacheController();
 332      }
 333  
 334      /**
 335       *    Get old calculated value (cached)
 336       *    This returns the value last calculated by MS Excel or whichever spreadsheet program was used to
 337       *        create the original spreadsheet file.
 338       *    Note that this value is not guaranteed to refelect the actual calculated value because it is
 339       *        possible that auto-calculation was disabled in the original spreadsheet, and underlying data
 340       *        values used by the formula have changed since it was last calculated.
 341       *
 342       *    @return    mixed
 343       */
 344  	public function getOldCalculatedValue()
 345      {
 346          return $this->_calculatedValue;
 347      }
 348  
 349      /**
 350       *    Get cell data type
 351       *
 352       *    @return string
 353       */
 354  	public function getDataType()
 355      {
 356          return $this->_dataType;
 357      }
 358  
 359      /**
 360       *    Set cell data type
 361       *
 362       *    @param    string $pDataType
 363       *    @return    PHPExcel_Cell
 364       */
 365  	public function setDataType($pDataType = PHPExcel_Cell_DataType::TYPE_STRING)
 366      {
 367          if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2)
 368              $pDataType = PHPExcel_Cell_DataType::TYPE_STRING;
 369  
 370          $this->_dataType = $pDataType;
 371  
 372          return $this->notifyCacheController();
 373      }
 374  
 375      /**
 376       *  Identify if the cell contains a formula
 377       *
 378       *  @return boolean
 379       */
 380      public function isFormula()
 381      {
 382          return $this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA;
 383      }
 384  
 385      /**
 386       *    Does this cell contain Data validation rules?
 387       *
 388       *    @return    boolean
 389       *    @throws    PHPExcel_Exception
 390       */
 391  	public function hasDataValidation()
 392      {
 393          if (!isset($this->_parent)) {
 394              throw new PHPExcel_Exception('Cannot check for data validation when cell is not bound to a worksheet');
 395          }
 396  
 397          return $this->getWorksheet()->dataValidationExists($this->getCoordinate());
 398      }
 399  
 400      /**
 401       *    Get Data validation rules
 402       *
 403       *    @return    PHPExcel_Cell_DataValidation
 404       *    @throws    PHPExcel_Exception
 405       */
 406  	public function getDataValidation()
 407      {
 408          if (!isset($this->_parent)) {
 409              throw new PHPExcel_Exception('Cannot get data validation for cell that is not bound to a worksheet');
 410          }
 411  
 412          return $this->getWorksheet()->getDataValidation($this->getCoordinate());
 413      }
 414  
 415      /**
 416       *    Set Data validation rules
 417       *
 418       *    @param    PHPExcel_Cell_DataValidation    $pDataValidation
 419       *    @return    PHPExcel_Cell
 420       *    @throws    PHPExcel_Exception
 421       */
 422  	public function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation = NULL)
 423      {
 424          if (!isset($this->_parent)) {
 425              throw new PHPExcel_Exception('Cannot set data validation for cell that is not bound to a worksheet');
 426          }
 427  
 428          $this->getWorksheet()->setDataValidation($this->getCoordinate(), $pDataValidation);
 429  
 430          return $this->notifyCacheController();
 431      }
 432  
 433      /**
 434       *    Does this cell contain a Hyperlink?
 435       *
 436       *    @return boolean
 437       *    @throws    PHPExcel_Exception
 438       */
 439  	public function hasHyperlink()
 440      {
 441          if (!isset($this->_parent)) {
 442              throw new PHPExcel_Exception('Cannot check for hyperlink when cell is not bound to a worksheet');
 443          }
 444  
 445          return $this->getWorksheet()->hyperlinkExists($this->getCoordinate());
 446      }
 447  
 448      /**
 449       *    Get Hyperlink
 450       *
 451       *    @return    PHPExcel_Cell_Hyperlink
 452       *    @throws    PHPExcel_Exception
 453       */
 454  	public function getHyperlink()
 455      {
 456          if (!isset($this->_parent)) {
 457              throw new PHPExcel_Exception('Cannot get hyperlink for cell that is not bound to a worksheet');
 458          }
 459  
 460          return $this->getWorksheet()->getHyperlink($this->getCoordinate());
 461      }
 462  
 463      /**
 464       *    Set Hyperlink
 465       *
 466       *    @param    PHPExcel_Cell_Hyperlink    $pHyperlink
 467       *    @return    PHPExcel_Cell
 468       *    @throws    PHPExcel_Exception
 469       */
 470  	public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = NULL)
 471      {
 472          if (!isset($this->_parent)) {
 473              throw new PHPExcel_Exception('Cannot set hyperlink for cell that is not bound to a worksheet');
 474          }
 475  
 476          $this->getWorksheet()->setHyperlink($this->getCoordinate(), $pHyperlink);
 477  
 478          return $this->notifyCacheController();
 479      }
 480  
 481      /**
 482       *    Get parent worksheet
 483       *
 484       *    @return PHPExcel_CachedObjectStorage_CacheBase
 485       */
 486  	public function getParent() {
 487          return $this->_parent;
 488      }
 489  
 490      /**
 491       *    Get parent worksheet
 492       *
 493       *    @return PHPExcel_Worksheet
 494       */
 495  	public function getWorksheet() {
 496          return $this->_parent->getParent();
 497      }
 498  
 499      /**
 500       *    Get cell style
 501       *
 502       *    @return    PHPExcel_Style
 503       */
 504  	public function getStyle()
 505      {
 506          return $this->getWorksheet()->getParent()->getCellXfByIndex($this->getXfIndex());
 507      }
 508  
 509      /**
 510       *    Re-bind parent
 511       *
 512       *    @param    PHPExcel_Worksheet $parent
 513       *    @return    PHPExcel_Cell
 514       */
 515  	public function rebindParent(PHPExcel_Worksheet $parent) {
 516          $this->_parent = $parent->getCellCacheController();
 517  
 518          return $this->notifyCacheController();
 519      }
 520  
 521      /**
 522       *    Is cell in a specific range?
 523       *
 524       *    @param    string    $pRange        Cell range (e.g. A1:A1)
 525       *    @return    boolean
 526       */
 527  	public function isInRange($pRange = 'A1:A1')
 528      {
 529          list($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange);
 530  
 531          // Translate properties
 532          $myColumn    = self::columnIndexFromString($this->getColumn());
 533          $myRow        = $this->getRow();
 534  
 535          // Verify if cell is in range
 536          return (($rangeStart[0] <= $myColumn) && ($rangeEnd[0] >= $myColumn) &&
 537                  ($rangeStart[1] <= $myRow) && ($rangeEnd[1] >= $myRow)
 538                 );
 539      }
 540  
 541      /**
 542       *    Coordinate from string
 543       *
 544       *    @param    string    $pCoordinateString
 545       *    @return    array    Array containing column and row (indexes 0 and 1)
 546       *    @throws    PHPExcel_Exception
 547       */
 548  	public static function coordinateFromString($pCoordinateString = 'A1')
 549      {
 550          if (preg_match("/^([$]?[A-Z]{1,3})([$]?\d{1,7})$/", $pCoordinateString, $matches)) {
 551              return array($matches[1],$matches[2]);
 552          } elseif ((strpos($pCoordinateString,':') !== FALSE) || (strpos($pCoordinateString,',') !== FALSE)) {
 553              throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells');
 554          } elseif ($pCoordinateString == '') {
 555              throw new PHPExcel_Exception('Cell coordinate can not be zero-length string');
 556          }
 557  
 558          throw new PHPExcel_Exception('Invalid cell coordinate '.$pCoordinateString);
 559      }
 560  
 561      /**
 562       *    Make string row, column or cell coordinate absolute
 563       *
 564       *    @param    string    $pCoordinateString        e.g. 'A' or '1' or 'A1'
 565       *                    Note that this value can be a row or column reference as well as a cell reference
 566       *    @return    string    Absolute coordinate        e.g. '$A' or '$1' or '$A$1'
 567       *    @throws    PHPExcel_Exception
 568       */
 569  	public static function absoluteReference($pCoordinateString = 'A1')
 570      {
 571          if (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) {
 572              // Split out any worksheet name from the reference
 573              $worksheet = '';
 574              $cellAddress = explode('!',$pCoordinateString);
 575              if (count($cellAddress) > 1) {
 576                  list($worksheet,$pCoordinateString) = $cellAddress;
 577              }
 578              if ($worksheet > '')    $worksheet .= '!';
 579  
 580              // Create absolute coordinate
 581              if (ctype_digit($pCoordinateString)) {
 582                  return $worksheet . '$' . $pCoordinateString;
 583              } elseif (ctype_alpha($pCoordinateString)) {
 584                  return $worksheet . '$' . strtoupper($pCoordinateString);
 585              }
 586              return $worksheet . self::absoluteCoordinate($pCoordinateString);
 587          }
 588  
 589          throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells');
 590      }
 591  
 592      /**
 593       *    Make string coordinate absolute
 594       *
 595       *    @param    string    $pCoordinateString        e.g. 'A1'
 596       *    @return    string    Absolute coordinate        e.g. '$A$1'
 597       *    @throws    PHPExcel_Exception
 598       */
 599  	public static function absoluteCoordinate($pCoordinateString = 'A1')
 600      {
 601          if (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) {
 602              // Split out any worksheet name from the coordinate
 603              $worksheet = '';
 604              $cellAddress = explode('!',$pCoordinateString);
 605              if (count($cellAddress) > 1) {
 606                  list($worksheet,$pCoordinateString) = $cellAddress;
 607              }
 608              if ($worksheet > '')    $worksheet .= '!';
 609  
 610              // Create absolute coordinate
 611              list($column, $row) = self::coordinateFromString($pCoordinateString);
 612              $column = ltrim($column,'$');
 613              $row = ltrim($row,'$');
 614              return $worksheet . '$' . $column . '$' . $row;
 615          }
 616  
 617          throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells');
 618      }
 619  
 620      /**
 621       *    Split range into coordinate strings
 622       *
 623       *    @param    string    $pRange        e.g. 'B4:D9' or 'B4:D9,H2:O11' or 'B4'
 624       *    @return    array    Array containg one or more arrays containing one or two coordinate strings
 625       *                                e.g. array('B4','D9') or array(array('B4','D9'),array('H2','O11'))
 626       *                                        or array('B4')
 627       */
 628  	public static function splitRange($pRange = 'A1:A1')
 629      {
 630          // Ensure $pRange is a valid range
 631          if(empty($pRange)) {
 632              $pRange = self::DEFAULT_RANGE;
 633          }
 634  
 635          $exploded = explode(',', $pRange);
 636          $counter = count($exploded);
 637          for ($i = 0; $i < $counter; ++$i) {
 638              $exploded[$i] = explode(':', $exploded[$i]);
 639          }
 640          return $exploded;
 641      }
 642  
 643      /**
 644       *    Build range from coordinate strings
 645       *
 646       *    @param    array    $pRange    Array containg one or more arrays containing one or two coordinate strings
 647       *    @return    string    String representation of $pRange
 648       *    @throws    PHPExcel_Exception
 649       */
 650  	public static function buildRange($pRange)
 651      {
 652          // Verify range
 653          if (!is_array($pRange) || empty($pRange) || !is_array($pRange[0])) {
 654              throw new PHPExcel_Exception('Range does not contain any information');
 655          }
 656  
 657          // Build range
 658          $imploded = array();
 659          $counter = count($pRange);
 660          for ($i = 0; $i < $counter; ++$i) {
 661              $pRange[$i] = implode(':', $pRange[$i]);
 662          }
 663          $imploded = implode(',', $pRange);
 664  
 665          return $imploded;
 666      }
 667  
 668      /**
 669       *    Calculate range boundaries
 670       *
 671       *    @param    string    $pRange        Cell range (e.g. A1:A1)
 672       *    @return    array    Range coordinates array(Start Cell, End Cell)
 673       *                    where Start Cell and End Cell are arrays (Column Number, Row Number)
 674       */
 675  	public static function rangeBoundaries($pRange = 'A1:A1')
 676      {
 677          // Ensure $pRange is a valid range
 678          if(empty($pRange)) {
 679              $pRange = self::DEFAULT_RANGE;
 680          }
 681  
 682          // Uppercase coordinate
 683          $pRange = strtoupper($pRange);
 684  
 685          // Extract range
 686          if (strpos($pRange, ':') === FALSE) {
 687              $rangeA = $rangeB = $pRange;
 688          } else {
 689              list($rangeA, $rangeB) = explode(':', $pRange);
 690          }
 691  
 692          // Calculate range outer borders
 693          $rangeStart = self::coordinateFromString($rangeA);
 694          $rangeEnd    = self::coordinateFromString($rangeB);
 695  
 696          // Translate column into index
 697          $rangeStart[0]    = self::columnIndexFromString($rangeStart[0]);
 698          $rangeEnd[0]    = self::columnIndexFromString($rangeEnd[0]);
 699  
 700          return array($rangeStart, $rangeEnd);
 701      }
 702  
 703      /**
 704       *    Calculate range dimension
 705       *
 706       *    @param    string    $pRange        Cell range (e.g. A1:A1)
 707       *    @return    array    Range dimension (width, height)
 708       */
 709  	public static function rangeDimension($pRange = 'A1:A1')
 710      {
 711          // Calculate range outer borders
 712          list($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange);
 713  
 714          return array( ($rangeEnd[0] - $rangeStart[0] + 1), ($rangeEnd[1] - $rangeStart[1] + 1) );
 715      }
 716  
 717      /**
 718       *    Calculate range boundaries
 719       *
 720       *    @param    string    $pRange        Cell range (e.g. A1:A1)
 721       *    @return    array    Range coordinates array(Start Cell, End Cell)
 722       *                    where Start Cell and End Cell are arrays (Column ID, Row Number)
 723       */
 724  	public static function getRangeBoundaries($pRange = 'A1:A1')
 725      {
 726          // Ensure $pRange is a valid range
 727          if(empty($pRange)) {
 728              $pRange = self::DEFAULT_RANGE;
 729          }
 730  
 731          // Uppercase coordinate
 732          $pRange = strtoupper($pRange);
 733  
 734          // Extract range
 735          if (strpos($pRange, ':') === FALSE) {
 736              $rangeA = $rangeB = $pRange;
 737          } else {
 738              list($rangeA, $rangeB) = explode(':', $pRange);
 739          }
 740  
 741          return array( self::coordinateFromString($rangeA), self::coordinateFromString($rangeB));
 742      }
 743  
 744      /**
 745       *    Column index from string
 746       *
 747       *    @param    string $pString
 748       *    @return    int Column index (base 1 !!!)
 749       */
 750  	public static function columnIndexFromString($pString = 'A')
 751      {
 752          //    Using a lookup cache adds a slight memory overhead, but boosts speed
 753          //    caching using a static within the method is faster than a class static,
 754          //        though it's additional memory overhead
 755          static $_indexCache = array();
 756  
 757          if (isset($_indexCache[$pString]))
 758              return $_indexCache[$pString];
 759  
 760          //    It's surprising how costly the strtoupper() and ord() calls actually are, so we use a lookup array rather than use ord()
 761          //        and make it case insensitive to get rid of the strtoupper() as well. Because it's a static, there's no significant
 762          //        memory overhead either
 763          static $_columnLookup = array(
 764              'A' => 1, 'B' => 2, 'C' => 3, 'D' => 4, 'E' => 5, 'F' => 6, 'G' => 7, 'H' => 8, 'I' => 9, 'J' => 10, 'K' => 11, 'L' => 12, 'M' => 13,
 765              'N' => 14, 'O' => 15, 'P' => 16, 'Q' => 17, 'R' => 18, 'S' => 19, 'T' => 20, 'U' => 21, 'V' => 22, 'W' => 23, 'X' => 24, 'Y' => 25, 'Z' => 26,
 766              'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5, 'f' => 6, 'g' => 7, 'h' => 8, 'i' => 9, 'j' => 10, 'k' => 11, 'l' => 12, 'm' => 13,
 767              'n' => 14, 'o' => 15, 'p' => 16, 'q' => 17, 'r' => 18, 's' => 19, 't' => 20, 'u' => 21, 'v' => 22, 'w' => 23, 'x' => 24, 'y' => 25, 'z' => 26
 768          );
 769  
 770          //    We also use the language construct isset() rather than the more costly strlen() function to match the length of $pString
 771          //        for improved performance
 772          if (isset($pString{0})) {
 773              if (!isset($pString{1})) {
 774                  $_indexCache[$pString] = $_columnLookup[$pString];
 775                  return $_indexCache[$pString];
 776              } elseif(!isset($pString{2})) {
 777                  $_indexCache[$pString] = $_columnLookup[$pString{0}] * 26 + $_columnLookup[$pString{1}];
 778                  return $_indexCache[$pString];
 779              } elseif(!isset($pString{3})) {
 780                  $_indexCache[$pString] = $_columnLookup[$pString{0}] * 676 + $_columnLookup[$pString{1}] * 26 + $_columnLookup[$pString{2}];
 781                  return $_indexCache[$pString];
 782              }
 783          }
 784          throw new PHPExcel_Exception("Column string index can not be " . ((isset($pString{0})) ? "longer than 3 characters" : "empty"));
 785      }
 786  
 787      /**
 788       *    String from columnindex
 789       *
 790       *    @param    int $pColumnIndex Column index (base 0 !!!)
 791       *    @return    string
 792       */
 793  	public static function stringFromColumnIndex($pColumnIndex = 0)
 794      {
 795          //    Using a lookup cache adds a slight memory overhead, but boosts speed
 796          //    caching using a static within the method is faster than a class static,
 797          //        though it's additional memory overhead
 798          static $_indexCache = array();
 799  
 800          if (!isset($_indexCache[$pColumnIndex])) {
 801              // Determine column string
 802              if ($pColumnIndex < 26) {
 803                  $_indexCache[$pColumnIndex] = chr(65 + $pColumnIndex);
 804              } elseif ($pColumnIndex < 702) {
 805                  $_indexCache[$pColumnIndex] = chr(64 + ($pColumnIndex / 26)) .
 806                                                chr(65 + $pColumnIndex % 26);
 807              } else {
 808                  $_indexCache[$pColumnIndex] = chr(64 + (($pColumnIndex - 26) / 676)) .
 809                                                chr(65 + ((($pColumnIndex - 26) % 676) / 26)) .
 810                                                chr(65 + $pColumnIndex % 26);
 811              }
 812          }
 813          return $_indexCache[$pColumnIndex];
 814      }
 815  
 816      /**
 817       *    Extract all cell references in range
 818       *
 819       *    @param    string    $pRange        Range (e.g. A1 or A1:C10 or A1:E10 A20:E25)
 820       *    @return    array    Array containing single cell references
 821       */
 822  	public static function extractAllCellReferencesInRange($pRange = 'A1') {
 823          // Returnvalue
 824          $returnValue = array();
 825  
 826          // Explode spaces
 827          $cellBlocks = explode(' ', str_replace('$', '', strtoupper($pRange)));
 828          foreach ($cellBlocks as $cellBlock) {
 829              // Single cell?
 830              if (strpos($cellBlock,':') === FALSE && strpos($cellBlock,',') === FALSE) {
 831                  $returnValue[] = $cellBlock;
 832                  continue;
 833              }
 834  
 835              // Range...
 836              $ranges = self::splitRange($cellBlock);
 837              foreach($ranges as $range) {
 838                  // Single cell?
 839                  if (!isset($range[1])) {
 840                      $returnValue[] = $range[0];
 841                      continue;
 842                  }
 843  
 844                  // Range...
 845                  list($rangeStart, $rangeEnd)    = $range;
 846                  sscanf($rangeStart,'%[A-Z]%d', $startCol, $startRow);
 847                  sscanf($rangeEnd,'%[A-Z]%d', $endCol, $endRow);
 848                  $endCol++;
 849  
 850                  // Current data
 851                  $currentCol    = $startCol;
 852                  $currentRow    = $startRow;
 853  
 854                  // Loop cells
 855                  while ($currentCol != $endCol) {
 856                      while ($currentRow <= $endRow) {
 857                          $returnValue[] = $currentCol.$currentRow;
 858                          ++$currentRow;
 859                      }
 860                      ++$currentCol;
 861                      $currentRow = $startRow;
 862                  }
 863              }
 864          }
 865  
 866          //    Sort the result by column and row
 867          $sortKeys = array();
 868          foreach (array_unique($returnValue) as $coord) {
 869              sscanf($coord,'%[A-Z]%d', $column, $row);
 870              $sortKeys[sprintf('%3s%09d',$column,$row)] = $coord;
 871          }
 872          ksort($sortKeys);
 873  
 874          // Return value
 875          return array_values($sortKeys);
 876      }
 877  
 878      /**
 879       * Compare 2 cells
 880       *
 881       * @param    PHPExcel_Cell    $a    Cell a
 882       * @param    PHPExcel_Cell    $b    Cell b
 883       * @return    int        Result of comparison (always -1 or 1, never zero!)
 884       */
 885  	public static function compareCells(PHPExcel_Cell $a, PHPExcel_Cell $b)
 886      {
 887          if ($a->getRow() < $b->getRow()) {
 888              return -1;
 889          } elseif ($a->getRow() > $b->getRow()) {
 890              return 1;
 891          } elseif (self::columnIndexFromString($a->getColumn()) < self::columnIndexFromString($b->getColumn())) {
 892              return -1;
 893          } else {
 894              return 1;
 895          }
 896      }
 897  
 898      /**
 899       * Get value binder to use
 900       *
 901       * @return PHPExcel_Cell_IValueBinder
 902       */
 903  	public static function getValueBinder() {
 904          if (self::$_valueBinder === NULL) {
 905              self::$_valueBinder = new PHPExcel_Cell_DefaultValueBinder();
 906          }
 907  
 908          return self::$_valueBinder;
 909      }
 910  
 911      /**
 912       * Set value binder to use
 913       *
 914       * @param PHPExcel_Cell_IValueBinder $binder
 915       * @throws PHPExcel_Exception
 916       */
 917  	public static function setValueBinder(PHPExcel_Cell_IValueBinder $binder = NULL) {
 918          if ($binder === NULL) {
 919              throw new PHPExcel_Exception("A PHPExcel_Cell_IValueBinder is required for PHPExcel to function correctly.");
 920          }
 921  
 922          self::$_valueBinder = $binder;
 923      }
 924  
 925      /**
 926       * Implement PHP __clone to create a deep clone, not just a shallow copy.
 927       */
 928  	public function __clone() {
 929          $vars = get_object_vars($this);
 930          foreach ($vars as $key => $value) {
 931              if ((is_object($value)) && ($key != '_parent')) {
 932                  $this->$key = clone $value;
 933              } else {
 934                  $this->$key = $value;
 935              }
 936          }
 937      }
 938  
 939      /**
 940       * Get index to cellXf
 941       *
 942       * @return int
 943       */
 944  	public function getXfIndex()
 945      {
 946          return $this->_xfIndex;
 947      }
 948  
 949      /**
 950       * Set index to cellXf
 951       *
 952       * @param int $pValue
 953       * @return PHPExcel_Cell
 954       */
 955  	public function setXfIndex($pValue = 0)
 956      {
 957          $this->_xfIndex = $pValue;
 958  
 959          return $this->notifyCacheController();
 960      }
 961  
 962      /**
 963       *    @deprecated        Since version 1.7.8 for planned changes to cell for array formula handling
 964       */
 965  	public function setFormulaAttributes($pAttributes)
 966      {
 967          $this->_formulaAttributes = $pAttributes;
 968          return $this;
 969      }
 970  
 971      /**
 972       *    @deprecated        Since version 1.7.8 for planned changes to cell for array formula handling
 973       */
 974  	public function getFormulaAttributes()
 975      {
 976          return $this->_formulaAttributes;
 977      }
 978  
 979      /**
 980       * Convert to string
 981       *
 982       * @return string
 983       */
 984  	public function __toString()
 985      {
 986          return (string) $this->getValue();
 987      }
 988  
 989  }
 990  


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