ILIAS  Release_4_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
Cell.php
Go to the documentation of this file.
1 <?php
30 if (!defined('PHPEXCEL_ROOT')) {
34  define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../');
35 }
36 
38 require_once PHPEXCEL_ROOT . 'PHPExcel/Cell/DataType.php';
39 
41 require_once PHPEXCEL_ROOT . 'PHPExcel/Cell/DataValidation.php';
42 
44 require_once PHPEXCEL_ROOT . 'PHPExcel/Cell/Hyperlink.php';
45 
47 require_once PHPEXCEL_ROOT . 'PHPExcel/Worksheet.php';
48 
50 require_once PHPEXCEL_ROOT . 'PHPExcel/Calculation.php';
51 
53 require_once PHPEXCEL_ROOT . 'PHPExcel/Cell/IValueBinder.php';
54 
56 require_once PHPEXCEL_ROOT . 'PHPExcel/Cell/DefaultValueBinder.php';
57 
59 require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/String.php';
60 
61 
70 {
76  private static $_valueBinder = null;
77 
83  private $_column;
84 
90  private $_row;
91 
97  private $_value;
98 
104  private $_calculatedValue = null;
105 
111  private $_dataType;
112 
118  private $_parent;
119 
125  private $_xfIndex;
126 
137  public function __construct($pColumn = 'A', $pRow = 1, $pValue = null, $pDataType = null, PHPExcel_Worksheet $pSheet = null)
138  {
139  // Set value binder?
140  if (is_null(self::$_valueBinder)) {
141  self::$_valueBinder = new PHPExcel_Cell_DefaultValueBinder();
142  }
143 
144  // Initialise cell coordinate
145  $this->_column = strtoupper($pColumn);
146  $this->_row = $pRow;
147 
148  // Initialise cell value
149  $this->_value = $pValue;
150 
151  // Set worksheet
152  $this->_parent = $pSheet;
153 
154  // Set datatype?
155  if (!is_null($pDataType)) {
156  $this->_dataType = $pDataType;
157  } else {
158  if (!self::getValueBinder()->bindValue($this, $pValue)) {
159  throw new Exception("Value could not be bound to cell.");
160  }
161  }
162 
163  // set default index to cellXf
164  $this->_xfIndex = 0;
165  }
166 
172  public function getColumn()
173  {
174  return strtoupper($this->_column);
175  }
176 
182  public function getRow()
183  {
184  return $this->_row;
185  }
186 
192  public function getCoordinate()
193  {
194  return $this->_column . $this->_row;
195  }
196 
202  public function getValue()
203  {
204  return $this->_value;
205  }
206 
215  public function setValue($pValue = null)
216  {
217  if (!self::getValueBinder()->bindValue($this, $pValue)) {
218  throw new Exception("Value could not be bound to cell.");
219  }
220  return $this;
221  }
222 
230  public function setValueExplicit($pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING)
231  {
232  // check strings that they are ok
233  // TODO: fix also for RichText
234  if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING && !($pValue instanceof PHPExcel_RichText)) {
235  // string must never be longer than 32,767 characters, truncate if necessary
236  $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 32767);
237 
238  // we require that newline is represented as "\n" in core, not as "\r\n" or "\r"
239  $pValue = str_replace(array("\r\n", "\r"), "\n", $pValue);
240  }
241 
242  $this->_value = $pValue;
243  $this->_dataType = $pDataType;
244  return $this;
245  }
246 
252  public function getCalculatedValue($resetLog=true)
253  {
254 // echo 'Cell '.$this->getCoordinate().' value is a '.$this->_dataType.' with a value of '.$this->getValue().'<br />';
255  if (!is_null($this->_calculatedValue) && $this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) {
256  try {
257 // echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value<br />';
258  $result = PHPExcel_Calculation::getInstance()->calculateCellValue($this,$resetLog);
259  } catch ( Exception $ex ) {
260 // echo 'Calculation Exception: '.$ex->getMessage().'<br />';
261  $result = '#N/A';
262  }
263 
264  if ((is_string($result)) && ($result == '#Not Yet Implemented')) {
265 // echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().'<br />';
266  return $this->_calculatedValue; // Fallback if calculation engine does not support the formula.
267  } else {
268 // echo 'Returning calculated value of '.$result.' for cell '.$this->getCoordinate().'<br />';
269  return $result;
270  }
271  }
272 
273  if (is_null($this->_value)) {
274 // echo 'Cell '.$this->getCoordinate().' has no value, formula or otherwise<br />';
275  return null;
276  } else if ($this->_dataType != PHPExcel_Cell_DataType::TYPE_FORMULA) {
277 // echo 'Cell value for '.$this->getCoordinate().' is not a formula: Returning data value of '.$this->_value.'<br />';
278  return $this->_value;
279  } else {
280 // echo 'Cell value is a formula: Calculating value<br />';
281  return PHPExcel_Calculation::getInstance()->calculateCellValue($this,$resetLog);
282  }
283  }
284 
291  public function setCalculatedValue($pValue = null)
292  {
293  if (!is_null($pValue)) {
294  $this->_calculatedValue = $pValue;
295  }
296  return $this;
297  }
298 
304  public function getOldCalculatedValue()
305  {
307  }
308 
314  public function getDataType()
315  {
316  return $this->_dataType;
317  }
318 
325  public function setDataType($pDataType = PHPExcel_Cell_DataType::TYPE_STRING)
326  {
327  $this->_dataType = $pDataType;
328  return $this;
329  }
330 
336  public function hasDataValidation()
337  {
338  if (!isset($this->_parent)) {
339  throw new Exception('Cannot check for data validation when cell is not bound to a worksheet');
340  }
341 
342  return $this->_parent->dataValidationExists($this->getCoordinate());
343  }
344 
350  public function getDataValidation()
351  {
352  if (!isset($this->_parent)) {
353  throw new Exception('Cannot get data validation for cell that is not bound to a worksheet');
354  }
355 
356  $dataValidation = $this->_parent->getDataValidation($this->getCoordinate());
357  return $dataValidation;
358  }
359 
367  public function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation = null)
368  {
369  if (!isset($this->_parent)) {
370  throw new Exception('Cannot set data validation for cell that is not bound to a worksheet');
371  }
372 
373  $this->_parent->setDataValidation($this->getCoordinate(), $pDataValidation);
374  return $this;
375  }
376 
382  public function hasHyperlink()
383  {
384  if (!isset($this->_parent)) {
385  throw new Exception('Cannot check for hyperlink when cell is not bound to a worksheet');
386  }
387 
388  return $this->_parent->hyperlinkExists($this->getCoordinate());
389  }
390 
397  public function getHyperlink()
398  {
399  if (!isset($this->_parent)) {
400  throw new Exception('Cannot get hyperlink for cell that is not bound to a worksheet');
401  }
402 
403  $hyperlink = $this->_parent->getHyperlink($this->getCoordinate());
404  return $hyperlink;
405  }
406 
414  public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = null)
415  {
416  if (!isset($this->_parent)) {
417  throw new Exception('Cannot set hyperlink for cell that is not bound to a worksheet');
418  }
419 
420  $this->_parent->setHyperlink($this->getCoordinate(), $pHyperlink);
421  return $this;
422  }
423 
429  public function getParent() {
430  return $this->_parent;
431  }
432 
439  public function rebindParent(PHPExcel_Worksheet $parent) {
440  $this->_parent = $parent;
441  return $this;
442  }
443 
450  public function isInRange($pRange = 'A1:A1')
451  {
452  // Uppercase coordinate
453  $pRange = strtoupper($pRange);
454 
455  // Extract range
456  $rangeA = '';
457  $rangeB = '';
458  if (strpos($pRange, ':') === false) {
459  $rangeA = $pRange;
460  $rangeB = $pRange;
461  } else {
462  list($rangeA, $rangeB) = explode(':', $pRange);
463  }
464 
465  // Calculate range outer borders
466  $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA);
467  $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB);
468 
469  // Translate column into index
470  $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1;
471  $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1;
472 
473  // Translate properties
474  $myColumn = PHPExcel_Cell::columnIndexFromString($this->getColumn()) - 1;
475  $myRow = $this->getRow();
476 
477  // Verify if cell is in range
478  return (
479  ($rangeStart[0] <= $myColumn && $rangeEnd[0] >= $myColumn) &&
480  ($rangeStart[1] <= $myRow && $rangeEnd[1] >= $myRow)
481  );
482  }
483 
491  public static function coordinateFromString($pCoordinateString = 'A1')
492  {
493  if (strpos($pCoordinateString,':') !== false) {
494  throw new Exception('Cell coordinate string can not be a range of cells.');
495  } else if ($pCoordinateString == '') {
496  throw new Exception('Cell coordinate can not be zero-length string.');
497  } else {
498  // Column
499  $column = '';
500 
501  // Row
502  $row = '';
503 
504  // Convert a cell reference
505  if (preg_match("/([$]?[A-Z]+)([$]?\d+)/", $pCoordinateString, $matches)) {
506  list(, $column, $row) = $matches;
507  }
508 
509  // Return array
510  return array($column, $row);
511  }
512  }
513 
521  public static function absoluteCoordinate($pCoordinateString = 'A1')
522  {
523  if (strpos($pCoordinateString,':') === false && strpos($pCoordinateString,',') === false) {
524  // Return value
525  $returnValue = '';
526 
527  // Create absolute coordinate
528  list($column, $row) = PHPExcel_Cell::coordinateFromString($pCoordinateString);
529  $returnValue = '$' . $column . '$' . $row;
530 
531  // Return
532  return $returnValue;
533  } else {
534  throw new Exception("Coordinate string should not be a cell range.");
535  }
536  }
537 
544  public static function splitRange($pRange = 'A1:A1')
545  {
546  $exploded = explode(',', $pRange);
547  for ($i = 0; $i < count($exploded); ++$i) {
548  $exploded[$i] = explode(':', $exploded[$i]);
549  }
550  return $exploded;
551  }
552 
560  public static function buildRange($pRange)
561  {
562  // Verify range
563  if (!is_array($pRange) || count($pRange) == 0 || !is_array($pRange[0])) {
564  throw new Exception('Range does not contain any information.');
565  }
566 
567  // Build range
568  $imploded = array();
569  for ($i = 0; $i < count($pRange); ++$i) {
570  $pRange[$i] = implode(':', $pRange[$i]);
571  }
572  $imploded = implode(',', $pRange);
573 
574  return $imploded;
575  }
576 
583  public static function rangeDimension($pRange = 'A1:A1')
584  {
585  // Uppercase coordinate
586  $pRange = strtoupper($pRange);
587 
588  // Extract range
589  $rangeA = '';
590  $rangeB = '';
591  if (strpos($pRange, ':') === false) {
592  $rangeA = $pRange;
593  $rangeB = $pRange;
594  } else {
595  list($rangeA, $rangeB) = explode(':', $pRange);
596  }
597 
598  // Calculate range outer borders
599  $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA);
600  $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB);
601 
602  // Translate column into index
603  $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]);
604  $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]);
605 
606  return array( ($rangeEnd[0] - $rangeStart[0] + 1), ($rangeEnd[1] - $rangeStart[1] + 1) );
607  }
608 
616  public static function columnIndexFromString($pString = 'A')
617  {
618  // Convert to uppercase
619  $pString = strtoupper($pString);
620 
621  $strLen = strlen($pString);
622  // Convert column to integer
623  if ($strLen == 1) {
624  return (ord($pString{0}) - 64);
625  } elseif ($strLen == 2) {
626  return $result = ((1 + (ord($pString{0}) - 65)) * 26) + (ord($pString{1}) - 64);
627  } elseif ($strLen == 3) {
628  return ((1 + (ord($pString{0}) - 65)) * 676) + ((1 + (ord($pString{1}) - 65)) * 26) + (ord($pString{2}) - 64);
629  } else {
630  throw new Exception("Column string index can not be " . ($strLen != 0 ? "longer than 3 characters" : "empty") . ".");
631  }
632  }
633 
640  public static function stringFromColumnIndex($pColumnIndex = 0)
641  {
642  // Determine column string
643  if ($pColumnIndex < 26) {
644  return chr(65 + $pColumnIndex);
645  }
646  return PHPExcel_Cell::stringFromColumnIndex((int)($pColumnIndex / 26) -1).chr(65 + $pColumnIndex%26) ;
647  }
648 
655  public static function extractAllCellReferencesInRange($pRange = 'A1') {
656  // Returnvalue
657  $returnValue = array();
658 
659  // Explode spaces
660  $aExplodeSpaces = explode(' ', str_replace('$', '', strtoupper($pRange)));
661  foreach ($aExplodeSpaces as $explodedSpaces) {
662  // Single cell?
663  if (strpos($explodedSpaces,':') === false && strpos($explodedSpaces,',') === false) {
664  $col = 'A';
665  $row = 1;
666  list($col, $row) = PHPExcel_Cell::coordinateFromString($explodedSpaces);
667 
668  if (strlen($col) <= 2) {
669  $returnValue[] = $explodedSpaces;
670  }
671 
672  continue;
673  }
674 
675  // Range...
676  $range = PHPExcel_Cell::splitRange($explodedSpaces);
677  for ($i = 0; $i < count($range); ++$i) {
678  // Single cell?
679  if (count($range[$i]) == 1) {
680  $col = 'A';
681  $row = 1;
682  list($col, $row) = PHPExcel_Cell::coordinateFromString($range[$i]);
683 
684  if (strlen($col) <= 2) {
685  $returnValue[] = $explodedSpaces;
686  }
687  }
688 
689  // Range...
690  $rangeStart = $rangeEnd = '';
691  $startingCol = $startingRow = $endingCol = $endingRow = 0;
692 
693  list($rangeStart, $rangeEnd) = $range[$i];
694  list($startingCol, $startingRow) = PHPExcel_Cell::coordinateFromString($rangeStart);
695  list($endingCol, $endingRow) = PHPExcel_Cell::coordinateFromString($rangeEnd);
696 
697  // Conversions...
698  $startingCol = PHPExcel_Cell::columnIndexFromString($startingCol);
699  $endingCol = PHPExcel_Cell::columnIndexFromString($endingCol);
700 
701  // Current data
702  $currentCol = --$startingCol;
703  $currentRow = $startingRow;
704 
705  // Loop cells
706  while ($currentCol < $endingCol) {
707  $loopColumn = PHPExcel_Cell::stringFromColumnIndex($currentCol);
708  while ($currentRow <= $endingRow) {
709  $returnValue[] = $loopColumn.$currentRow;
710  ++$currentRow;
711  }
712  ++$currentCol;
713  $currentRow = $startingRow;
714  }
715  }
716  }
717 
718  // Return value
719  return $returnValue;
720  }
721 
729  public static function compareCells(PHPExcel_Cell $a, PHPExcel_Cell $b)
730  {
731  if ($a->_row < $b->_row) {
732  return -1;
733  } elseif ($a->_row > $b->_row) {
734  return 1;
736  return -1;
737  } else {
738  return 1;
739  }
740  }
741 
747  public static function getValueBinder() {
748  return self::$_valueBinder;
749  }
750 
757  public static function setValueBinder(PHPExcel_Cell_IValueBinder $binder = null) {
758  if (is_null($binder)) {
759  throw new Exception("A PHPExcel_Cell_IValueBinder is required for PHPExcel to function correctly.");
760  }
761 
762  self::$_valueBinder = $binder;
763  }
764 
768  public function __clone() {
769  $vars = get_object_vars($this);
770  foreach ($vars as $key => $value) {
771  if (is_object($value)) {
772  $this->$key = clone $value;
773  } else {
774  $this->$key = $value;
775  }
776  }
777  }
778 
784  public function getXfIndex()
785  {
786  return $this->_xfIndex;
787  }
788 
795  public function setXfIndex($pValue = 0)
796  {
797  $this->_xfIndex = $pValue;
798  return $this;
799  }
800 
801 }