1033 lines
33 KiB
PHP
Executable File
1033 lines
33 KiB
PHP
Executable File
<?php
|
|
|
|
/**
|
|
* PHPExcel_Cell
|
|
*
|
|
* Copyright (c) 2006 - 2015 PHPExcel
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
* @category PHPExcel
|
|
* @package PHPExcel_Cell
|
|
* @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
|
|
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
|
* @version ##VERSION##, ##DATE##
|
|
*/
|
|
class PHPExcel_Cell
|
|
{
|
|
/**
|
|
* Default range variable constant
|
|
*
|
|
* @var string
|
|
*/
|
|
const DEFAULT_RANGE = 'A1:A1';
|
|
|
|
/**
|
|
* Value binder to use
|
|
*
|
|
* @var PHPExcel_Cell_IValueBinder
|
|
*/
|
|
private static $valueBinder;
|
|
|
|
/**
|
|
* Value of the cell
|
|
*
|
|
* @var mixed
|
|
*/
|
|
private $value;
|
|
|
|
/**
|
|
* Calculated value of the cell (used for caching)
|
|
* This returns the value last calculated by MS Excel or whichever spreadsheet program was used to
|
|
* create the original spreadsheet file.
|
|
* Note that this value is not guaranteed to reflect the actual calculated value because it is
|
|
* possible that auto-calculation was disabled in the original spreadsheet, and underlying data
|
|
* values used by the formula have changed since it was last calculated.
|
|
*
|
|
* @var mixed
|
|
*/
|
|
private $calculatedValue;
|
|
|
|
/**
|
|
* Type of the cell data
|
|
*
|
|
* @var string
|
|
*/
|
|
private $dataType;
|
|
|
|
/**
|
|
* Parent worksheet
|
|
*
|
|
* @var PHPExcel_CachedObjectStorage_CacheBase
|
|
*/
|
|
private $parent;
|
|
|
|
/**
|
|
* Index to cellXf
|
|
*
|
|
* @var int
|
|
*/
|
|
private $xfIndex = 0;
|
|
|
|
/**
|
|
* Attributes of the formula
|
|
*
|
|
*/
|
|
private $formulaAttributes;
|
|
|
|
|
|
/**
|
|
* Send notification to the cache controller
|
|
*
|
|
* @return void
|
|
**/
|
|
public function notifyCacheController()
|
|
{
|
|
$this->parent->updateCacheData($this);
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function detach()
|
|
{
|
|
$this->parent = null;
|
|
}
|
|
|
|
public function attach(PHPExcel_CachedObjectStorage_CacheBase $parent)
|
|
{
|
|
$this->parent = $parent;
|
|
}
|
|
|
|
|
|
/**
|
|
* Create a new Cell
|
|
*
|
|
* @param mixed $pValue
|
|
* @param string $pDataType
|
|
* @param PHPExcel_Worksheet $pSheet
|
|
* @throws PHPExcel_Exception
|
|
*/
|
|
public function __construct($pValue = null, $pDataType = null, PHPExcel_Worksheet $pSheet = null)
|
|
{
|
|
// Initialise cell value
|
|
$this->value = $pValue;
|
|
|
|
// Set worksheet cache
|
|
$this->parent = $pSheet->getCellCacheController();
|
|
|
|
// Set datatype?
|
|
if ($pDataType !== null) {
|
|
if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) {
|
|
$pDataType = PHPExcel_Cell_DataType::TYPE_STRING;
|
|
}
|
|
$this->dataType = $pDataType;
|
|
} elseif (!self::getValueBinder()->bindValue($this, $pValue)) {
|
|
throw new PHPExcel_Exception("Value could not be bound to cell.");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get cell coordinate column
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getColumn()
|
|
{
|
|
return $this->parent->getCurrentColumn();
|
|
}
|
|
|
|
/**
|
|
* Get cell coordinate row
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getRow()
|
|
{
|
|
return $this->parent->getCurrentRow();
|
|
}
|
|
|
|
/**
|
|
* Get cell coordinate
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getCoordinate()
|
|
{
|
|
return $this->parent->getCurrentAddress();
|
|
}
|
|
|
|
/**
|
|
* Get cell value
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function getValue()
|
|
{
|
|
return $this->value;
|
|
}
|
|
|
|
/**
|
|
* Get cell value with formatting
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getFormattedValue()
|
|
{
|
|
return (string) PHPExcel_Style_NumberFormat::toFormattedString(
|
|
$this->getCalculatedValue(),
|
|
$this->getStyle()
|
|
->getNumberFormat()->getFormatCode()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Set cell value
|
|
*
|
|
* Sets the value for a cell, automatically determining the datatype using the value binder
|
|
*
|
|
* @param mixed $pValue Value
|
|
* @return PHPExcel_Cell
|
|
* @throws PHPExcel_Exception
|
|
*/
|
|
public function setValue($pValue = null)
|
|
{
|
|
if (!self::getValueBinder()->bindValue($this, $pValue)) {
|
|
throw new PHPExcel_Exception("Value could not be bound to cell.");
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set the value for a cell, with the explicit data type passed to the method (bypassing any use of the value binder)
|
|
*
|
|
* @param mixed $pValue Value
|
|
* @param string $pDataType Explicit data type
|
|
* @return PHPExcel_Cell
|
|
* @throws PHPExcel_Exception
|
|
*/
|
|
public function setValueExplicit($pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING)
|
|
{
|
|
// set the value according to data type
|
|
switch ($pDataType) {
|
|
case PHPExcel_Cell_DataType::TYPE_NULL:
|
|
$this->value = $pValue;
|
|
break;
|
|
case PHPExcel_Cell_DataType::TYPE_STRING2:
|
|
$pDataType = PHPExcel_Cell_DataType::TYPE_STRING;
|
|
// no break
|
|
case PHPExcel_Cell_DataType::TYPE_STRING:
|
|
// Synonym for string
|
|
case PHPExcel_Cell_DataType::TYPE_INLINE:
|
|
// Rich text
|
|
$this->value = PHPExcel_Cell_DataType::checkString($pValue);
|
|
break;
|
|
case PHPExcel_Cell_DataType::TYPE_NUMERIC:
|
|
$this->value = (float) $pValue;
|
|
break;
|
|
case PHPExcel_Cell_DataType::TYPE_FORMULA:
|
|
$this->value = (string) $pValue;
|
|
break;
|
|
case PHPExcel_Cell_DataType::TYPE_BOOL:
|
|
$this->value = (bool) $pValue;
|
|
break;
|
|
case PHPExcel_Cell_DataType::TYPE_ERROR:
|
|
$this->value = PHPExcel_Cell_DataType::checkErrorCode($pValue);
|
|
break;
|
|
default:
|
|
throw new PHPExcel_Exception('Invalid datatype: ' . $pDataType);
|
|
break;
|
|
}
|
|
|
|
// set the datatype
|
|
$this->dataType = $pDataType;
|
|
|
|
return $this->notifyCacheController();
|
|
}
|
|
|
|
/**
|
|
* Get calculated cell value
|
|
*
|
|
* @deprecated Since version 1.7.8 for planned changes to cell for array formula handling
|
|
*
|
|
* @param boolean $resetLog Whether the calculation engine logger should be reset or not
|
|
* @return mixed
|
|
* @throws PHPExcel_Exception
|
|
*/
|
|
public function getCalculatedValue($resetLog = true)
|
|
{
|
|
//echo 'Cell '.$this->getCoordinate().' value is a '.$this->dataType.' with a value of '.$this->getValue().PHP_EOL;
|
|
if ($this->dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) {
|
|
try {
|
|
//echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value'.PHP_EOL;
|
|
$result = PHPExcel_Calculation::getInstance(
|
|
$this->getWorksheet()->getParent()
|
|
)->calculateCellValue($this, $resetLog);
|
|
//echo $this->getCoordinate().' calculation result is '.$result.PHP_EOL;
|
|
// We don't yet handle array returns
|
|
if (is_array($result)) {
|
|
while (is_array($result)) {
|
|
$result = array_pop($result);
|
|
}
|
|
}
|
|
} catch (PHPExcel_Exception $ex) {
|
|
if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->calculatedValue !== null)) {
|
|
//echo 'Returning fallback value of '.$this->calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL;
|
|
return $this->calculatedValue; // Fallback for calculations referencing external files.
|
|
}
|
|
//echo 'Calculation Exception: '.$ex->getMessage().PHP_EOL;
|
|
$result = '#N/A';
|
|
throw new PHPExcel_Calculation_Exception(
|
|
$this->getWorksheet()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage()
|
|
);
|
|
}
|
|
|
|
if ($result === '#Not Yet Implemented') {
|
|
//echo 'Returning fallback value of '.$this->calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL;
|
|
return $this->calculatedValue; // Fallback if calculation engine does not support the formula.
|
|
}
|
|
//echo 'Returning calculated value of '.$result.' for cell '.$this->getCoordinate().PHP_EOL;
|
|
return $result;
|
|
} elseif ($this->value instanceof PHPExcel_RichText) {
|
|
// echo 'Cell value for '.$this->getCoordinate().' is rich text: Returning data value of '.$this->value.'<br />';
|
|
return $this->value->getPlainText();
|
|
}
|
|
// echo 'Cell value for '.$this->getCoordinate().' is not a formula: Returning data value of '.$this->value.'<br />';
|
|
return $this->value;
|
|
}
|
|
|
|
/**
|
|
* Set old calculated value (cached)
|
|
*
|
|
* @param mixed $pValue Value
|
|
* @return PHPExcel_Cell
|
|
*/
|
|
public function setCalculatedValue($pValue = null)
|
|
{
|
|
if ($pValue !== null) {
|
|
$this->calculatedValue = (is_numeric($pValue)) ? (float) $pValue : $pValue;
|
|
}
|
|
|
|
return $this->notifyCacheController();
|
|
}
|
|
|
|
/**
|
|
* Get old calculated value (cached)
|
|
* This returns the value last calculated by MS Excel or whichever spreadsheet program was used to
|
|
* create the original spreadsheet file.
|
|
* Note that this value is not guaranteed to refelect the actual calculated value because it is
|
|
* possible that auto-calculation was disabled in the original spreadsheet, and underlying data
|
|
* values used by the formula have changed since it was last calculated.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function getOldCalculatedValue()
|
|
{
|
|
return $this->calculatedValue;
|
|
}
|
|
|
|
/**
|
|
* Get cell data type
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getDataType()
|
|
{
|
|
return $this->dataType;
|
|
}
|
|
|
|
/**
|
|
* Set cell data type
|
|
*
|
|
* @param string $pDataType
|
|
* @return PHPExcel_Cell
|
|
*/
|
|
public function setDataType($pDataType = PHPExcel_Cell_DataType::TYPE_STRING)
|
|
{
|
|
if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) {
|
|
$pDataType = PHPExcel_Cell_DataType::TYPE_STRING;
|
|
}
|
|
$this->dataType = $pDataType;
|
|
|
|
return $this->notifyCacheController();
|
|
}
|
|
|
|
/**
|
|
* Identify if the cell contains a formula
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public function isFormula()
|
|
{
|
|
return $this->dataType == PHPExcel_Cell_DataType::TYPE_FORMULA;
|
|
}
|
|
|
|
/**
|
|
* Does this cell contain Data validation rules?
|
|
*
|
|
* @return boolean
|
|
* @throws PHPExcel_Exception
|
|
*/
|
|
public function hasDataValidation()
|
|
{
|
|
if (!isset($this->parent)) {
|
|
throw new PHPExcel_Exception('Cannot check for data validation when cell is not bound to a worksheet');
|
|
}
|
|
|
|
return $this->getWorksheet()->dataValidationExists($this->getCoordinate());
|
|
}
|
|
|
|
/**
|
|
* Get Data validation rules
|
|
*
|
|
* @return PHPExcel_Cell_DataValidation
|
|
* @throws PHPExcel_Exception
|
|
*/
|
|
public function getDataValidation()
|
|
{
|
|
if (!isset($this->parent)) {
|
|
throw new PHPExcel_Exception('Cannot get data validation for cell that is not bound to a worksheet');
|
|
}
|
|
|
|
return $this->getWorksheet()->getDataValidation($this->getCoordinate());
|
|
}
|
|
|
|
/**
|
|
* Set Data validation rules
|
|
*
|
|
* @param PHPExcel_Cell_DataValidation $pDataValidation
|
|
* @return PHPExcel_Cell
|
|
* @throws PHPExcel_Exception
|
|
*/
|
|
public function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation = null)
|
|
{
|
|
if (!isset($this->parent)) {
|
|
throw new PHPExcel_Exception('Cannot set data validation for cell that is not bound to a worksheet');
|
|
}
|
|
|
|
$this->getWorksheet()->setDataValidation($this->getCoordinate(), $pDataValidation);
|
|
|
|
return $this->notifyCacheController();
|
|
}
|
|
|
|
/**
|
|
* Does this cell contain a Hyperlink?
|
|
*
|
|
* @return boolean
|
|
* @throws PHPExcel_Exception
|
|
*/
|
|
public function hasHyperlink()
|
|
{
|
|
if (!isset($this->parent)) {
|
|
throw new PHPExcel_Exception('Cannot check for hyperlink when cell is not bound to a worksheet');
|
|
}
|
|
|
|
return $this->getWorksheet()->hyperlinkExists($this->getCoordinate());
|
|
}
|
|
|
|
/**
|
|
* Get Hyperlink
|
|
*
|
|
* @return PHPExcel_Cell_Hyperlink
|
|
* @throws PHPExcel_Exception
|
|
*/
|
|
public function getHyperlink()
|
|
{
|
|
if (!isset($this->parent)) {
|
|
throw new PHPExcel_Exception('Cannot get hyperlink for cell that is not bound to a worksheet');
|
|
}
|
|
|
|
return $this->getWorksheet()->getHyperlink($this->getCoordinate());
|
|
}
|
|
|
|
/**
|
|
* Set Hyperlink
|
|
*
|
|
* @param PHPExcel_Cell_Hyperlink $pHyperlink
|
|
* @return PHPExcel_Cell
|
|
* @throws PHPExcel_Exception
|
|
*/
|
|
public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = null)
|
|
{
|
|
if (!isset($this->parent)) {
|
|
throw new PHPExcel_Exception('Cannot set hyperlink for cell that is not bound to a worksheet');
|
|
}
|
|
|
|
$this->getWorksheet()->setHyperlink($this->getCoordinate(), $pHyperlink);
|
|
|
|
return $this->notifyCacheController();
|
|
}
|
|
|
|
/**
|
|
* Get parent worksheet
|
|
*
|
|
* @return PHPExcel_CachedObjectStorage_CacheBase
|
|
*/
|
|
public function getParent()
|
|
{
|
|
return $this->parent;
|
|
}
|
|
|
|
/**
|
|
* Get parent worksheet
|
|
*
|
|
* @return PHPExcel_Worksheet
|
|
*/
|
|
|