@ -0,0 +1,3 @@ | |||||
/Build export-ignore | |||||
/unitTests export-ignore | |||||
README.md export-ignore |
@ -0,0 +1,9 @@ | |||||
build/PHPExcel.phar | |||||
unitTests/codeCoverage | |||||
analysis | |||||
## IDE support | |||||
*.buildpath | |||||
*.project | |||||
/.settings | |||||
/.idea |
@ -0,0 +1,29 @@ | |||||
language: php | |||||
php: | |||||
- 5.4 | |||||
- 5.5 | |||||
- 5.6 | |||||
- 7.0 | |||||
- hhvm | |||||
matrix: | |||||
allow_failures: | |||||
- php: hhvm | |||||
before_script: | |||||
## Packages | |||||
- sudo apt-get -qq update > /dev/null | |||||
## Composer | |||||
- composer self-update | |||||
- composer install --prefer-source --dev | |||||
- phpenv global "$TRAVIS_PHP_VERSION" | |||||
script: | |||||
## PHP_CodeSniffer | |||||
- ./vendor/bin/phpcs --report-width=200 --report-summary --report-full Classes/ unitTests/ --standard=PSR2 -n | |||||
## PHPUnit | |||||
- phpunit -c ./unitTests/ | |||||
notifications: | |||||
email: false |
@ -0,0 +1,289 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_IOFactory | |||||
* | |||||
* 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 | |||||
* @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_IOFactory | |||||
{ | |||||
/** | |||||
* Search locations | |||||
* | |||||
* @var array | |||||
* @access private | |||||
* @static | |||||
*/ | |||||
private static $searchLocations = array( | |||||
array( 'type' => 'IWriter', 'path' => 'PHPExcel/Writer/{0}.php', 'class' => 'PHPExcel_Writer_{0}' ), | |||||
array( 'type' => 'IReader', 'path' => 'PHPExcel/Reader/{0}.php', 'class' => 'PHPExcel_Reader_{0}' ) | |||||
); | |||||
/** | |||||
* Autoresolve classes | |||||
* | |||||
* @var array | |||||
* @access private | |||||
* @static | |||||
*/ | |||||
private static $autoResolveClasses = array( | |||||
'Excel2007', | |||||
'Excel5', | |||||
'Excel2003XML', | |||||
'OOCalc', | |||||
'SYLK', | |||||
'Gnumeric', | |||||
'HTML', | |||||
'CSV', | |||||
); | |||||
/** | |||||
* Private constructor for PHPExcel_IOFactory | |||||
*/ | |||||
private function __construct() | |||||
{ | |||||
} | |||||
/** | |||||
* Get search locations | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @return array | |||||
*/ | |||||
public static function getSearchLocations() | |||||
{ | |||||
return self::$searchLocations; | |||||
} | |||||
/** | |||||
* Set search locations | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param array $value | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function setSearchLocations($value) | |||||
{ | |||||
if (is_array($value)) { | |||||
self::$searchLocations = $value; | |||||
} else { | |||||
throw new PHPExcel_Reader_Exception('Invalid parameter passed.'); | |||||
} | |||||
} | |||||
/** | |||||
* Add search location | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param string $type Example: IWriter | |||||
* @param string $location Example: PHPExcel/Writer/{0}.php | |||||
* @param string $classname Example: PHPExcel_Writer_{0} | |||||
*/ | |||||
public static function addSearchLocation($type = '', $location = '', $classname = '') | |||||
{ | |||||
self::$searchLocations[] = array( 'type' => $type, 'path' => $location, 'class' => $classname ); | |||||
} | |||||
/** | |||||
* Create PHPExcel_Writer_IWriter | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param PHPExcel $phpExcel | |||||
* @param string $writerType Example: Excel2007 | |||||
* @return PHPExcel_Writer_IWriter | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function createWriter(PHPExcel $phpExcel, $writerType = '') | |||||
{ | |||||
// Search type | |||||
$searchType = 'IWriter'; | |||||
// Include class | |||||
foreach (self::$searchLocations as $searchLocation) { | |||||
if ($searchLocation['type'] == $searchType) { | |||||
$className = str_replace('{0}', $writerType, $searchLocation['class']); | |||||
$instance = new $className($phpExcel); | |||||
if ($instance !== null) { | |||||
return $instance; | |||||
} | |||||
} | |||||
} | |||||
// Nothing found... | |||||
throw new PHPExcel_Reader_Exception("No $searchType found for type $writerType"); | |||||
} | |||||
/** | |||||
* Create PHPExcel_Reader_IReader | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param string $readerType Example: Excel2007 | |||||
* @return PHPExcel_Reader_IReader | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function createReader($readerType = '') | |||||
{ | |||||
// Search type | |||||
$searchType = 'IReader'; | |||||
// Include class | |||||
foreach (self::$searchLocations as $searchLocation) { | |||||
if ($searchLocation['type'] == $searchType) { | |||||
$className = str_replace('{0}', $readerType, $searchLocation['class']); | |||||
$instance = new $className(); | |||||
if ($instance !== null) { | |||||
return $instance; | |||||
} | |||||
} | |||||
} | |||||
// Nothing found... | |||||
throw new PHPExcel_Reader_Exception("No $searchType found for type $readerType"); | |||||
} | |||||
/** | |||||
* Loads PHPExcel from file using automatic PHPExcel_Reader_IReader resolution | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param string $pFilename The name of the spreadsheet file | |||||
* @return PHPExcel | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function load($pFilename) | |||||
{ | |||||
$reader = self::createReaderForFile($pFilename); | |||||
return $reader->load($pFilename); | |||||
} | |||||
/** | |||||
* Identify file type using automatic PHPExcel_Reader_IReader resolution | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param string $pFilename The name of the spreadsheet file to identify | |||||
* @return string | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function identify($pFilename) | |||||
{ | |||||
$reader = self::createReaderForFile($pFilename); | |||||
$className = get_class($reader); | |||||
$classType = explode('_', $className); | |||||
unset($reader); | |||||
return array_pop($classType); | |||||
} | |||||
/** | |||||
* Create PHPExcel_Reader_IReader for file using automatic PHPExcel_Reader_IReader resolution | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param string $pFilename The name of the spreadsheet file | |||||
* @return PHPExcel_Reader_IReader | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function createReaderForFile($pFilename) | |||||
{ | |||||
// First, lucky guess by inspecting file extension | |||||
$pathinfo = pathinfo($pFilename); | |||||
$extensionType = null; | |||||
if (isset($pathinfo['extension'])) { | |||||
switch (strtolower($pathinfo['extension'])) { | |||||
case 'xlsx': // Excel (OfficeOpenXML) Spreadsheet | |||||
case 'xlsm': // Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded) | |||||
case 'xltx': // Excel (OfficeOpenXML) Template | |||||
case 'xltm': // Excel (OfficeOpenXML) Macro Template (macros will be discarded) | |||||
$extensionType = 'Excel2007'; | |||||
break; | |||||
case 'xls': // Excel (BIFF) Spreadsheet | |||||
case 'xlt': // Excel (BIFF) Template | |||||
$extensionType = 'Excel5'; | |||||
break; | |||||
case 'ods': // Open/Libre Offic Calc | |||||
case 'ots': // Open/Libre Offic Calc Template | |||||
$extensionType = 'OOCalc'; | |||||
break; | |||||
case 'slk': | |||||
$extensionType = 'SYLK'; | |||||
break; | |||||
case 'xml': // Excel 2003 SpreadSheetML | |||||
$extensionType = 'Excel2003XML'; | |||||
break; | |||||
case 'gnumeric': | |||||
$extensionType = 'Gnumeric'; | |||||
break; | |||||
case 'htm': | |||||
case 'html': | |||||
$extensionType = 'HTML'; | |||||
break; | |||||
case 'csv': | |||||
// Do nothing | |||||
// We must not try to use CSV reader since it loads | |||||
// all files including Excel files etc. | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
if ($extensionType !== null) { | |||||
$reader = self::createReader($extensionType); | |||||
// Let's see if we are lucky | |||||
if (isset($reader) && $reader->canRead($pFilename)) { | |||||
return $reader; | |||||
} | |||||
} | |||||
} | |||||
// If we reach here then "lucky guess" didn't give any result | |||||
// Try walking through all the options in self::$autoResolveClasses | |||||
foreach (self::$autoResolveClasses as $autoResolveClass) { | |||||
// Ignore our original guess, we know that won't work | |||||
if ($autoResolveClass !== $extensionType) { | |||||
$reader = self::createReader($autoResolveClass); | |||||
if ($reader->canRead($pFilename)) { | |||||
return $reader; | |||||
} | |||||
} | |||||
} | |||||
throw new PHPExcel_Reader_Exception('Unable to identify a reader for this file'); | |||||
} | |||||
} |
@ -0,0 +1,81 @@ | |||||
<?php | |||||
PHPExcel_Autoloader::register(); | |||||
// As we always try to run the autoloader before anything else, we can use it to do a few | |||||
// simple checks and initialisations | |||||
//PHPExcel_Shared_ZipStreamWrapper::register(); | |||||
// check mbstring.func_overload | |||||
if (ini_get('mbstring.func_overload') & 2) { | |||||
throw new PHPExcel_Exception('Multibyte function overloading in PHP must be disabled for string functions (2).'); | |||||
} | |||||
PHPExcel_Shared_String::buildCharacterSets(); | |||||
/** | |||||
* PHPExcel | |||||
* | |||||
* 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 | |||||
* @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_Autoloader | |||||
{ | |||||
/** | |||||
* Register the Autoloader with SPL | |||||
* | |||||
*/ | |||||
public static function register() | |||||
{ | |||||
if (function_exists('__autoload')) { | |||||
// Register any existing autoloader function with SPL, so we don't get any clashes | |||||
spl_autoload_register('__autoload'); | |||||
} | |||||
// Register ourselves with SPL | |||||
if (version_compare(PHP_VERSION, '5.3.0') >= 0) { | |||||
return spl_autoload_register(array('PHPExcel_Autoloader', 'load'), true, true); | |||||
} else { | |||||
return spl_autoload_register(array('PHPExcel_Autoloader', 'load')); | |||||
} | |||||
} | |||||
/** | |||||
* Autoload a class identified by name | |||||
* | |||||
* @param string $pClassName Name of the object to load | |||||
*/ | |||||
public static function load($pClassName) | |||||
{ | |||||
if ((class_exists($pClassName, false)) || (strpos($pClassName, 'PHPExcel') !== 0)) { | |||||
// Either already loaded, or not a PHPExcel class request | |||||
return false; | |||||
} | |||||
$pClassFilePath = PHPEXCEL_ROOT . | |||||
str_replace('_', DIRECTORY_SEPARATOR, $pClassName) . | |||||
'.php'; | |||||
if ((file_exists($pClassFilePath) === false) || (is_readable($pClassFilePath) === false)) { | |||||
// Can't load | |||||
return false; | |||||
} | |||||
require($pClassFilePath); | |||||
} | |||||
} |
@ -0,0 +1,290 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CachedObjectStorage_APC | |||||
* | |||||
* 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_CachedObjectStorage | |||||
* @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_CachedObjectStorage_APC extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | |||||
{ | |||||
/** | |||||
* Prefix used to uniquely identify cache data for this worksheet | |||||
* | |||||
* @access private | |||||
* @var string | |||||
*/ | |||||
private $cachePrefix = null; | |||||
/** | |||||
* Cache timeout | |||||
* | |||||
* @access private | |||||
* @var integer | |||||
*/ | |||||
private $cacheTime = 600; | |||||
/** | |||||
* Store cell data in cache for the current cell object if it's "dirty", | |||||
* and the 'nullify' the current cell object | |||||
* | |||||
* @access private | |||||
* @return void | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
protected function storeData() | |||||
{ | |||||
if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | |||||
$this->currentObject->detach(); | |||||
if (!apc_store( | |||||
$this->cachePrefix . $this->currentObjectID . '.cache', | |||||
serialize($this->currentObject), | |||||
$this->cacheTime | |||||
)) { | |||||
$this->__destruct(); | |||||
throw new PHPExcel_Exception('Failed to store cell ' . $this->currentObjectID . ' in APC'); | |||||
} | |||||
$this->currentCellIsDirty = false; | |||||
} | |||||
$this->currentObjectID = $this->currentObject = null; | |||||
} | |||||
/** | |||||
* Add or Update a cell in cache identified by coordinate address | |||||
* | |||||
* @access public | |||||
* @param string $pCoord Coordinate address of the cell to update | |||||
* @param PHPExcel_Cell $cell Cell to update | |||||
* @return PHPExcel_Cell | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function addCacheData($pCoord, PHPExcel_Cell $cell) | |||||
{ | |||||
if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | |||||
$this->storeData(); | |||||
} | |||||
$this->cellCache[$pCoord] = true; | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = $cell; | |||||
$this->currentCellIsDirty = true; | |||||
return $cell; | |||||
} | |||||
/** | |||||
* Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? | |||||
* | |||||
* @access public | |||||
* @param string $pCoord Coordinate address of the cell to check | |||||
* @throws PHPExcel_Exception | |||||
* @return boolean | |||||
*/ | |||||
public function isDataSet($pCoord) | |||||
{ | |||||
// Check if the requested entry is the current object, or exists in the cache | |||||
if (parent::isDataSet($pCoord)) { | |||||
if ($this->currentObjectID == $pCoord) { | |||||
return true; | |||||
} | |||||
// Check if the requested entry still exists in apc | |||||
$success = apc_fetch($this->cachePrefix.$pCoord.'.cache'); | |||||
if ($success === false) { | |||||
// Entry no longer exists in APC, so clear it from the cache array | |||||
parent::deleteCacheData($pCoord); | |||||
throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache'); | |||||
} | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* Get cell at a specific coordinate | |||||
* | |||||
* @access public | |||||
* @param string $pCoord Coordinate of the cell | |||||
* @throws PHPExcel_Exception | |||||
* @return PHPExcel_Cell Cell that was found, or null if not found | |||||
*/ | |||||
public function getCacheData($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID) { | |||||
return $this->currentObject; | |||||
} | |||||
$this->storeData(); | |||||
// Check if the entry that has been requested actually exists | |||||
if (parent::isDataSet($pCoord)) { | |||||
$obj = apc_fetch($this->cachePrefix . $pCoord . '.cache'); | |||||
if ($obj === false) { | |||||
// Entry no longer exists in APC, so clear it from the cache array | |||||
parent::deleteCacheData($pCoord); | |||||
throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache'); | |||||
} | |||||
} else { | |||||
// Return null if requested entry doesn't exist in cache | |||||
return null; | |||||
} | |||||
// Set current entry to the requested entry | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = unserialize($obj); | |||||
// Re-attach this as the cell's parent | |||||
$this->currentObject->attach($this); | |||||
// Return requested entry | |||||
return $this->currentObject; | |||||
} | |||||
/** | |||||
* Get a list of all cell addresses currently held in cache | |||||
* | |||||
* @return string[] | |||||
*/ | |||||
public function getCellList() | |||||
{ | |||||
if ($this->currentObjectID !== null) { | |||||
$this->storeData(); | |||||
} | |||||
return parent::getCellList(); | |||||
} | |||||
/** | |||||
* Delete a cell in cache identified by coordinate address | |||||
* | |||||
* @access public | |||||
* @param string $pCoord Coordinate address of the cell to delete | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function deleteCacheData($pCoord) | |||||
{ | |||||
// Delete the entry from APC | |||||
apc_delete($this->cachePrefix.$pCoord.'.cache'); | |||||
// Delete the entry from our cell address array | |||||
parent::deleteCacheData($pCoord); | |||||
} | |||||
/** | |||||
* Clone the cell collection | |||||
* | |||||
* @access public | |||||
* @param PHPExcel_Worksheet $parent The new worksheet | |||||
* @throws PHPExcel_Exception | |||||
* @return void | |||||
*/ | |||||
public function copyCellCollection(PHPExcel_Worksheet $parent) | |||||
{ | |||||
parent::copyCellCollection($parent); | |||||
// Get a new id for the new file name | |||||
$baseUnique = $this->getUniqueID(); | |||||
$newCachePrefix = substr(md5($baseUnique), 0, 8) . '.'; | |||||
$cacheList = $this->getCellList(); | |||||
foreach ($cacheList as $cellID) { | |||||
if ($cellID != $this->currentObjectID) { | |||||
$obj = apc_fetch($this->cachePrefix . $cellID . '.cache'); | |||||
if ($obj === false) { | |||||
// Entry no longer exists in APC, so clear it from the cache array | |||||
parent::deleteCacheData($cellID); | |||||
throw new PHPExcel_Exception('Cell entry ' . $cellID . ' no longer exists in APC'); | |||||
} | |||||
if (!apc_store($newCachePrefix . $cellID . '.cache', $obj, $this->cacheTime)) { | |||||
$this->__destruct(); | |||||
throw new PHPExcel_Exception('Failed to store cell ' . $cellID . ' in APC'); | |||||
} | |||||
} | |||||
} | |||||
$this->cachePrefix = $newCachePrefix; | |||||
} | |||||
/** | |||||
* Clear the cell collection and disconnect from our parent | |||||
* | |||||
* @return void | |||||
*/ | |||||
public function unsetWorksheetCells() | |||||
{ | |||||
if ($this->currentObject !== null) { | |||||
$this->currentObject->detach(); | |||||
$this->currentObject = $this->currentObjectID = null; | |||||
} | |||||
// Flush the APC cache | |||||
$this->__destruct(); | |||||
$this->cellCache = array(); | |||||
// detach ourself from the worksheet, so that it can then delete this object successfully | |||||
$this->parent = null; | |||||
} | |||||
/** | |||||
* Initialise this new cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The worksheet for this cell collection | |||||
* @param array of mixed $arguments Additional initialisation arguments | |||||
*/ | |||||
public function __construct(PHPExcel_Worksheet $parent, $arguments) | |||||
{ | |||||
$cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; | |||||
if ($this->cachePrefix === null) { | |||||
$baseUnique = $this->getUniqueID(); | |||||
$this->cachePrefix = substr(md5($baseUnique), 0, 8) . '.'; | |||||
$this->cacheTime = $cacheTime; | |||||
parent::__construct($parent); | |||||
} | |||||
} | |||||
/** | |||||
* Destroy this cell collection | |||||
*/ | |||||
public function __destruct() | |||||
{ | |||||
$cacheList = $this->getCellList(); | |||||
foreach ($cacheList as $cellID) { | |||||
apc_delete($this->cachePrefix . $cellID . '.cache'); | |||||
} | |||||
} | |||||
/** | |||||
* Identify whether the caching method is currently available | |||||
* Some methods are dependent on the availability of certain extensions being enabled in the PHP build | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public static function cacheMethodIsAvailable() | |||||
{ | |||||
if (!function_exists('apc_store')) { | |||||
return false; | |||||
} | |||||
if (apc_sma_info() === false) { | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
} |
@ -0,0 +1,368 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CachedObjectStorage_CacheBase | |||||
* | |||||
* 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_CachedObjectStorage | |||||
* @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## | |||||
*/ | |||||
abstract class PHPExcel_CachedObjectStorage_CacheBase | |||||
{ | |||||
/** | |||||
* Parent worksheet | |||||
* | |||||
* @var PHPExcel_Worksheet | |||||
*/ | |||||
protected $parent; | |||||
/** | |||||
* The currently active Cell | |||||
* | |||||
* @var PHPExcel_Cell | |||||
*/ | |||||
protected $currentObject = null; | |||||
/** | |||||
* Coordinate address of the currently active Cell | |||||
* | |||||
* @var string | |||||
*/ | |||||
protected $currentObjectID = null; | |||||
/** | |||||
* Flag indicating whether the currently active Cell requires saving | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
protected $currentCellIsDirty = true; | |||||
/** | |||||
* An array of cells or cell pointers for the worksheet cells held in this cache, | |||||
* and indexed by their coordinate address within the worksheet | |||||
* | |||||
* @var array of mixed | |||||
*/ | |||||
protected $cellCache = array(); | |||||
/** | |||||
* Initialise this new cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The worksheet for this cell collection | |||||
*/ | |||||
public function __construct(PHPExcel_Worksheet $parent) | |||||
{ | |||||
// Set our parent worksheet. | |||||
// This is maintained within the cache controller to facilitate re-attaching it to PHPExcel_Cell objects when | |||||
// they are woken from a serialized state | |||||
$this->parent = $parent; | |||||
} | |||||
/** | |||||
* Return the parent worksheet for this cell collection | |||||
* | |||||
* @return PHPExcel_Worksheet | |||||
*/ | |||||
public function getParent() | |||||
{ | |||||
return $this->parent; | |||||
} | |||||
/** | |||||
* Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to check | |||||
* @return boolean | |||||
*/ | |||||
public function isDataSet($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID) { | |||||
return true; | |||||
} | |||||
// Check if the requested entry exists in the cache | |||||
return isset($this->cellCache[$pCoord]); | |||||
} | |||||
/** | |||||
* Move a cell object from one address to another | |||||
* | |||||
* @param string $fromAddress Current address of the cell to move | |||||
* @param string $toAddress Destination address of the cell to move | |||||
* @return boolean | |||||
*/ | |||||
public function moveCell($fromAddress, $toAddress) | |||||
{ | |||||
if ($fromAddress === $this->currentObjectID) { | |||||
$this->currentObjectID = $toAddress; | |||||
} | |||||
$this->currentCellIsDirty = true; | |||||
if (isset($this->cellCache[$fromAddress])) { | |||||
$this->cellCache[$toAddress] = &$this->cellCache[$fromAddress]; | |||||
unset($this->cellCache[$fromAddress]); | |||||
} | |||||
return true; | |||||
} | |||||
/** | |||||
* Add or Update a cell in cache | |||||
* | |||||
* @param PHPExcel_Cell $cell Cell to update | |||||
* @return PHPExcel_Cell | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function updateCacheData(PHPExcel_Cell $cell) | |||||
{ | |||||
return $this->addCacheData($cell->getCoordinate(), $cell); | |||||
} | |||||
/** | |||||
* Delete a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to delete | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function deleteCacheData($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID && !is_null($this->currentObject)) { | |||||
$this->currentObject->detach(); | |||||
$this->currentObjectID = $this->currentObject = null; | |||||
} | |||||
if (is_object($this->cellCache[$pCoord])) { | |||||
$this->cellCache[$pCoord]->detach(); | |||||
unset($this->cellCache[$pCoord]); | |||||
} | |||||
$this->currentCellIsDirty = false; | |||||
} | |||||
/** | |||||
* Get a list of all cell addresses currently held in cache | |||||
* | |||||
* @return string[] | |||||
*/ | |||||
public function getCellList() | |||||
{ | |||||
return array_keys($this->cellCache); | |||||
} | |||||
/** | |||||
* Sort the list of all cell addresses currently held in cache by row and column | |||||
* | |||||
* @return string[] | |||||
*/ | |||||
public function getSortedCellList() | |||||
{ | |||||
$sortKeys = array(); | |||||
foreach ($this->getCellList() as $coord) { | |||||
sscanf($coord, '%[A-Z]%d', $column, $row); | |||||
$sortKeys[sprintf('%09d%3s', $row, $column)] = $coord; | |||||
} | |||||
ksort($sortKeys); | |||||
return array_values($sortKeys); | |||||
} | |||||
/** | |||||
* Get highest worksheet column and highest row that have cell records | |||||
* | |||||
* @return array Highest column name and highest row number | |||||
*/ | |||||
public function getHighestRowAndColumn() | |||||
{ | |||||
// Lookup highest column and highest row | |||||
$col = array('A' => '1A'); | |||||
$row = array(1); | |||||
foreach ($this->getCellList() as $coord) { | |||||
sscanf($coord, '%[A-Z]%d', $c, $r); | |||||
$row[$r] = $r; | |||||
$col[$c] = strlen($c).$c; | |||||
} | |||||
if (!empty($row)) { | |||||
// Determine highest column and row | |||||
$highestRow = max($row); | |||||
$highestColumn = substr(max($col), 1); | |||||
} | |||||
return array( | |||||
'row' => $highestRow, | |||||
'column' => $highestColumn | |||||
); | |||||
} | |||||
/** | |||||
* Return the cell address of the currently active cell object | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getCurrentAddress() | |||||
{ | |||||
return $this->currentObjectID; | |||||
} | |||||
/** | |||||
* Return the column address of the currently active cell object | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getCurrentColumn() | |||||
{ | |||||
sscanf($this->currentObjectID, '%[A-Z]%d', $column, $row); | |||||
return $column; | |||||
} | |||||
/** | |||||
* Return the row address of the currently active cell object | |||||
* | |||||
* @return integer | |||||
*/ | |||||
public function getCurrentRow() | |||||
{ | |||||
sscanf($this->currentObjectID, '%[A-Z]%d', $column, $row); | |||||
return (integer) $row; | |||||
} | |||||
/** | |||||
* Get highest worksheet column | |||||
* | |||||
* @param string $row Return the highest column for the specified row, | |||||
* or the highest column of any row if no row number is passed | |||||
* @return string Highest column name | |||||
*/ | |||||
public function getHighestColumn($row = null) | |||||
{ | |||||
if ($row == null) { | |||||
$colRow = $this->getHighestRowAndColumn(); | |||||
return $colRow['column']; | |||||
} | |||||
$columnList = array(1); | |||||
foreach ($this->getCellList() as $coord) { | |||||
sscanf($coord, '%[A-Z]%d', $c, $r); | |||||
if ($r != $row) { | |||||
continue; | |||||
} | |||||
$columnList[] = PHPExcel_Cell::columnIndexFromString($c); | |||||
} | |||||
return PHPExcel_Cell::stringFromColumnIndex(max($columnList) - 1); | |||||
} | |||||
/** | |||||
* Get highest worksheet row | |||||
* | |||||
* @param string $column Return the highest row for the specified column, | |||||
* or the highest row of any column if no column letter is passed | |||||
* @return int Highest row number | |||||
*/ | |||||
public function getHighestRow($column = null) | |||||
{ | |||||
if ($column == null) { | |||||
$colRow = $this->getHighestRowAndColumn(); | |||||
return $colRow['row']; | |||||
} | |||||
$rowList = array(0); | |||||
foreach ($this->getCellList() as $coord) { | |||||
sscanf($coord, '%[A-Z]%d', $c, $r); | |||||
if ($c != $column) { | |||||
continue; | |||||
} | |||||
$rowList[] = $r; | |||||
} | |||||
return max($rowList); | |||||
} | |||||
/** | |||||
* Generate a unique ID for cache referencing | |||||
* | |||||
* @return string Unique Reference | |||||
*/ | |||||
protected function getUniqueID() | |||||
{ | |||||
if (function_exists('posix_getpid')) { | |||||
$baseUnique = posix_getpid(); | |||||
} else { | |||||
$baseUnique = mt_rand(); | |||||
} | |||||
return uniqid($baseUnique, true); | |||||
} | |||||
/** | |||||
* Clone the cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The new worksheet | |||||
* @return void | |||||
*/ | |||||
public function copyCellCollection(PHPExcel_Worksheet $parent) | |||||
{ | |||||
$this->currentCellIsDirty; | |||||
$this->storeData(); | |||||
$this->parent = $parent; | |||||
if (($this->currentObject !== null) && (is_object($this->currentObject))) { | |||||
$this->currentObject->attach($this); | |||||
} | |||||
} // function copyCellCollection() | |||||
/** | |||||
* Remove a row, deleting all cells in that row | |||||
* | |||||
* @param string $row Row number to remove | |||||
* @return void | |||||
*/ | |||||
public function removeRow($row) | |||||
{ | |||||
foreach ($this->getCellList() as $coord) { | |||||
sscanf($coord, '%[A-Z]%d', $c, $r); | |||||
if ($r == $row) { | |||||
$this->deleteCacheData($coord); | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Remove a column, deleting all cells in that column | |||||
* | |||||
* @param string $column Column ID to remove | |||||
* @return void | |||||
*/ | |||||
public function removeColumn($column) | |||||
{ | |||||
foreach ($this->getCellList() as $coord) { | |||||
sscanf($coord, '%[A-Z]%d', $c, $r); | |||||
if ($c == $column) { | |||||
$this->deleteCacheData($coord); | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Identify whether the caching method is currently available | |||||
* Some methods are dependent on the availability of certain extensions being enabled in the PHP build | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public static function cacheMethodIsAvailable() | |||||
{ | |||||
return true; | |||||
} | |||||
} |
@ -0,0 +1,208 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CachedObjectStorage_DiscISAM | |||||
* | |||||
* 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_CachedObjectStorage | |||||
* @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_CachedObjectStorage_DiscISAM extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | |||||
{ | |||||
/** | |||||
* Name of the file for this cache | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $fileName = null; | |||||
/** | |||||
* File handle for this cache file | |||||
* | |||||
* @var resource | |||||
*/ | |||||
private $fileHandle = null; | |||||
/** | |||||
* Directory/Folder where the cache file is located | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $cacheDirectory = null; | |||||
/** | |||||
* Store cell data in cache for the current cell object if it's "dirty", | |||||
* and the 'nullify' the current cell object | |||||
* | |||||
* @return void | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
protected function storeData() | |||||
{ | |||||
if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | |||||
$this->currentObject->detach(); | |||||
fseek($this->fileHandle, 0, SEEK_END); | |||||
$this->cellCache[$this->currentObjectID] = array( | |||||
'ptr' => ftell($this->fileHandle), | |||||
'sz' => fwrite($this->fileHandle, serialize($this->currentObject)) | |||||
); | |||||
$this->currentCellIsDirty = false; | |||||
} | |||||
$this->currentObjectID = $this->currentObject = null; | |||||
} | |||||
/** | |||||
* Add or Update a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to update | |||||
* @param PHPExcel_Cell $cell Cell to update | |||||
* @return PHPExcel_Cell | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function addCacheData($pCoord, PHPExcel_Cell $cell) | |||||
{ | |||||
if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | |||||
$this->storeData(); | |||||
} | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = $cell; | |||||
$this->currentCellIsDirty = true; | |||||
return $cell; | |||||
} | |||||
/** | |||||
* Get cell at a specific coordinate | |||||
* | |||||
* @param string $pCoord Coordinate of the cell | |||||
* @throws PHPExcel_Exception | |||||
* @return PHPExcel_Cell Cell that was found, or null if not found | |||||
*/ | |||||
public function getCacheData($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID) { | |||||
return $this->currentObject; | |||||
} | |||||
$this->storeData(); | |||||
// Check if the entry that has been requested actually exists | |||||
if (!isset($this->cellCache[$pCoord])) { | |||||
// Return null if requested entry doesn't exist in cache | |||||
return null; | |||||
} | |||||
// Set current entry to the requested entry | |||||
$this->currentObjectID = $pCoord; | |||||
fseek($this->fileHandle, $this->cellCache[$pCoord]['ptr']); | |||||
$this->currentObject = unserialize(fread($this->fileHandle, $this->cellCache[$pCoord]['sz'])); | |||||
// Re-attach this as the cell's parent | |||||
$this->currentObject->attach($this); | |||||
// Return requested entry | |||||
return $this->currentObject; | |||||
} | |||||
/** | |||||
* Get a list of all cell addresses currently held in cache | |||||
* | |||||
* @return string[] | |||||
*/ | |||||
public function getCellList() | |||||
{ | |||||
if ($this->currentObjectID !== null) { | |||||
$this->storeData(); | |||||
} | |||||
return parent::getCellList(); | |||||
} | |||||
/** | |||||
* Clone the cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The new worksheet | |||||
*/ | |||||
public function copyCellCollection(PHPExcel_Worksheet $parent) | |||||
{ | |||||
parent::copyCellCollection($parent); | |||||
// Get a new id for the new file name | |||||
$baseUnique = $this->getUniqueID(); | |||||
$newFileName = $this->cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache'; | |||||
// Copy the existing cell cache file | |||||
copy($this->fileName, $newFileName); | |||||
$this->fileName = $newFileName; | |||||
// Open the copied cell cache file | |||||
$this->fileHandle = fopen($this->fileName, 'a+'); | |||||
} | |||||
/** | |||||
* Clear the cell collection and disconnect from our parent | |||||
* | |||||
*/ | |||||
public function unsetWorksheetCells() | |||||
{ | |||||
if (!is_null($this->currentObject)) { | |||||
$this->currentObject->detach(); | |||||
$this->currentObject = $this->currentObjectID = null; | |||||
} | |||||
$this->cellCache = array(); | |||||
// detach ourself from the worksheet, so that it can then delete this object successfully | |||||
$this->parent = null; | |||||
// Close down the temporary cache file | |||||
$this->__destruct(); | |||||
} | |||||
/** | |||||
* Initialise this new cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The worksheet for this cell collection | |||||
* @param array of mixed $arguments Additional initialisation arguments | |||||
*/ | |||||
public function __construct(PHPExcel_Worksheet $parent, $arguments) | |||||
{ | |||||
$this->cacheDirectory = ((isset($arguments['dir'])) && ($arguments['dir'] !== null)) | |||||
? $arguments['dir'] | |||||
: PHPExcel_Shared_File::sys_get_temp_dir(); | |||||
parent::__construct($parent); | |||||
if (is_null($this->fileHandle)) { | |||||
$baseUnique = $this->getUniqueID(); | |||||
$this->fileName = $this->cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache'; | |||||
$this->fileHandle = fopen($this->fileName, 'a+'); | |||||
} | |||||
} | |||||
/** | |||||
* Destroy this cell collection | |||||
*/ | |||||
public function __destruct() | |||||
{ | |||||
if (!is_null($this->fileHandle)) { | |||||
fclose($this->fileHandle); | |||||
unlink($this->fileName); | |||||
} | |||||
$this->fileHandle = null; | |||||
} | |||||
} |
@ -0,0 +1,103 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CachedObjectStorage_ICache | |||||
* | |||||
* 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_CachedObjectStorage | |||||
* @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## | |||||
*/ | |||||
interface PHPExcel_CachedObjectStorage_ICache | |||||
{ | |||||
/** | |||||
* Add or Update a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to update | |||||
* @param PHPExcel_Cell $cell Cell to update | |||||
* @return PHPExcel_Cell | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function addCacheData($pCoord, PHPExcel_Cell $cell); | |||||
/** | |||||
* Add or Update a cell in cache | |||||
* | |||||
* @param PHPExcel_Cell $cell Cell to update | |||||
* @return PHPExcel_Cell | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function updateCacheData(PHPExcel_Cell $cell); | |||||
/** | |||||
* Fetch a cell from cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to retrieve | |||||
* @return PHPExcel_Cell Cell that was found, or null if not found | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function getCacheData($pCoord); | |||||
/** | |||||
* Delete a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to delete | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function deleteCacheData($pCoord); | |||||
/** | |||||
* Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to check | |||||
* @return boolean | |||||
*/ | |||||
public function isDataSet($pCoord); | |||||
/** | |||||
* Get a list of all cell addresses currently held in cache | |||||
* | |||||
* @return string[] | |||||
*/ | |||||
public function getCellList(); | |||||
/** | |||||
* Get the list of all cell addresses currently held in cache sorted by column and row | |||||
* | |||||
* @return string[] | |||||
*/ | |||||
public function getSortedCellList(); | |||||
/** | |||||
* Clone the cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The new worksheet | |||||
* @return void | |||||
*/ | |||||
public function copyCellCollection(PHPExcel_Worksheet $parent); | |||||
/** | |||||
* Identify whether the caching method is currently available | |||||
* Some methods are dependent on the availability of certain extensions being enabled in the PHP build | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public static function cacheMethodIsAvailable(); | |||||
} |
@ -0,0 +1,149 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CachedObjectStorage_Igbinary | |||||
* | |||||
* 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_CachedObjectStorage | |||||
* @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_CachedObjectStorage_Igbinary extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | |||||
{ | |||||
/** | |||||
* Store cell data in cache for the current cell object if it's "dirty", | |||||
* and the 'nullify' the current cell object | |||||
* | |||||
* @return void | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
protected function storeData() | |||||
{ | |||||
if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | |||||
$this->currentObject->detach(); | |||||
$this->cellCache[$this->currentObjectID] = igbinary_serialize($this->currentObject); | |||||
$this->currentCellIsDirty = false; | |||||
} | |||||
$this->currentObjectID = $this->currentObject = null; | |||||
} // function _storeData() | |||||
/** | |||||
* Add or Update a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to update | |||||
* @param PHPExcel_Cell $cell Cell to update | |||||
* @return PHPExcel_Cell | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function addCacheData($pCoord, PHPExcel_Cell $cell) | |||||
{ | |||||
if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | |||||
$this->storeData(); | |||||
} | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = $cell; | |||||
$this->currentCellIsDirty = true; | |||||
return $cell; | |||||
} // function addCacheData() | |||||
/** | |||||
* Get cell at a specific coordinate | |||||
* | |||||
* @param string $pCoord Coordinate of the cell | |||||
* @throws PHPExcel_Exception | |||||
* @return PHPExcel_Cell Cell that was found, or null if not found | |||||
*/ | |||||
public function getCacheData($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID) { | |||||
return $this->currentObject; | |||||
} | |||||
$this->storeData(); | |||||
// Check if the entry that has been requested actually exists | |||||
if (!isset($this->cellCache[$pCoord])) { | |||||
// Return null if requested entry doesn't exist in cache | |||||
return null; | |||||
} | |||||
// Set current entry to the requested entry | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = igbinary_unserialize($this->cellCache[$pCoord]); | |||||
// Re-attach this as the cell's parent | |||||
$this->currentObject->attach($this); | |||||
// Return requested entry | |||||
return $this->currentObject; | |||||
} // function getCacheData() | |||||
/** | |||||
* Get a list of all cell addresses currently held in cache | |||||
* | |||||
* @return string[] | |||||
*/ | |||||
public function getCellList() | |||||
{ | |||||
if ($this->currentObjectID !== null) { | |||||
$this->storeData(); | |||||
} | |||||
return parent::getCellList(); | |||||
} | |||||
/** | |||||
* Clear the cell collection and disconnect from our parent | |||||
* | |||||
* @return void | |||||
*/ | |||||
public function unsetWorksheetCells() | |||||
{ | |||||
if (!is_null($this->currentObject)) { | |||||
$this->currentObject->detach(); | |||||
$this->currentObject = $this->currentObjectID = null; | |||||
} | |||||
$this->cellCache = array(); | |||||
// detach ourself from the worksheet, so that it can then delete this object successfully | |||||
$this->parent = null; | |||||
} // function unsetWorksheetCells() | |||||
/** | |||||
* Identify whether the caching method is currently available | |||||
* Some methods are dependent on the availability of certain extensions being enabled in the PHP build | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public static function cacheMethodIsAvailable() | |||||
{ | |||||
if (!function_exists('igbinary_serialize')) { | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
} |
@ -0,0 +1,308 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CachedObjectStorage_Memcache | |||||
* | |||||
* 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_CachedObjectStorage | |||||
* @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_CachedObjectStorage_Memcache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | |||||
{ | |||||
/** | |||||
* Prefix used to uniquely identify cache data for this worksheet | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $cachePrefix = null; | |||||
/** | |||||
* Cache timeout | |||||
* | |||||
* @var integer | |||||
*/ | |||||
private $cacheTime = 600; | |||||
/** | |||||
* Memcache interface | |||||
* | |||||
* @var resource | |||||
*/ | |||||
private $memcache = null; | |||||
/** | |||||
* Store cell data in cache for the current cell object if it's "dirty", | |||||
* and the 'nullify' the current cell object | |||||
* | |||||
* @return void | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
protected function storeData() | |||||
{ | |||||
if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | |||||
$this->currentObject->detach(); | |||||
$obj = serialize($this->currentObject); | |||||
if (!$this->memcache->replace($this->cachePrefix . $this->currentObjectID . '.cache', $obj, null, $this->cacheTime)) { | |||||
if (!$this->memcache->add($this->cachePrefix . $this->currentObjectID . '.cache', $obj, null, $this->cacheTime)) { | |||||
$this->__destruct(); | |||||
throw new PHPExcel_Exception("Failed to store cell {$this->currentObjectID} in MemCache"); | |||||
} | |||||
} | |||||
$this->currentCellIsDirty = false; | |||||
} | |||||
$this->currentObjectID = $this->currentObject = null; | |||||
} // function _storeData() | |||||
/** | |||||
* Add or Update a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to update | |||||
* @param PHPExcel_Cell $cell Cell to update | |||||
* @return PHPExcel_Cell | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function addCacheData($pCoord, PHPExcel_Cell $cell) | |||||
{ | |||||
if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | |||||
$this->storeData(); | |||||
} | |||||
$this->cellCache[$pCoord] = true; | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = $cell; | |||||
$this->currentCellIsDirty = true; | |||||
return $cell; | |||||
} // function addCacheData() | |||||
/** | |||||
* Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to check | |||||
* @return boolean | |||||
* @return boolean | |||||
*/ | |||||
public function isDataSet($pCoord) | |||||
{ | |||||
// Check if the requested entry is the current object, or exists in the cache | |||||
if (parent::isDataSet($pCoord)) { | |||||
if ($this->currentObjectID == $pCoord) { | |||||
return true; | |||||
} | |||||
// Check if the requested entry still exists in Memcache | |||||
$success = $this->memcache->get($this->cachePrefix.$pCoord.'.cache'); | |||||
if ($success === false) { | |||||
// Entry no longer exists in Memcache, so clear it from the cache array | |||||
parent::deleteCacheData($pCoord); | |||||
throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in MemCache'); | |||||
} | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* Get cell at a specific coordinate | |||||
* | |||||
* @param string $pCoord Coordinate of the cell | |||||
* @throws PHPExcel_Exception | |||||
* @return PHPExcel_Cell Cell that was found, or null if not found | |||||
*/ | |||||
public function getCacheData($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID) { | |||||
return $this->currentObject; | |||||
} | |||||
$this->storeData(); | |||||
// Check if the entry that has been requested actually exists | |||||
if (parent::isDataSet($pCoord)) { | |||||
$obj = $this->memcache->get($this->cachePrefix . $pCoord . '.cache'); | |||||
if ($obj === false) { | |||||
// Entry no longer exists in Memcache, so clear it from the cache array | |||||
parent::deleteCacheData($pCoord); | |||||
throw new PHPExcel_Exception("Cell entry {$pCoord} no longer exists in MemCache"); | |||||
} | |||||
} else { | |||||
// Return null if requested entry doesn't exist in cache | |||||
return null; | |||||
} | |||||
// Set current entry to the requested entry | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = unserialize($obj); | |||||
// Re-attach this as the cell's parent | |||||
$this->currentObject->attach($this); | |||||
// Return requested entry | |||||
return $this->currentObject; | |||||
} | |||||
/** | |||||
* Get a list of all cell addresses currently held in cache | |||||
* | |||||
* @return string[] | |||||
*/ | |||||
public function getCellList() | |||||
{ | |||||
if ($this->currentObjectID !== null) { | |||||
$this->storeData(); | |||||
} | |||||
return parent::getCellList(); | |||||
} | |||||
/** | |||||
* Delete a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to delete | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function deleteCacheData($pCoord) | |||||
{ | |||||
// Delete the entry from Memcache | |||||
$this->memcache->delete($this->cachePrefix . $pCoord . '.cache'); | |||||
// Delete the entry from our cell address array | |||||
parent::deleteCacheData($pCoord); | |||||
} | |||||
/** | |||||
* Clone the cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The new worksheet | |||||
* @return void | |||||
*/ | |||||
public function copyCellCollection(PHPExcel_Worksheet $parent) | |||||
{ | |||||
parent::copyCellCollection($parent); | |||||
// Get a new id for the new file name | |||||
$baseUnique = $this->getUniqueID(); | |||||
$newCachePrefix = substr(md5($baseUnique), 0, 8) . '.'; | |||||
$cacheList = $this->getCellList(); | |||||
foreach ($cacheList as $cellID) { | |||||
if ($cellID != $this->currentObjectID) { | |||||
$obj = $this->memcache->get($this->cachePrefix.$cellID.'.cache'); | |||||
if ($obj === false) { | |||||
// Entry no longer exists in Memcache, so clear it from the cache array | |||||
parent::deleteCacheData($cellID); | |||||
throw new PHPExcel_Exception("Cell entry {$cellID} no longer exists in MemCache"); | |||||
} | |||||
if (!$this->memcache->add($newCachePrefix . $cellID . '.cache', $obj, null, $this->cacheTime)) { | |||||
$this->__destruct(); | |||||
throw new PHPExcel_Exception("Failed to store cell {$cellID} in MemCache"); | |||||
} | |||||
} | |||||
} | |||||
$this->cachePrefix = $newCachePrefix; | |||||
} | |||||
/** | |||||
* Clear the cell collection and disconnect from our parent | |||||
* | |||||
* @return void | |||||
*/ | |||||
public function unsetWorksheetCells() | |||||
{ | |||||
if (!is_null($this->currentObject)) { | |||||
$this->currentObject->detach(); | |||||
$this->currentObject = $this->currentObjectID = null; | |||||
} | |||||
// Flush the Memcache cache | |||||
$this->__destruct(); | |||||
$this->cellCache = array(); | |||||
// detach ourself from the worksheet, so that it can then delete this object successfully | |||||
$this->parent = null; | |||||
} | |||||
/** | |||||
* Initialise this new cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The worksheet for this cell collection | |||||
* @param array of mixed $arguments Additional initialisation arguments | |||||
*/ | |||||
public function __construct(PHPExcel_Worksheet $parent, $arguments) | |||||
{ | |||||
$memcacheServer = (isset($arguments['memcacheServer'])) ? $arguments['memcacheServer'] : 'localhost'; | |||||
$memcachePort = (isset($arguments['memcachePort'])) ? $arguments['memcachePort'] : 11211; | |||||
$cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; | |||||
if (is_null($this->cachePrefix)) { | |||||
$baseUnique = $this->getUniqueID(); | |||||
$this->cachePrefix = substr(md5($baseUnique), 0, 8) . '.'; | |||||
// Set a new Memcache object and connect to the Memcache server | |||||
$this->memcache = new Memcache(); | |||||
if (!$this->memcache->addServer($memcacheServer, $memcachePort, false, 50, 5, 5, true, array($this, 'failureCallback'))) { | |||||
throw new PHPExcel_Exception("Could not connect to MemCache server at {$memcacheServer}:{$memcachePort}"); | |||||
} | |||||
$this->cacheTime = $cacheTime; | |||||
parent::__construct($parent); | |||||
} | |||||
} | |||||
/** | |||||
* Memcache error handler | |||||
* | |||||
* @param string $host Memcache server | |||||
* @param integer $port Memcache port | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function failureCallback($host, $port) | |||||
{ | |||||
throw new PHPExcel_Exception("memcache {$host}:{$port} failed"); | |||||
} | |||||
/** | |||||
* Destroy this cell collection | |||||
*/ | |||||
public function __destruct() | |||||
{ | |||||
$cacheList = $this->getCellList(); | |||||
foreach ($cacheList as $cellID) { | |||||
$this->memcache->delete($this->cachePrefix.$cellID . '.cache'); | |||||
} | |||||
} | |||||
/** | |||||
* Identify whether the caching method is currently available | |||||
* Some methods are dependent on the availability of certain extensions being enabled in the PHP build | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public static function cacheMethodIsAvailable() | |||||
{ | |||||
if (!function_exists('memcache_add')) { | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
} |
@ -0,0 +1,118 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CachedObjectStorage_Memory | |||||
* | |||||
* 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_CachedObjectStorage | |||||
* @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_CachedObjectStorage_Memory extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | |||||
{ | |||||
/** | |||||
* Dummy method callable from CacheBase, but unused by Memory cache | |||||
* | |||||
* @return void | |||||
*/ | |||||
protected function storeData() | |||||
{ | |||||
} | |||||
/** | |||||
* Add or Update a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to update | |||||
* @param PHPExcel_Cell $cell Cell to update | |||||
* @return PHPExcel_Cell | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function addCacheData($pCoord, PHPExcel_Cell $cell) | |||||
{ | |||||
$this->cellCache[$pCoord] = $cell; | |||||
// Set current entry to the new/updated entry | |||||
$this->currentObjectID = $pCoord; | |||||
return $cell; | |||||
} | |||||
/** | |||||
* Get cell at a specific coordinate | |||||
* | |||||
* @param string $pCoord Coordinate of the cell | |||||
* @throws PHPExcel_Exception | |||||
* @return PHPExcel_Cell Cell that was found, or null if not found | |||||
*/ | |||||
public function getCacheData($pCoord) | |||||
{ | |||||
// Check if the entry that has been requested actually exists | |||||
if (!isset($this->cellCache[$pCoord])) { | |||||
$this->currentObjectID = null; | |||||
// Return null if requested entry doesn't exist in cache | |||||
return null; | |||||
} | |||||
// Set current entry to the requested entry | |||||
$this->currentObjectID = $pCoord; | |||||
// Return requested entry | |||||
return $this->cellCache[$pCoord]; | |||||
} | |||||
/** | |||||
* Clone the cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The new worksheet | |||||
*/ | |||||
public function copyCellCollection(PHPExcel_Worksheet $parent) | |||||
{ | |||||
parent::copyCellCollection($parent); | |||||
$newCollection = array(); | |||||
foreach ($this->cellCache as $k => &$cell) { | |||||
$newCollection[$k] = clone $cell; | |||||
$newCollection[$k]->attach($this); | |||||
} | |||||
$this->cellCache = $newCollection; | |||||
} | |||||
/** | |||||
* Clear the cell collection and disconnect from our parent | |||||
* | |||||
*/ | |||||
public function unsetWorksheetCells() | |||||
{ | |||||
// Because cells are all stored as intact objects in memory, we need to detach each one from the parent | |||||
foreach ($this->cellCache as $k => &$cell) { | |||||
$cell->detach(); | |||||
$this->cellCache[$k] = null; | |||||
} | |||||
unset($cell); | |||||
$this->cellCache = array(); | |||||
// detach ourself from the worksheet, so that it can then delete this object successfully | |||||
$this->parent = null; | |||||
} | |||||
} |
@ -0,0 +1,133 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CachedObjectStorage_MemoryGZip | |||||
* | |||||
* 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_CachedObjectStorage | |||||
* @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_CachedObjectStorage_MemoryGZip extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | |||||
{ | |||||
/** | |||||
* Store cell data in cache for the current cell object if it's "dirty", | |||||
* and the 'nullify' the current cell object | |||||
* | |||||
* @return void | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
protected function storeData() | |||||
{ | |||||
if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | |||||
$this->currentObject->detach(); | |||||
$this->cellCache[$this->currentObjectID] = gzdeflate(serialize($this->currentObject)); | |||||
$this->currentCellIsDirty = false; | |||||
} | |||||
$this->currentObjectID = $this->currentObject = null; | |||||
} | |||||
/** | |||||
* Add or Update a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to update | |||||
* @param PHPExcel_Cell $cell Cell to update | |||||
* @return PHPExcel_Cell | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function addCacheData($pCoord, PHPExcel_Cell $cell) | |||||
{ | |||||
if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | |||||
$this->storeData(); | |||||
} | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = $cell; | |||||
$this->currentCellIsDirty = true; | |||||
return $cell; | |||||
} | |||||
/** | |||||
* Get cell at a specific coordinate | |||||
* | |||||
* @param string $pCoord Coordinate of the cell | |||||
* @throws PHPExcel_Exception | |||||
* @return PHPExcel_Cell Cell that was found, or null if not found | |||||
*/ | |||||
public function getCacheData($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID) { | |||||
return $this->currentObject; | |||||
} | |||||
$this->storeData(); | |||||
// Check if the entry that has been requested actually exists | |||||
if (!isset($this->cellCache[$pCoord])) { | |||||
// Return null if requested entry doesn't exist in cache | |||||
return null; | |||||
} | |||||
// Set current entry to the requested entry | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = unserialize(gzinflate($this->cellCache[$pCoord])); | |||||
// Re-attach this as the cell's parent | |||||
$this->currentObject->attach($this); | |||||
// Return requested entry | |||||
return $this->currentObject; | |||||
} | |||||
/** | |||||
* Get a list of all cell addresses currently held in cache | |||||
* | |||||
* @return string[] | |||||
*/ | |||||
public function getCellList() | |||||
{ | |||||
if ($this->currentObjectID !== null) { | |||||
$this->storeData(); | |||||
} | |||||
return parent::getCellList(); | |||||
} | |||||
/** | |||||
* Clear the cell collection and disconnect from our parent | |||||
* | |||||
* @return void | |||||
*/ | |||||
public function unsetWorksheetCells() | |||||
{ | |||||
if (!is_null($this->currentObject)) { | |||||
$this->currentObject->detach(); | |||||
$this->currentObject = $this->currentObjectID = null; | |||||
} | |||||
$this->cellCache = array(); | |||||
// detach ourself from the worksheet, so that it can then delete this object successfully | |||||
$this->parent = null; | |||||
} | |||||
} |
@ -0,0 +1,129 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CachedObjectStorage_MemorySerialized | |||||
* | |||||
* 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_CachedObjectStorage | |||||
* @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_CachedObjectStorage_MemorySerialized extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | |||||
{ | |||||
/** | |||||
* Store cell data in cache for the current cell object if it's "dirty", | |||||
* and the 'nullify' the current cell object | |||||
* | |||||
* @return void | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
protected function storeData() | |||||
{ | |||||
if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | |||||
$this->currentObject->detach(); | |||||
$this->cellCache[$this->currentObjectID] = serialize($this->currentObject); | |||||
$this->currentCellIsDirty = false; | |||||
} | |||||
$this->currentObjectID = $this->currentObject = null; | |||||
} | |||||
/** | |||||
* Add or Update a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to update | |||||
* @param PHPExcel_Cell $cell Cell to update | |||||
* @return PHPExcel_Cell | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function addCacheData($pCoord, PHPExcel_Cell $cell) | |||||
{ | |||||
if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | |||||
$this->storeData(); | |||||
} | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = $cell; | |||||
$this->currentCellIsDirty = true; | |||||
return $cell; | |||||
} | |||||
/** | |||||
* Get cell at a specific coordinate | |||||
* | |||||
* @param string $pCoord Coordinate of the cell | |||||
* @throws PHPExcel_Exception | |||||
* @return PHPExcel_Cell Cell that was found, or null if not found | |||||
*/ | |||||
public function getCacheData($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID) { | |||||
return $this->currentObject; | |||||
} | |||||
$this->storeData(); | |||||
// Check if the entry that has been requested actually exists | |||||
if (!isset($this->cellCache[$pCoord])) { | |||||
// Return null if requested entry doesn't exist in cache | |||||
return null; | |||||
} | |||||
// Set current entry to the requested entry | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = unserialize($this->cellCache[$pCoord]); | |||||
// Re-attach this as the cell's parent | |||||
$this->currentObject->attach($this); | |||||
// Return requested entry | |||||
return $this->currentObject; | |||||
} | |||||
/** | |||||
* Get a list of all cell addresses currently held in cache | |||||
* | |||||
* @return string[] | |||||
*/ | |||||
public function getCellList() | |||||
{ | |||||
if ($this->currentObjectID !== null) { | |||||
$this->storeData(); | |||||
} | |||||
return parent::getCellList(); | |||||
} | |||||
/** | |||||
* Clear the cell collection and disconnect from our parent | |||||
* | |||||
* @return void | |||||
*/ | |||||
public function unsetWorksheetCells() | |||||
{ | |||||
if (!is_null($this->currentObject)) { | |||||
$this->currentObject->detach(); | |||||
$this->currentObject = $this->currentObjectID = null; | |||||
} | |||||
$this->cellCache = array(); | |||||
// detach ourself from the worksheet, so that it can then delete this object successfully | |||||
$this->parent = null; | |||||
} | |||||
} |
@ -0,0 +1,200 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CachedObjectStorage_PHPTemp | |||||
* | |||||
* 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_CachedObjectStorage | |||||
* @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_CachedObjectStorage_PHPTemp extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | |||||
{ | |||||
/** | |||||
* Name of the file for this cache | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $fileHandle = null; | |||||
/** | |||||
* Memory limit to use before reverting to file cache | |||||
* | |||||
* @var integer | |||||
*/ | |||||
private $memoryCacheSize = null; | |||||
/** | |||||
* Store cell data in cache for the current cell object if it's "dirty", | |||||
* and the 'nullify' the current cell object | |||||
* | |||||
* @return void | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
protected function storeData() | |||||
{ | |||||
if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | |||||
$this->currentObject->detach(); | |||||
fseek($this->fileHandle, 0, SEEK_END); | |||||
$this->cellCache[$this->currentObjectID] = array( | |||||
'ptr' => ftell($this->fileHandle), | |||||
'sz' => fwrite($this->fileHandle, serialize($this->currentObject)) | |||||
); | |||||
$this->currentCellIsDirty = false; | |||||
} | |||||
$this->currentObjectID = $this->currentObject = null; | |||||
} | |||||
/** | |||||
* Add or Update a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to update | |||||
* @param PHPExcel_Cell $cell Cell to update | |||||
* @return PHPExcel_Cell | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function addCacheData($pCoord, PHPExcel_Cell $cell) | |||||
{ | |||||
if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | |||||
$this->storeData(); | |||||
} | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = $cell; | |||||
$this->currentCellIsDirty = true; | |||||
return $cell; | |||||
} | |||||
/** | |||||
* Get cell at a specific coordinate | |||||
* | |||||
* @param string $pCoord Coordinate of the cell | |||||
* @throws PHPExcel_Exception | |||||
* @return PHPExcel_Cell Cell that was found, or null if not found | |||||
*/ | |||||
public function getCacheData($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID) { | |||||
return $this->currentObject; | |||||
} | |||||
$this->storeData(); | |||||
// Check if the entry that has been requested actually exists | |||||
if (!isset($this->cellCache[$pCoord])) { | |||||
// Return null if requested entry doesn't exist in cache | |||||
return null; | |||||
} | |||||
// Set current entry to the requested entry | |||||
$this->currentObjectID = $pCoord; | |||||
fseek($this->fileHandle, $this->cellCache[$pCoord]['ptr']); | |||||
$this->currentObject = unserialize(fread($this->fileHandle, $this->cellCache[$pCoord]['sz'])); | |||||
// Re-attach this as the cell's parent | |||||
$this->currentObject->attach($this); | |||||
// Return requested entry | |||||
return $this->currentObject; | |||||
} | |||||
/** | |||||
* Get a list of all cell addresses currently held in cache | |||||
* | |||||
* @return string[] | |||||
*/ | |||||
public function getCellList() | |||||
{ | |||||
if ($this->currentObjectID !== null) { | |||||
$this->storeData(); | |||||
} | |||||
return parent::getCellList(); | |||||
} | |||||
/** | |||||
* Clone the cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The new worksheet | |||||
* @return void | |||||
*/ | |||||
public function copyCellCollection(PHPExcel_Worksheet $parent) | |||||
{ | |||||
parent::copyCellCollection($parent); | |||||
// Open a new stream for the cell cache data | |||||
$newFileHandle = fopen('php://temp/maxmemory:' . $this->memoryCacheSize, 'a+'); | |||||
// Copy the existing cell cache data to the new stream | |||||
fseek($this->fileHandle, 0); | |||||
while (!feof($this->fileHandle)) { | |||||
fwrite($newFileHandle, fread($this->fileHandle, 1024)); | |||||
} | |||||
$this->fileHandle = $newFileHandle; | |||||
} | |||||
/** | |||||
* Clear the cell collection and disconnect from our parent | |||||
* | |||||
* @return void | |||||
*/ | |||||
public function unsetWorksheetCells() | |||||
{ | |||||
if (!is_null($this->currentObject)) { | |||||
$this->currentObject->detach(); | |||||
$this->currentObject = $this->currentObjectID = null; | |||||
} | |||||
$this->cellCache = array(); | |||||
// detach ourself from the worksheet, so that it can then delete this object successfully | |||||
$this->parent = null; | |||||
// Close down the php://temp file | |||||
$this->__destruct(); | |||||
} | |||||
/** | |||||
* Initialise this new cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The worksheet for this cell collection | |||||
* @param array of mixed $arguments Additional initialisation arguments | |||||
*/ | |||||
public function __construct(PHPExcel_Worksheet $parent, $arguments) | |||||
{ | |||||
$this->memoryCacheSize = (isset($arguments['memoryCacheSize'])) ? $arguments['memoryCacheSize'] : '1MB'; | |||||
parent::__construct($parent); | |||||
if (is_null($this->fileHandle)) { | |||||
$this->fileHandle = fopen('php://temp/maxmemory:' . $this->memoryCacheSize, 'a+'); | |||||
} | |||||
} | |||||
/** | |||||
* Destroy this cell collection | |||||
*/ | |||||
public function __destruct() | |||||
{ | |||||
if (!is_null($this->fileHandle)) { | |||||
fclose($this->fileHandle); | |||||
} | |||||
$this->fileHandle = null; | |||||
} | |||||
} |
@ -0,0 +1,307 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CachedObjectStorage_SQLite | |||||
* | |||||
* 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_CachedObjectStorage | |||||
* @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_CachedObjectStorage_SQLite extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | |||||
{ | |||||
/** | |||||
* Database table name | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $TableName = null; | |||||
/** | |||||
* Database handle | |||||
* | |||||
* @var resource | |||||
*/ | |||||
private $DBHandle = null; | |||||
/** | |||||
* Store cell data in cache for the current cell object if it's "dirty", | |||||
* and the 'nullify' the current cell object | |||||
* | |||||
* @return void | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
protected function storeData() | |||||
{ | |||||
if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | |||||
$this->currentObject->detach(); | |||||
if (!$this->DBHandle->queryExec("INSERT OR REPLACE INTO kvp_".$this->TableName." VALUES('".$this->currentObjectID."','".sqlite_escape_string(serialize($this->currentObject))."')")) { | |||||
throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | |||||
} | |||||
$this->currentCellIsDirty = false; | |||||
} | |||||
$this->currentObjectID = $this->currentObject = null; | |||||
} | |||||
/** | |||||
* Add or Update a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to update | |||||
* @param PHPExcel_Cell $cell Cell to update | |||||
* @return PHPExcel_Cell | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function addCacheData($pCoord, PHPExcel_Cell $cell) | |||||
{ | |||||
if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | |||||
$this->storeData(); | |||||
} | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = $cell; | |||||
$this->currentCellIsDirty = true; | |||||
return $cell; | |||||
} | |||||
/** | |||||
* Get cell at a specific coordinate | |||||
* | |||||
* @param string $pCoord Coordinate of the cell | |||||
* @throws PHPExcel_Exception | |||||
* @return PHPExcel_Cell Cell that was found, or null if not found | |||||
*/ | |||||
public function getCacheData($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID) { | |||||
return $this->currentObject; | |||||
} | |||||
$this->storeData(); | |||||
$query = "SELECT value FROM kvp_".$this->TableName." WHERE id='".$pCoord."'"; | |||||
$cellResultSet = $this->DBHandle->query($query, SQLITE_ASSOC); | |||||
if ($cellResultSet === false) { | |||||
throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | |||||
} elseif ($cellResultSet->numRows() == 0) { | |||||
// Return null if requested entry doesn't exist in cache | |||||
return null; | |||||
} | |||||
// Set current entry to the requested entry | |||||
$this->currentObjectID = $pCoord; | |||||
$cellResult = $cellResultSet->fetchSingle(); | |||||
$this->currentObject = unserialize($cellResult); | |||||
// Re-attach this as the cell's parent | |||||
$this->currentObject->attach($this); | |||||
// Return requested entry | |||||
return $this->currentObject; | |||||
} | |||||
/** | |||||
* Is a value set for an indexed cell? | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to check | |||||
* @return boolean | |||||
*/ | |||||
public function isDataSet($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID) { | |||||
return true; | |||||
} | |||||
// Check if the requested entry exists in the cache | |||||
$query = "SELECT id FROM kvp_".$this->TableName." WHERE id='".$pCoord."'"; | |||||
$cellResultSet = $this->DBHandle->query($query, SQLITE_ASSOC); | |||||
if ($cellResultSet === false) { | |||||
throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | |||||
} elseif ($cellResultSet->numRows() == 0) { | |||||
// Return null if requested entry doesn't exist in cache | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
/** | |||||
* Delete a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to delete | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function deleteCacheData($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID) { | |||||
$this->currentObject->detach(); | |||||
$this->currentObjectID = $this->currentObject = null; | |||||
} | |||||
// Check if the requested entry exists in the cache | |||||
$query = "DELETE FROM kvp_".$this->TableName." WHERE id='".$pCoord."'"; | |||||
if (!$this->DBHandle->queryExec($query)) { | |||||
throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | |||||
} | |||||
$this->currentCellIsDirty = false; | |||||
} | |||||
/** | |||||
* Move a cell object from one address to another | |||||
* | |||||
* @param string $fromAddress Current address of the cell to move | |||||
* @param string $toAddress Destination address of the cell to move | |||||
* @return boolean | |||||
*/ | |||||
public function moveCell($fromAddress, $toAddress) | |||||
{ | |||||
if ($fromAddress === $this->currentObjectID) { | |||||
$this->currentObjectID = $toAddress; | |||||
} | |||||
$query = "DELETE FROM kvp_".$this->TableName." WHERE id='".$toAddress."'"; | |||||
$result = $this->DBHandle->exec($query); | |||||
if ($result === false) { | |||||
throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | |||||
} | |||||
$query = "UPDATE kvp_".$this->TableName." SET id='".$toAddress."' WHERE id='".$fromAddress."'"; | |||||
$result = $this->DBHandle->exec($query); | |||||
if ($result === false) { | |||||
throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | |||||
} | |||||
return true; | |||||
} | |||||
/** | |||||
* Get a list of all cell addresses currently held in cache | |||||
* | |||||
* @return string[] | |||||
*/ | |||||
public function getCellList() | |||||
{ | |||||
if ($this->currentObjectID !== null) { | |||||
$this->storeData(); | |||||
} | |||||
$query = "SELECT id FROM kvp_".$this->TableName; | |||||
$cellIdsResult = $this->DBHandle->unbufferedQuery($query, SQLITE_ASSOC); | |||||
if ($cellIdsResult === false) { | |||||
throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | |||||
} | |||||
$cellKeys = array(); | |||||
foreach ($cellIdsResult as $row) { | |||||
$cellKeys[] = $row['id']; | |||||
} | |||||
return $cellKeys; | |||||
} | |||||
/** | |||||
* Clone the cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The new worksheet | |||||
* @return void | |||||
*/ | |||||
public function copyCellCollection(PHPExcel_Worksheet $parent) | |||||
{ | |||||
$this->currentCellIsDirty; | |||||
$this->storeData(); | |||||
// Get a new id for the new table name | |||||
$tableName = str_replace('.', '_', $this->getUniqueID()); | |||||
if (!$this->DBHandle->queryExec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB) | |||||
AS SELECT * FROM kvp_'.$this->TableName) | |||||
) { | |||||
throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | |||||
} | |||||
// Copy the existing cell cache file | |||||
$this->TableName = $tableName; | |||||
} | |||||
/** | |||||
* Clear the cell collection and disconnect from our parent | |||||
* | |||||
* @return void | |||||
*/ | |||||
public function unsetWorksheetCells() | |||||
{ | |||||
if (!is_null($this->currentObject)) { | |||||
$this->currentObject->detach(); | |||||
$this->currentObject = $this->currentObjectID = null; | |||||
} | |||||
// detach ourself from the worksheet, so that it can then delete this object successfully | |||||
$this->parent = null; | |||||
// Close down the temporary cache file | |||||
$this->__destruct(); | |||||
} | |||||
/** | |||||
* Initialise this new cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The worksheet for this cell collection | |||||
*/ | |||||
public function __construct(PHPExcel_Worksheet $parent) | |||||
{ | |||||
parent::__construct($parent); | |||||
if (is_null($this->DBHandle)) { | |||||
$this->TableName = str_replace('.', '_', $this->getUniqueID()); | |||||
$_DBName = ':memory:'; | |||||
$this->DBHandle = new SQLiteDatabase($_DBName); | |||||
if ($this->DBHandle === false) { | |||||
throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | |||||
} | |||||
if (!$this->DBHandle->queryExec('CREATE TABLE kvp_'.$this->TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) { | |||||
throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Destroy this cell collection | |||||
*/ | |||||
public function __destruct() | |||||
{ | |||||
if (!is_null($this->DBHandle)) { | |||||
$this->DBHandle->queryExec('DROP TABLE kvp_'.$this->TableName); | |||||
} | |||||
$this->DBHandle = null; | |||||
} | |||||
/** | |||||
* Identify whether the caching method is currently available | |||||
* Some methods are dependent on the availability of certain extensions being enabled in the PHP build | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public static function cacheMethodIsAvailable() | |||||
{ | |||||
if (!function_exists('sqlite_open')) { | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
} |
@ -0,0 +1,346 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CachedObjectStorage_SQLite3 | |||||
* | |||||
* 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_CachedObjectStorage | |||||
* @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_CachedObjectStorage_SQLite3 extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | |||||
{ | |||||
/** | |||||
* Database table name | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $TableName = null; | |||||
/** | |||||
* Database handle | |||||
* | |||||
* @var resource | |||||
*/ | |||||
private $DBHandle = null; | |||||
/** | |||||
* Prepared statement for a SQLite3 select query | |||||
* | |||||
* @var SQLite3Stmt | |||||
*/ | |||||
private $selectQuery; | |||||
/** | |||||
* Prepared statement for a SQLite3 insert query | |||||
* | |||||
* @var SQLite3Stmt | |||||
*/ | |||||
private $insertQuery; | |||||
/** | |||||
* Prepared statement for a SQLite3 update query | |||||
* | |||||
* @var SQLite3Stmt | |||||
*/ | |||||
private $updateQuery; | |||||
/** | |||||
* Prepared statement for a SQLite3 delete query | |||||
* | |||||
* @var SQLite3Stmt | |||||
*/ | |||||
private $deleteQuery; | |||||
/** | |||||
* Store cell data in cache for the current cell object if it's "dirty", | |||||
* and the 'nullify' the current cell object | |||||
* | |||||
* @return void | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
protected function storeData() | |||||
{ | |||||
if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | |||||
$this->currentObject->detach(); | |||||
$this->insertQuery->bindValue('id', $this->currentObjectID, SQLITE3_TEXT); | |||||
$this->insertQuery->bindValue('data', serialize($this->currentObject), SQLITE3_BLOB); | |||||
$result = $this->insertQuery->execute(); | |||||
if ($result === false) { | |||||
throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | |||||
} | |||||
$this->currentCellIsDirty = false; | |||||
} | |||||
$this->currentObjectID = $this->currentObject = null; | |||||
} | |||||
/** | |||||
* Add or Update a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to update | |||||
* @param PHPExcel_Cell $cell Cell to update | |||||
* @return PHPExcel_Cell | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function addCacheData($pCoord, PHPExcel_Cell $cell) | |||||
{ | |||||
if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | |||||
$this->storeData(); | |||||
} | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = $cell; | |||||
$this->currentCellIsDirty = true; | |||||
return $cell; | |||||
} | |||||
/** | |||||
* Get cell at a specific coordinate | |||||
* | |||||
* @param string $pCoord Coordinate of the cell | |||||
* @throws PHPExcel_Exception | |||||
* @return PHPExcel_Cell Cell that was found, or null if not found | |||||
*/ | |||||
public function getCacheData($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID) { | |||||
return $this->currentObject; | |||||
} | |||||
$this->storeData(); | |||||
$this->selectQuery->bindValue('id', $pCoord, SQLITE3_TEXT); | |||||
$cellResult = $this->selectQuery->execute(); | |||||
if ($cellResult === false) { | |||||
throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | |||||
} | |||||
$cellData = $cellResult->fetchArray(SQLITE3_ASSOC); | |||||
if ($cellData === false) { | |||||
// Return null if requested entry doesn't exist in cache | |||||
return null; | |||||
} | |||||
// Set current entry to the requested entry | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = unserialize($cellData['value']); | |||||
// Re-attach this as the cell's parent | |||||
$this->currentObject->attach($this); | |||||
// Return requested entry | |||||
return $this->currentObject; | |||||
} | |||||
/** | |||||
* Is a value set for an indexed cell? | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to check | |||||
* @return boolean | |||||
*/ | |||||
public function isDataSet($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID) { | |||||
return true; | |||||
} | |||||
// Check if the requested entry exists in the cache | |||||
$this->selectQuery->bindValue('id', $pCoord, SQLITE3_TEXT); | |||||
$cellResult = $this->selectQuery->execute(); | |||||
if ($cellResult === false) { | |||||
throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | |||||
} | |||||
$cellData = $cellResult->fetchArray(SQLITE3_ASSOC); | |||||
return ($cellData === false) ? false : true; | |||||
} | |||||
/** | |||||
* Delete a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to delete | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function deleteCacheData($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID) { | |||||
$this->currentObject->detach(); | |||||
$this->currentObjectID = $this->currentObject = null; | |||||
} | |||||
// Check if the requested entry exists in the cache | |||||
$this->deleteQuery->bindValue('id', $pCoord, SQLITE3_TEXT); | |||||
$result = $this->deleteQuery->execute(); | |||||
if ($result === false) { | |||||
throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | |||||
} | |||||
$this->currentCellIsDirty = false; | |||||
} | |||||
/** | |||||
* Move a cell object from one address to another | |||||
* | |||||
* @param string $fromAddress Current address of the cell to move | |||||
* @param string $toAddress Destination address of the cell to move | |||||
* @return boolean | |||||
*/ | |||||
public function moveCell($fromAddress, $toAddress) | |||||
{ | |||||
if ($fromAddress === $this->currentObjectID) { | |||||
$this->currentObjectID = $toAddress; | |||||
} | |||||
$this->deleteQuery->bindValue('id', $toAddress, SQLITE3_TEXT); | |||||
$result = $this->deleteQuery->execute(); | |||||
if ($result === false) { | |||||
throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | |||||
} | |||||
$this->updateQuery->bindValue('toid', $toAddress, SQLITE3_TEXT); | |||||
$this->updateQuery->bindValue('fromid', $fromAddress, SQLITE3_TEXT); | |||||
$result = $this->updateQuery->execute(); | |||||
if ($result === false) { | |||||
throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | |||||
} | |||||
return true; | |||||
} | |||||
/** | |||||
* Get a list of all cell addresses currently held in cache | |||||
* | |||||
* @return string[] | |||||
*/ | |||||
public function getCellList() | |||||
{ | |||||
if ($this->currentObjectID !== null) { | |||||
$this->storeData(); | |||||
} | |||||
$query = "SELECT id FROM kvp_".$this->TableName; | |||||
$cellIdsResult = $this->DBHandle->query($query); | |||||
if ($cellIdsResult === false) { | |||||
throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | |||||
} | |||||
$cellKeys = array(); | |||||
while ($row = $cellIdsResult->fetchArray(SQLITE3_ASSOC)) { | |||||
$cellKeys[] = $row['id']; | |||||
} | |||||
return $cellKeys; | |||||
} | |||||
/** | |||||
* Clone the cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The new worksheet | |||||
* @return void | |||||
*/ | |||||
public function copyCellCollection(PHPExcel_Worksheet $parent) | |||||
{ | |||||
$this->currentCellIsDirty; | |||||
$this->storeData(); | |||||
// Get a new id for the new table name | |||||
$tableName = str_replace('.', '_', $this->getUniqueID()); | |||||
if (!$this->DBHandle->exec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB) | |||||
AS SELECT * FROM kvp_'.$this->TableName) | |||||
) { | |||||
throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | |||||
} | |||||
// Copy the existing cell cache file | |||||
$this->TableName = $tableName; | |||||
} | |||||
/** | |||||
* Clear the cell collection and disconnect from our parent | |||||
* | |||||
* @return void | |||||
*/ | |||||
public function unsetWorksheetCells() | |||||
{ | |||||
if (!is_null($this->currentObject)) { | |||||
$this->currentObject->detach(); | |||||
$this->currentObject = $this->currentObjectID = null; | |||||
} | |||||
// detach ourself from the worksheet, so that it can then delete this object successfully | |||||
$this->parent = null; | |||||
// Close down the temporary cache file | |||||
$this->__destruct(); | |||||
} | |||||
/** | |||||
* Initialise this new cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The worksheet for this cell collection | |||||
*/ | |||||
public function __construct(PHPExcel_Worksheet $parent) | |||||
{ | |||||
parent::__construct($parent); | |||||
if (is_null($this->DBHandle)) { | |||||
$this->TableName = str_replace('.', '_', $this->getUniqueID()); | |||||
$_DBName = ':memory:'; | |||||
$this->DBHandle = new SQLite3($_DBName); | |||||
if ($this->DBHandle === false) { | |||||
throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | |||||
} | |||||
if (!$this->DBHandle->exec('CREATE TABLE kvp_'.$this->TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) { | |||||
throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | |||||
} | |||||
} | |||||
$this->selectQuery = $this->DBHandle->prepare("SELECT value FROM kvp_".$this->TableName." WHERE id = :id"); | |||||
$this->insertQuery = $this->DBHandle->prepare("INSERT OR REPLACE INTO kvp_".$this->TableName." VALUES(:id,:data)"); | |||||
$this->updateQuery = $this->DBHandle->prepare("UPDATE kvp_".$this->TableName." SET id=:toId WHERE id=:fromId"); | |||||
$this->deleteQuery = $this->DBHandle->prepare("DELETE FROM kvp_".$this->TableName." WHERE id = :id"); | |||||
} | |||||
/** | |||||
* Destroy this cell collection | |||||
*/ | |||||
public function __destruct() | |||||
{ | |||||
if (!is_null($this->DBHandle)) { | |||||
$this->DBHandle->exec('DROP TABLE kvp_'.$this->TableName); | |||||
$this->DBHandle->close(); | |||||
} | |||||
$this->DBHandle = null; | |||||
} | |||||
/** | |||||
* Identify whether the caching method is currently available | |||||
* Some methods are dependent on the availability of certain extensions being enabled in the PHP build | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public static function cacheMethodIsAvailable() | |||||
{ | |||||
if (!class_exists('SQLite3', false)) { | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
} |
@ -0,0 +1,289 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CachedObjectStorage_Wincache | |||||
* | |||||
* 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_CachedObjectStorage | |||||
* @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_CachedObjectStorage_Wincache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | |||||
{ | |||||
/** | |||||
* Prefix used to uniquely identify cache data for this worksheet | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $cachePrefix = null; | |||||
/** | |||||
* Cache timeout | |||||
* | |||||
* @var integer | |||||
*/ | |||||
private $cacheTime = 600; | |||||
/** | |||||
* Store cell data in cache for the current cell object if it's "dirty", | |||||
* and the 'nullify' the current cell object | |||||
* | |||||
* @return void | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
protected function storeData() | |||||
{ | |||||
if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | |||||
$this->currentObject->detach(); | |||||
$obj = serialize($this->currentObject); | |||||
if (wincache_ucache_exists($this->cachePrefix.$this->currentObjectID.'.cache')) { | |||||
if (!wincache_ucache_set($this->cachePrefix.$this->currentObjectID.'.cache', $obj, $this->cacheTime)) { | |||||
$this->__destruct(); | |||||
throw new PHPExcel_Exception('Failed to store cell '.$this->currentObjectID.' in WinCache'); | |||||
} | |||||
} else { | |||||
if (!wincache_ucache_add($this->cachePrefix.$this->currentObjectID.'.cache', $obj, $this->cacheTime)) { | |||||
$this->__destruct(); | |||||
throw new PHPExcel_Exception('Failed to store cell '.$this->currentObjectID.' in WinCache'); | |||||
} | |||||
} | |||||
$this->currentCellIsDirty = false; | |||||
} | |||||
$this->currentObjectID = $this->currentObject = null; | |||||
} | |||||
/** | |||||
* Add or Update a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to update | |||||
* @param PHPExcel_Cell $cell Cell to update | |||||
* @return PHPExcel_Cell | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function addCacheData($pCoord, PHPExcel_Cell $cell) | |||||
{ | |||||
if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | |||||
$this->storeData(); | |||||
} | |||||
$this->cellCache[$pCoord] = true; | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = $cell; | |||||
$this->currentCellIsDirty = true; | |||||
return $cell; | |||||
} | |||||
/** | |||||
* Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to check | |||||
* @return boolean | |||||
*/ | |||||
public function isDataSet($pCoord) | |||||
{ | |||||
// Check if the requested entry is the current object, or exists in the cache | |||||
if (parent::isDataSet($pCoord)) { | |||||
if ($this->currentObjectID == $pCoord) { | |||||
return true; | |||||
} | |||||
// Check if the requested entry still exists in cache | |||||
$success = wincache_ucache_exists($this->cachePrefix.$pCoord.'.cache'); | |||||
if ($success === false) { | |||||
// Entry no longer exists in Wincache, so clear it from the cache array | |||||
parent::deleteCacheData($pCoord); | |||||
throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache'); | |||||
} | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* Get cell at a specific coordinate | |||||
* | |||||
* @param string $pCoord Coordinate of the cell | |||||
* @throws PHPExcel_Exception | |||||
* @return PHPExcel_Cell Cell that was found, or null if not found | |||||
*/ | |||||
public function getCacheData($pCoord) | |||||
{ | |||||
if ($pCoord === $this->currentObjectID) { | |||||
return $this->currentObject; | |||||
} | |||||
$this->storeData(); | |||||
// Check if the entry that has been requested actually exists | |||||
$obj = null; | |||||
if (parent::isDataSet($pCoord)) { | |||||
$success = false; | |||||
$obj = wincache_ucache_get($this->cachePrefix.$pCoord.'.cache', $success); | |||||
if ($success === false) { | |||||
// Entry no longer exists in WinCache, so clear it from the cache array | |||||
parent::deleteCacheData($pCoord); | |||||
throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache'); | |||||
} | |||||
} else { | |||||
// Return null if requested entry doesn't exist in cache | |||||
return null; | |||||
} | |||||
// Set current entry to the requested entry | |||||
$this->currentObjectID = $pCoord; | |||||
$this->currentObject = unserialize($obj); | |||||
// Re-attach this as the cell's parent | |||||
$this->currentObject->attach($this); | |||||
// Return requested entry | |||||
return $this->currentObject; | |||||
} | |||||
/** | |||||
* Get a list of all cell addresses currently held in cache | |||||
* | |||||
* @return string[] | |||||
*/ | |||||
public function getCellList() | |||||
{ | |||||
if ($this->currentObjectID !== null) { | |||||
$this->storeData(); | |||||
} | |||||
return parent::getCellList(); | |||||
} | |||||
/** | |||||
* Delete a cell in cache identified by coordinate address | |||||
* | |||||
* @param string $pCoord Coordinate address of the cell to delete | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function deleteCacheData($pCoord) | |||||
{ | |||||
// Delete the entry from Wincache | |||||
wincache_ucache_delete($this->cachePrefix.$pCoord.'.cache'); | |||||
// Delete the entry from our cell address array | |||||
parent::deleteCacheData($pCoord); | |||||
} | |||||
/** | |||||
* Clone the cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The new worksheet | |||||
* @return void | |||||
*/ | |||||
public function copyCellCollection(PHPExcel_Worksheet $parent) | |||||
{ | |||||
parent::copyCellCollection($parent); | |||||
// Get a new id for the new file name | |||||
$baseUnique = $this->getUniqueID(); | |||||
$newCachePrefix = substr(md5($baseUnique), 0, 8) . '.'; | |||||
$cacheList = $this->getCellList(); | |||||
foreach ($cacheList as $cellID) { | |||||
if ($cellID != $this->currentObjectID) { | |||||
$success = false; | |||||
$obj = wincache_ucache_get($this->cachePrefix.$cellID.'.cache', $success); | |||||
if ($success === false) { | |||||
// Entry no longer exists in WinCache, so clear it from the cache array | |||||
parent::deleteCacheData($cellID); | |||||
throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in Wincache'); | |||||
} | |||||
if (!wincache_ucache_add($newCachePrefix.$cellID.'.cache', $obj, $this->cacheTime)) { | |||||
$this->__destruct(); | |||||
throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in Wincache'); | |||||
} | |||||
} | |||||
} | |||||
$this->cachePrefix = $newCachePrefix; | |||||
} | |||||
/** | |||||
* Clear the cell collection and disconnect from our parent | |||||
* | |||||
* @return void | |||||
*/ | |||||
public function unsetWorksheetCells() | |||||
{ | |||||
if (!is_null($this->currentObject)) { | |||||
$this->currentObject->detach(); | |||||
$this->currentObject = $this->currentObjectID = null; | |||||
} | |||||
// Flush the WinCache cache | |||||
$this->__destruct(); | |||||
$this->cellCache = array(); | |||||
// detach ourself from the worksheet, so that it can then delete this object successfully | |||||
$this->parent = null; | |||||
} | |||||
/** | |||||
* Initialise this new cell collection | |||||
* | |||||
* @param PHPExcel_Worksheet $parent The worksheet for this cell collection | |||||
* @param array of mixed $arguments Additional initialisation arguments | |||||
*/ | |||||
public function __construct(PHPExcel_Worksheet $parent, $arguments) | |||||
{ | |||||
$cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; | |||||
if (is_null($this->cachePrefix)) { | |||||
$baseUnique = $this->getUniqueID(); | |||||
$this->cachePrefix = substr(md5($baseUnique), 0, 8).'.'; | |||||
$this->cacheTime = $cacheTime; | |||||
parent::__construct($parent); | |||||
} | |||||
} | |||||
/** | |||||
* Destroy this cell collection | |||||
*/ | |||||
public function __destruct() | |||||
{ | |||||
$cacheList = $this->getCellList(); | |||||
foreach ($cacheList as $cellID) { | |||||
wincache_ucache_delete($this->cachePrefix.$cellID.'.cache'); | |||||
} | |||||
} | |||||
/** | |||||
* Identify whether the caching method is currently available | |||||
* Some methods are dependent on the availability of certain extensions being enabled in the PHP build | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public static function cacheMethodIsAvailable() | |||||
{ | |||||
if (!function_exists('wincache_ucache_add')) { | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
} |
@ -0,0 +1,231 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CachedObjectStorageFactory | |||||
* | |||||
* 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_CachedObjectStorage | |||||
* @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_CachedObjectStorageFactory | |||||
{ | |||||
const cache_in_memory = 'Memory'; | |||||
const cache_in_memory_gzip = 'MemoryGZip'; | |||||
const cache_in_memory_serialized = 'MemorySerialized'; | |||||
const cache_igbinary = 'Igbinary'; | |||||
const cache_to_discISAM = 'DiscISAM'; | |||||
const cache_to_apc = 'APC'; | |||||
const cache_to_memcache = 'Memcache'; | |||||
const cache_to_phpTemp = 'PHPTemp'; | |||||
const cache_to_wincache = 'Wincache'; | |||||
const cache_to_sqlite = 'SQLite'; | |||||
const cache_to_sqlite3 = 'SQLite3'; | |||||
/** | |||||
* Name of the method used for cell cacheing | |||||
* | |||||
* @var string | |||||
*/ | |||||
private static $cacheStorageMethod = null; | |||||
/** | |||||
* Name of the class used for cell cacheing | |||||
* | |||||
* @var string | |||||
*/ | |||||
private static $cacheStorageClass = null; | |||||
/** | |||||
* List of all possible cache storage methods | |||||
* | |||||
* @var string[] | |||||
*/ | |||||
private static $storageMethods = array( | |||||
self::cache_in_memory, | |||||
self::cache_in_memory_gzip, | |||||
self::cache_in_memory_serialized, | |||||
self::cache_igbinary, | |||||
self::cache_to_phpTemp, | |||||
self::cache_to_discISAM, | |||||
self::cache_to_apc, | |||||
self::cache_to_memcache, | |||||
self::cache_to_wincache, | |||||
self::cache_to_sqlite, | |||||
self::cache_to_sqlite3, | |||||
); | |||||
/** | |||||
* Default arguments for each cache storage method | |||||
* | |||||
* @var array of mixed array | |||||
*/ | |||||
private static $storageMethodDefaultParameters = array( | |||||
self::cache_in_memory => array( | |||||
), | |||||
self::cache_in_memory_gzip => array( | |||||
), | |||||
self::cache_in_memory_serialized => array( | |||||
), | |||||
self::cache_igbinary => array( | |||||
), | |||||
self::cache_to_phpTemp => array( 'memoryCacheSize' => '1MB' | |||||
), | |||||
self::cache_to_discISAM => array( 'dir' => null | |||||
), | |||||
self::cache_to_apc => array( 'cacheTime' => 600 | |||||
), | |||||
self::cache_to_memcache => array( 'memcacheServer' => 'localhost', | |||||
'memcachePort' => 11211, | |||||
'cacheTime' => 600 | |||||
), | |||||
self::cache_to_wincache => array( 'cacheTime' => 600 | |||||
), | |||||
self::cache_to_sqlite => array( | |||||
), | |||||
self::cache_to_sqlite3 => array( | |||||
), | |||||
); | |||||
/** | |||||
* Arguments for the active cache storage method | |||||
* | |||||
* @var array of mixed array | |||||
*/ | |||||
private static $storageMethodParameters = array(); | |||||
/** | |||||
* Return the current cache storage method | |||||
* | |||||
* @return string|null | |||||
**/ | |||||
public static function getCacheStorageMethod() | |||||
{ | |||||
return self::$cacheStorageMethod; | |||||
} | |||||
/** | |||||
* Return the current cache storage class | |||||
* | |||||
* @return PHPExcel_CachedObjectStorage_ICache|null | |||||
**/ | |||||
public static function getCacheStorageClass() | |||||
{ | |||||
return self::$cacheStorageClass; | |||||
} | |||||
/** | |||||
* Return the list of all possible cache storage methods | |||||
* | |||||
* @return string[] | |||||
**/ | |||||
public static function getAllCacheStorageMethods() | |||||
{ | |||||
return self::$storageMethods; | |||||
} | |||||
/** | |||||
* Return the list of all available cache storage methods | |||||
* | |||||
* @return string[] | |||||
**/ | |||||
public static function getCacheStorageMethods() | |||||
{ | |||||
$activeMethods = array(); | |||||
foreach (self::$storageMethods as $storageMethod) { | |||||
$cacheStorageClass = 'PHPExcel_CachedObjectStorage_' . $storageMethod; | |||||
if (call_user_func(array($cacheStorageClass, 'cacheMethodIsAvailable'))) { | |||||
$activeMethods[] = $storageMethod; | |||||
} | |||||
} | |||||
return $activeMethods; | |||||
} | |||||
/** | |||||
* Identify the cache storage method to use | |||||
* | |||||
* @param string $method Name of the method to use for cell cacheing | |||||
* @param array of mixed $arguments Additional arguments to pass to the cell caching class | |||||
* when instantiating | |||||
* @return boolean | |||||
**/ | |||||
public static function initialize($method = self::cache_in_memory, $arguments = array()) | |||||
{ | |||||
if (!in_array($method, self::$storageMethods)) { | |||||
return false; | |||||
} | |||||
$cacheStorageClass = 'PHPExcel_CachedObjectStorage_'.$method; | |||||
if (!call_user_func(array( $cacheStorageClass, | |||||
'cacheMethodIsAvailable'))) { | |||||
return false; | |||||
} | |||||
self::$storageMethodParameters[$method] = self::$storageMethodDefaultParameters[$method]; | |||||
foreach ($arguments as $k => $v) { | |||||
if (array_key_exists($k, self::$storageMethodParameters[$method])) { | |||||
self::$storageMethodParameters[$method][$k] = $v; | |||||
} | |||||
} | |||||
if (self::$cacheStorageMethod === null) { | |||||
self::$cacheStorageClass = 'PHPExcel_CachedObjectStorage_' . $method; | |||||
self::$cacheStorageMethod = $method; | |||||
} | |||||
return true; | |||||
} | |||||
/** | |||||
* Initialise the cache storage | |||||
* | |||||
* @param PHPExcel_Worksheet $parent Enable cell caching for this worksheet | |||||
* @return PHPExcel_CachedObjectStorage_ICache | |||||
**/ | |||||
public static function getInstance(PHPExcel_Worksheet $parent) | |||||
{ | |||||
$cacheMethodIsAvailable = true; | |||||
if (self::$cacheStorageMethod === null) { | |||||
$cacheMethodIsAvailable = self::initialize(); | |||||
} | |||||
if ($cacheMethodIsAvailable) { | |||||
$instance = new self::$cacheStorageClass( | |||||
$parent, | |||||
self::$storageMethodParameters[self::$cacheStorageMethod] | |||||
); | |||||
if ($instance !== null) { | |||||
return $instance; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* Clear the cache storage | |||||
* | |||||
**/ | |||||
public static function finalize() | |||||
{ | |||||
self::$cacheStorageMethod = null; | |||||
self::$cacheStorageClass = null; | |||||
self::$storageMethodParameters = array(); | |||||
} | |||||
} |
@ -0,0 +1,94 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CalcEngine_CyclicReferenceStack | |||||
* | |||||
* 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_Calculation | |||||
* @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_CalcEngine_CyclicReferenceStack | |||||
{ | |||||
/** | |||||
* The call stack for calculated cells | |||||
* | |||||
* @var mixed[] | |||||
*/ | |||||
private $stack = array(); | |||||
/** | |||||
* Return the number of entries on the stack | |||||
* | |||||
* @return integer | |||||
*/ | |||||
public function count() | |||||
{ | |||||
return count($this->stack); | |||||
} | |||||
/** | |||||
* Push a new entry onto the stack | |||||
* | |||||
* @param mixed $value | |||||
*/ | |||||
public function push($value) | |||||
{ | |||||
$this->stack[$value] = $value; | |||||
} | |||||
/** | |||||
* Pop the last entry from the stack | |||||
* | |||||
* @return mixed | |||||
*/ | |||||
public function pop() | |||||
{ | |||||
return array_pop($this->stack); | |||||
} | |||||
/** | |||||
* Test to see if a specified entry exists on the stack | |||||
* | |||||
* @param mixed $value The value to test | |||||
*/ | |||||
public function onStack($value) | |||||
{ | |||||
return isset($this->stack[$value]); | |||||
} | |||||
/** | |||||
* Clear the stack | |||||
*/ | |||||
public function clear() | |||||
{ | |||||
$this->stack = array(); | |||||
} | |||||
/** | |||||
* Return an array of all entries on the stack | |||||
* | |||||
* @return mixed[] | |||||
*/ | |||||
public function showStack() | |||||
{ | |||||
return $this->stack; | |||||
} | |||||
} |
@ -0,0 +1,151 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_CalcEngine_Logger | |||||
* | |||||
* 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_Calculation | |||||
* @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_CalcEngine_Logger | |||||
{ | |||||
/** | |||||
* Flag to determine whether a debug log should be generated by the calculation engine | |||||
* If true, then a debug log will be generated | |||||
* If false, then a debug log will not be generated | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $writeDebugLog = false; | |||||
/** | |||||
* Flag to determine whether a debug log should be echoed by the calculation engine | |||||
* If true, then a debug log will be echoed | |||||
* If false, then a debug log will not be echoed | |||||
* A debug log can only be echoed if it is generated | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $echoDebugLog = false; | |||||
/** | |||||
* The debug log generated by the calculation engine | |||||
* | |||||
* @var string[] | |||||
*/ | |||||
private $debugLog = array(); | |||||
/** | |||||
* The calculation engine cell reference stack | |||||
* | |||||
* @var PHPExcel_CalcEngine_CyclicReferenceStack | |||||
*/ | |||||
private $cellStack; | |||||
/** | |||||
* Instantiate a Calculation engine logger | |||||
* | |||||
* @param PHPExcel_CalcEngine_CyclicReferenceStack $stack | |||||
*/ | |||||
public function __construct(PHPExcel_CalcEngine_CyclicReferenceStack $stack) | |||||
{ | |||||
$this->cellStack = $stack; | |||||
} | |||||
/** | |||||
* Enable/Disable Calculation engine logging | |||||
* | |||||
* @param boolean $pValue | |||||
*/ | |||||
public function setWriteDebugLog($pValue = false) | |||||
{ | |||||
$this->writeDebugLog = $pValue; | |||||
} | |||||
/** | |||||
* Return whether calculation engine logging is enabled or disabled | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getWriteDebugLog() | |||||
{ | |||||
return $this->writeDebugLog; | |||||
} | |||||
/** | |||||
* Enable/Disable echoing of debug log information | |||||
* | |||||
* @param boolean $pValue | |||||
*/ | |||||
public function setEchoDebugLog($pValue = false) | |||||
{ | |||||
$this->echoDebugLog = $pValue; | |||||
} | |||||
/** | |||||
* Return whether echoing of debug log information is enabled or disabled | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getEchoDebugLog() | |||||
{ | |||||
return $this->echoDebugLog; | |||||
} | |||||
/** | |||||
* Write an entry to the calculation engine debug log | |||||
*/ | |||||
public function writeDebugLog() | |||||
{ | |||||
// Only write the debug log if logging is enabled | |||||
if ($this->writeDebugLog) { | |||||
$message = implode(func_get_args()); | |||||
$cellReference = implode(' -> ', $this->cellStack->showStack()); | |||||
if ($this->echoDebugLog) { | |||||
echo $cellReference, | |||||
($this->cellStack->count() > 0 ? ' => ' : ''), | |||||
$message, | |||||
PHP_EOL; | |||||
} | |||||
$this->debugLog[] = $cellReference . | |||||
($this->cellStack->count() > 0 ? ' => ' : '') . | |||||
$message; | |||||
} | |||||
} | |||||
/** | |||||
* Clear the calculation engine debug log | |||||
*/ | |||||
public function clearLog() | |||||
{ | |||||
$this->debugLog = array(); | |||||
} | |||||
/** | |||||
* Return the calculation engine debug log | |||||
* | |||||
* @return string[] | |||||
*/ | |||||
public function getLog() | |||||
{ | |||||
return $this->debugLog; | |||||
} | |||||
} |
@ -0,0 +1,676 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_Calculation_Database | |||||
* | |||||
* 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_Calculation | |||||
* @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_Calculation_Database | |||||
{ | |||||
/** | |||||
* fieldExtract | |||||
* | |||||
* Extracts the column ID to use for the data field. | |||||
* | |||||
* @access private | |||||
* @param mixed[] $database The range of cells that makes up the list or database. | |||||
* A database is a list of related data in which rows of related | |||||
* information are records, and columns of data are fields. The | |||||
* first row of the list contains labels for each column. | |||||
* @param mixed $field Indicates which column is used in the function. Enter the | |||||
* column label enclosed between double quotation marks, such as | |||||
* "Age" or "Yield," or a number (without quotation marks) that | |||||
* represents the position of the column within the list: 1 for | |||||
* the first column, 2 for the second column, and so on. | |||||
* @return string|NULL | |||||
* | |||||
*/ | |||||
private static function fieldExtract($database, $field) | |||||
{ | |||||
$field = strtoupper(PHPExcel_Calculation_Functions::flattenSingleValue($field)); | |||||
$fieldNames = array_map('strtoupper', array_shift($database)); | |||||
if (is_numeric($field)) { | |||||
$keys = array_keys($fieldNames); | |||||
return $keys[$field-1]; | |||||
} | |||||
$key = array_search($field, $fieldNames); | |||||
return ($key) ? $key : null; | |||||
} | |||||
/** | |||||
* filter | |||||
* | |||||
* Parses the selection criteria, extracts the database rows that match those criteria, and | |||||
* returns that subset of rows. | |||||
* | |||||
* @access private | |||||
* @param mixed[] $database The range of cells that makes up the list or database. | |||||
* A database is a list of related data in which rows of related | |||||
* information are records, and columns of data are fields. The | |||||
* first row of the list contains labels for each column. | |||||
* @param mixed[] $criteria The range of cells that contains the conditions you specify. | |||||
* You can use any range for the criteria argument, as long as it | |||||
* includes at least one column label and at least one cell below | |||||
* the column label in which you specify a condition for the | |||||
* column. | |||||
* @return array of mixed | |||||
* | |||||
*/ | |||||
private static function filter($database, $criteria) | |||||
{ | |||||
$fieldNames = array_shift($database); | |||||
$criteriaNames = array_shift($criteria); | |||||
// Convert the criteria into a set of AND/OR conditions with [:placeholders] | |||||
$testConditions = $testValues = array(); | |||||
$testConditionsCount = 0; | |||||
foreach ($criteriaNames as $key => $criteriaName) { | |||||
$testCondition = array(); | |||||
$testConditionCount = 0; | |||||
foreach ($criteria as $row => $criterion) { | |||||
if ($criterion[$key] > '') { | |||||
$testCondition[] = '[:'.$criteriaName.']'.PHPExcel_Calculation_Functions::ifCondition($criterion[$key]); | |||||
$testConditionCount++; | |||||
} | |||||
} | |||||
if ($testConditionCount > 1) { | |||||
$testConditions[] = 'OR(' . implode(',', $testCondition) . ')'; | |||||
$testConditionsCount++; | |||||
} elseif ($testConditionCount == 1) { | |||||
$testConditions[] = $testCondition[0]; | |||||
$testConditionsCount++; | |||||
} | |||||
} | |||||
if ($testConditionsCount > 1) { | |||||
$testConditionSet = 'AND(' . implode(',', $testConditions) . ')'; | |||||
} elseif ($testConditionsCount == 1) { | |||||
$testConditionSet = $testConditions[0]; | |||||
} | |||||
// Loop through each row of the database | |||||
foreach ($database as $dataRow => $dataValues) { | |||||
// Substitute actual values from the database row for our [:placeholders] | |||||
$testConditionList = $testConditionSet; | |||||
foreach ($criteriaNames as $key => $criteriaName) { | |||||
$k = array_search($criteriaName, $fieldNames); | |||||
if (isset($dataValues[$k])) { | |||||
$dataValue = $dataValues[$k]; | |||||
$dataValue = (is_string($dataValue)) ? PHPExcel_Calculation::wrapResult(strtoupper($dataValue)) : $dataValue; | |||||
$testConditionList = str_replace('[:' . $criteriaName . ']', $dataValue, $testConditionList); | |||||
} | |||||
} | |||||
// evaluate the criteria against the row data | |||||
$result = PHPExcel_Calculation::getInstance()->_calculateFormulaValue('='.$testConditionList); | |||||
// If the row failed to meet the criteria, remove it from the database | |||||
if (!$result) { | |||||
unset($database[$dataRow]); | |||||
} | |||||
} | |||||
return $database; | |||||
} | |||||
private static function getFilteredColumn($database, $field, $criteria) | |||||
{ | |||||
// reduce the database to a set of rows that match all the criteria | |||||
$database = self::filter($database, $criteria); | |||||
// extract an array of values for the requested column | |||||
$colData = array(); | |||||
foreach ($database as $row) { | |||||
$colData[] = $row[$field]; | |||||
} | |||||
return $colData; | |||||
} | |||||
/** | |||||
* DAVERAGE | |||||
* | |||||
* Averages the values in a column of a list or database that match conditions you specify. | |||||
* | |||||
* Excel Function: | |||||
* DAVERAGE(database,field,criteria) | |||||
* | |||||
* @access public | |||||
* @category Database Functions | |||||
* @param mixed[] $database The range of cells that makes up the list or database. | |||||
* A database is a list of related data in which rows of related | |||||
* information are records, and columns of data are fields. The | |||||
* first row of the list contains labels for each column. | |||||
* @param string|integer $field Indicates which column is used in the function. Enter the | |||||
* column label enclosed between double quotation marks, such as | |||||
* "Age" or "Yield," or a number (without quotation marks) that | |||||
* represents the position of the column within the list: 1 for | |||||
* the first column, 2 for the second column, and so on. | |||||
* @param mixed[] $criteria The range of cells that contains the conditions you specify. | |||||
* You can use any range for the criteria argument, as long as it | |||||
* includes at least one column label and at least one cell below | |||||
* the column label in which you specify a condition for the | |||||
* column. | |||||
* @return float | |||||
* | |||||
*/ | |||||
public static function DAVERAGE($database, $field, $criteria) | |||||
{ | |||||
$field = self::fieldExtract($database, $field); | |||||
if (is_null($field)) { | |||||
return null; | |||||
} | |||||
// Return | |||||
return PHPExcel_Calculation_Statistical::AVERAGE( | |||||
self::getFilteredColumn($database, $field, $criteria) | |||||
); | |||||
} | |||||
/** | |||||
* DCOUNT | |||||
* | |||||
* Counts the cells that contain numbers in a column of a list or database that match conditions | |||||
* that you specify. | |||||
* | |||||
* Excel Function: | |||||
* DCOUNT(database,[field],criteria) | |||||
* | |||||
* Excel Function: | |||||
* DAVERAGE(database,field,criteria) | |||||
* | |||||
* @access public | |||||
* @category Database Functions | |||||
* @param mixed[] $database The range of cells that makes up the list or database. | |||||
* A database is a list of related data in which rows of related | |||||
* information are records, and columns of data are fields. The | |||||
* first row of the list contains labels for each column. | |||||
* @param string|integer $field Indicates which column is used in the function. Enter the | |||||
* column label enclosed between double quotation marks, such as | |||||
* "Age" or "Yield," or a number (without quotation marks) that | |||||
* represents the position of the column within the list: 1 for | |||||
* the first column, 2 for the second column, and so on. | |||||
* @param mixed[] $criteria The range of cells that contains the conditions you specify. | |||||
* You can use any range for the criteria argument, as long as it | |||||
* includes at least one column label and at least one cell below | |||||
* the column label in which you specify a condition for the | |||||
* column. | |||||
* @return integer | |||||
* | |||||
* @TODO The field argument is optional. If field is omitted, DCOUNT counts all records in the | |||||
* database that match the criteria. | |||||
* | |||||
*/ | |||||
public static function DCOUNT($database, $field, $criteria) | |||||
{ | |||||
$field = self::fieldExtract($database, $field); | |||||
if (is_null($field)) { | |||||
return null; | |||||
} | |||||
// Return | |||||
return PHPExcel_Calculation_Statistical::COUNT( | |||||
self::getFilteredColumn($database, $field, $criteria) | |||||
); | |||||
} | |||||
/** | |||||
* DCOUNTA | |||||
* | |||||
* Counts the nonblank cells in a column of a list or database that match conditions that you specify. | |||||
* | |||||
* Excel Function: | |||||
* DCOUNTA(database,[field],criteria) | |||||
* | |||||
* @access public | |||||
* @category Database Functions | |||||
* @param mixed[] $database The range of cells that makes up the list or database. | |||||
* A database is a list of related data in which rows of related | |||||
* information are records, and columns of data are fields. The | |||||
* first row of the list contains labels for each column. | |||||
* @param string|integer $field Indicates which column is used in the function. Enter the | |||||
* column label enclosed between double quotation marks, such as | |||||
* "Age" or "Yield," or a number (without quotation marks) that | |||||
* represents the position of the column within the list: 1 for | |||||
* the first column, 2 for the second column, and so on. | |||||
* @param mixed[] $criteria The range of cells that contains the conditions you specify. | |||||
* You can use any range for the criteria argument, as long as it | |||||
* includes at least one column label and at least one cell below | |||||
* the column label in which you specify a condition for the | |||||
* column. | |||||
* @return integer | |||||
* | |||||
* @TODO The field argument is optional. If field is omitted, DCOUNTA counts all records in the | |||||
* database that match the criteria. | |||||
* | |||||
*/ | |||||
public static function DCOUNTA($database, $field, $criteria) | |||||
{ | |||||
$field = self::fieldExtract($database, $field); | |||||
if (is_null($field)) { | |||||
return null; | |||||
} | |||||
// reduce the database to a set of rows that match all the criteria | |||||
$database = self::filter($database, $criteria); | |||||
// extract an array of values for the requested column | |||||
$colData = array(); | |||||
foreach ($database as $row) { | |||||
$colData[] = $row[$field]; | |||||
} | |||||
// Return | |||||
return PHPExcel_Calculation_Statistical::COUNTA( | |||||
self::getFilteredColumn($database, $field, $criteria) | |||||
); | |||||
} | |||||
/** | |||||
* DGET | |||||
* | |||||
* Extracts a single value from a column of a list or database that matches conditions that you | |||||
* specify. | |||||
* | |||||
* Excel Function: | |||||
* DGET(database,field,criteria) | |||||
* | |||||
* @access public | |||||
* @category Database Functions | |||||
* @param mixed[] $database The range of cells that makes up the list or database. | |||||
* A database is a list of related data in which rows of related | |||||
* information are records, and columns of data are fields. The | |||||
* first row of the list contains labels for each column. | |||||
* @param string|integer $field Indicates which column is used in the function. Enter the | |||||
* column label enclosed between double quotation marks, such as | |||||
* "Age" or "Yield," or a number (without quotation marks) that | |||||
* represents the position of the column within the list: 1 for | |||||
* the first column, 2 for the second column, and so on. | |||||
* @param mixed[] $criteria The range of cells that contains the conditions you specify. | |||||
* You can use any range for the criteria argument, as long as it | |||||
* includes at least one column label and at least one cell below | |||||
* the column label in which you specify a condition for the | |||||
* column. | |||||
* @return mixed | |||||
* | |||||
*/ | |||||
public static function DGET($database, $field, $criteria) | |||||
{ | |||||
$field = self::fieldExtract($database, $field); | |||||
if (is_null($field)) { | |||||
return null; | |||||
} | |||||
// Return | |||||
$colData = self::getFilteredColumn($database, $field, $criteria); | |||||
if (count($colData) > 1) { | |||||
return PHPExcel_Calculation_Functions::NaN(); | |||||
} | |||||
return $colData[0]; | |||||
} | |||||
/** | |||||
* DMAX | |||||
* | |||||
* Returns the largest number in a column of a list or database that matches conditions you that | |||||
* specify. | |||||
* | |||||
* Excel Function: | |||||
* DMAX(database,field,criteria) | |||||
* | |||||
* @access public | |||||
* @category Database Functions | |||||
* @param mixed[] $database The range of cells that makes up the list or database. | |||||
* A database is a list of related data in which rows of related | |||||
* information are records, and columns of data are fields. The | |||||
* first row of the list contains labels for each column. | |||||
* @param string|integer $field Indicates which column is used in the function. Enter the | |||||
* column label enclosed between double quotation marks, such as | |||||
* "Age" or "Yield," or a number (without quotation marks) that | |||||
* represents the position of the column within the list: 1 for | |||||
* the first column, 2 for the second column, and so on. | |||||
* @param mixed[] $criteria The range of cells that contains the conditions you specify. | |||||
* You can use any range for the criteria argument, as long as it | |||||
* includes at least one column label and at least one cell below | |||||
* the column label in which you specify a condition for the | |||||
* column. | |||||
* @return float | |||||
* | |||||
*/ | |||||
public static function DMAX($database, $field, $criteria) | |||||
{ | |||||
$field = self::fieldExtract($database, $field); | |||||
if (is_null($field)) { | |||||
return null; | |||||
} | |||||
// Return | |||||
return PHPExcel_Calculation_Statistical::MAX( | |||||
self::getFilteredColumn($database, $field, $criteria) | |||||
); | |||||
} | |||||
/** | |||||
* DMIN | |||||
* | |||||
* Returns the smallest number in a column of a list or database that matches conditions you that | |||||
* specify. | |||||
* | |||||
* Excel Function: | |||||
* DMIN(database,field,criteria) | |||||
* | |||||
* @access public | |||||
* @category Database Functions | |||||
* @param mixed[] $database The range of cells that makes up the list or database. | |||||
* A database is a list of related data in which rows of related | |||||
* information are records, and columns of data are fields. The | |||||
* first row of the list contains labels for each column. | |||||
* @param string|integer $field Indicates which column is used in the function. Enter the | |||||
* column label enclosed between double quotation marks, such as | |||||
* "Age" or "Yield," or a number (without quotation marks) that | |||||
* represents the position of the column within the list: 1 for | |||||
* the first column, 2 for the second column, and so on. | |||||
* @param mixed[] $criteria The range of cells that contains the conditions you specify. | |||||
* You can use any range for the criteria argument, as long as it | |||||
* includes at least one column label and at least one cell below | |||||
* the column label in which you specify a condition for the | |||||
* column. | |||||
* @return float | |||||
* | |||||
*/ | |||||
public static function DMIN($database, $field, $criteria) | |||||
{ | |||||
$field = self::fieldExtract($database, $field); | |||||
if (is_null($field)) { | |||||
return null; | |||||
} | |||||
// Return | |||||
return PHPExcel_Calculation_Statistical::MIN( | |||||
self::getFilteredColumn($database, $field, $criteria) | |||||
); | |||||
} | |||||
/** | |||||
* DPRODUCT | |||||
* | |||||
* Multiplies the values in a column of a list or database that match conditions that you specify. | |||||
* | |||||
* Excel Function: | |||||
* DPRODUCT(database,field,criteria) | |||||
* | |||||
* @access public | |||||
* @category Database Functions | |||||
* @param mixed[] $database The range of cells that makes up the list or database. | |||||
* A database is a list of related data in which rows of related | |||||
* information are records, and columns of data are fields. The | |||||
* first row of the list contains labels for each column. | |||||
* @param string|integer $field Indicates which column is used in the function. Enter the | |||||
* column label enclosed between double quotation marks, such as | |||||
* "Age" or "Yield," or a number (without quotation marks) that | |||||
* represents the position of the column within the list: 1 for | |||||
* the first column, 2 for the second column, and so on. | |||||
* @param mixed[] $criteria The range of cells that contains the conditions you specify. | |||||
* You can use any range for the criteria argument, as long as it | |||||
* includes at least one column label and at least one cell below | |||||
* the column label in which you specify a condition for the | |||||
* column. | |||||
* @return float | |||||
* | |||||
*/ | |||||
public static function DPRODUCT($database, $field, $criteria) | |||||
{ | |||||
$field = self::fieldExtract($database, $field); | |||||
if (is_null($field)) { | |||||
return null; | |||||
} | |||||
// Return | |||||
return PHPExcel_Calculation_MathTrig::PRODUCT( | |||||
self::getFilteredColumn($database, $field, $criteria) | |||||
); | |||||
} | |||||
/** | |||||
* DSTDEV | |||||
* | |||||
* Estimates the standard deviation of a population based on a sample by using the numbers in a | |||||
* column of a list or database that match conditions that you specify. | |||||
* | |||||
* Excel Function: | |||||
* DSTDEV(database,field,criteria) | |||||
* | |||||
* @access public | |||||
* @category Database Functions | |||||
* @param mixed[] $database The range of cells that makes up the list or database. | |||||
* A database is a list of related data in which rows of related | |||||
* information are records, and columns of data are fields. The | |||||
* first row of the list contains labels for each column. | |||||
* @param string|integer $field Indicates which column is used in the function. Enter the | |||||
* column label enclosed between double quotation marks, such as | |||||
* "Age" or "Yield," or a number (without quotation marks) that | |||||
* represents the position of the column within the list: 1 for | |||||
* the first column, 2 for the second column, and so on. | |||||
* @param mixed[] $criteria The range of cells that contains the conditions you specify. | |||||
* You can use any range for the criteria argument, as long as it | |||||
* includes at least one column label and at least one cell below | |||||
* the column label in which you specify a condition for the | |||||
* column. | |||||
* @return float | |||||
* | |||||
*/ | |||||
public static function DSTDEV($database, $field, $criteria) | |||||
{ | |||||
$field = self::fieldExtract($database, $field); | |||||
if (is_null($field)) { | |||||
return null; | |||||
} | |||||
// Return | |||||
return PHPExcel_Calculation_Statistical::STDEV( | |||||
self::getFilteredColumn($database, $field, $criteria) | |||||
); | |||||
} | |||||
/** | |||||
* DSTDEVP | |||||
* | |||||
* Calculates the standard deviation of a population based on the entire population by using the | |||||
* numbers in a column of a list or database that match conditions that you specify. | |||||
* | |||||
* Excel Function: | |||||
* DSTDEVP(database,field,criteria) | |||||
* | |||||
* @access public | |||||
* @category Database Functions | |||||
* @param mixed[] $database The range of cells that makes up the list or database. | |||||
* A database is a list of related data in which rows of related | |||||
* information are records, and columns of data are fields. The | |||||
* first row of the list contains labels for each column. | |||||
* @param string|integer $field Indicates which column is used in the function. Enter the | |||||
* column label enclosed between double quotation marks, such as | |||||
* "Age" or "Yield," or a number (without quotation marks) that | |||||
* represents the position of the column within the list: 1 for | |||||
* the first column, 2 for the second column, and so on. | |||||
* @param mixed[] $criteria The range of cells that contains the conditions you specify. | |||||
* You can use any range for the criteria argument, as long as it | |||||
* includes at least one column label and at least one cell below | |||||
* the column label in which you specify a condition for the | |||||
* column. | |||||
* @return float | |||||
* | |||||
*/ | |||||
public static function DSTDEVP($database, $field, $criteria) | |||||
{ | |||||
$field = self::fieldExtract($database, $field); | |||||
if (is_null($field)) { | |||||
return null; | |||||
} | |||||
// Return | |||||
return PHPExcel_Calculation_Statistical::STDEVP( | |||||
self::getFilteredColumn($database, $field, $criteria) | |||||
); | |||||
} | |||||
/** | |||||
* DSUM | |||||
* | |||||
* Adds the numbers in a column of a list or database that match conditions that you specify. | |||||
* | |||||
* Excel Function: | |||||
* DSUM(database,field,criteria) | |||||
* | |||||
* @access public | |||||
* @category Database Functions | |||||
* @param mixed[] $database The range of cells that makes up the list or database. | |||||
* A database is a list of related data in which rows of related | |||||
* information are records, and columns of data are fields. The | |||||
* first row of the list contains labels for each column. | |||||
* @param string|integer $field Indicates which column is used in the function. Enter the | |||||
* column label enclosed between double quotation marks, such as | |||||
* "Age" or "Yield," or a number (without quotation marks) that | |||||
* represents the position of the column within the list: 1 for | |||||
* the first column, 2 for the second column, and so on. | |||||
* @param mixed[] $criteria The range of cells that contains the conditions you specify. | |||||
* You can use any range for the criteria argument, as long as it | |||||
* includes at least one column label and at least one cell below | |||||
* the column label in which you specify a condition for the | |||||
* column. | |||||
* @return float | |||||
* | |||||
*/ | |||||
public static function DSUM($database, $field, $criteria) | |||||
{ | |||||
$field = self::fieldExtract($database, $field); | |||||
if (is_null($field)) { | |||||
return null; | |||||
} | |||||
// Return | |||||
return PHPExcel_Calculation_MathTrig::SUM( | |||||
self::getFilteredColumn($database, $field, $criteria) | |||||
); | |||||
} | |||||
/** | |||||
* DVAR | |||||
* | |||||
* Estimates the variance of a population based on a sample by using the numbers in a column | |||||
* of a list or database that match conditions that you specify. | |||||
* | |||||
* Excel Function: | |||||
* DVAR(database,field,criteria) | |||||
* | |||||
* @access public | |||||
* @category Database Functions | |||||
* @param mixed[] $database The range of cells that makes up the list or database. | |||||
* A database is a list of related data in which rows of related | |||||
* information are records, and columns of data are fields. The | |||||
* first row of the list contains labels for each column. | |||||
* @param string|integer $field Indicates which column is used in the function. Enter the | |||||
* column label enclosed between double quotation marks, such as | |||||
* "Age" or "Yield," or a number (without quotation marks) that | |||||
* represents the position of the column within the list: 1 for | |||||
* the first column, 2 for the second column, and so on. | |||||
* @param mixed[] $criteria The range of cells that contains the conditions you specify. | |||||
* You can use any range for the criteria argument, as long as it | |||||
* includes at least one column label and at least one cell below | |||||
* the column label in which you specify a condition for the | |||||
* column. | |||||
* @return float | |||||
* | |||||
*/ | |||||
public static function DVAR($database, $field, $criteria) | |||||
{ | |||||
$field = self::fieldExtract($database, $field); | |||||
if (is_null($field)) { | |||||
return null; | |||||
} | |||||
// Return | |||||
return PHPExcel_Calculation_Statistical::VARFunc( | |||||
self::getFilteredColumn($database, $field, $criteria) | |||||
); | |||||
} | |||||
/** | |||||
* DVARP | |||||
* | |||||
* Calculates the variance of a population based on the entire population by using the numbers | |||||
* in a column of a list or database that match conditions that you specify. | |||||
* | |||||
* Excel Function: | |||||
* DVARP(database,field,criteria) | |||||
* | |||||
* @access public | |||||
* @category Database Functions | |||||
* @param mixed[] $database The range of cells that makes up the list or database. | |||||
* A database is a list of related data in which rows of related | |||||
* information are records, and columns of data are fields. The | |||||
* first row of the list contains labels for each column. | |||||
* @param string|integer $field Indicates which column is used in the function. Enter the | |||||
* column label enclosed between double quotation marks, such as | |||||
* "Age" or "Yield," or a number (without quotation marks) that | |||||
* represents the position of the column within the list: 1 for | |||||
* the first column, 2 for the second column, and so on. | |||||
* @param mixed[] $criteria The range of cells that contains the conditions you specify. | |||||
* You can use any range for the criteria argument, as long as it | |||||
* includes at least one column label and at least one cell below | |||||
* the column label in which you specify a condition for the | |||||
* column. | |||||
* @return float | |||||
* | |||||
*/ | |||||
public static function DVARP($database, $field, $criteria) | |||||
{ | |||||
$field = self::fieldExtract($database, $field); | |||||
if (is_null($field)) { | |||||
return null; | |||||
} | |||||
// Return | |||||
return PHPExcel_Calculation_Statistical::VARP( | |||||
self::getFilteredColumn($database, $field, $criteria) | |||||
); | |||||
} | |||||
} |
@ -0,0 +1,46 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Calculation_Exception | |||||
* | |||||
* 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_Calculation | |||||
* @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_Calculation_Exception extends PHPExcel_Exception | |||||
{ | |||||
/** | |||||
* Error handler callback | |||||
* | |||||
* @param mixed $code | |||||
* @param mixed $string | |||||
* @param mixed $file | |||||
* @param mixed $line | |||||
* @param mixed $context | |||||
*/ | |||||
public static function errorHandlerCallback($code, $string, $file, $line, $context) | |||||
{ | |||||
$e = new self($string, $code); | |||||
$e->line = $line; | |||||
$e->file = $file; | |||||
throw $e; | |||||
} | |||||
} |
@ -0,0 +1,45 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Calculation_ExceptionHandler | |||||
* | |||||
* 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_Calculation | |||||
* @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_Calculation_ExceptionHandler | |||||
{ | |||||
/** | |||||
* Register errorhandler | |||||
*/ | |||||
public function __construct() | |||||
{ | |||||
set_error_handler(array('PHPExcel_Calculation_Exception', 'errorHandlerCallback'), E_ALL); | |||||
} | |||||
/** | |||||
* Unregister errorhandler | |||||
*/ | |||||
public function __destruct() | |||||
{ | |||||
restore_error_handler(); | |||||
} | |||||
} |
@ -0,0 +1,622 @@ | |||||
<?php | |||||
/* | |||||
PARTLY BASED ON: | |||||
Copyright (c) 2007 E. W. Bachtal, Inc. | |||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software | |||||
and associated documentation files (the "Software"), to deal in the Software without restriction, | |||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, | |||||
subject to the following conditions: | |||||
The above copyright notice and this permission notice shall be included in all copies or substantial | |||||
portions of the Software. | |||||
The software is provided "as is", without warranty of any kind, express or implied, including but not | |||||
limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In | |||||
no event shall the authors or copyright holders be liable for any claim, damages or other liability, | |||||
whether in an action of contract, tort or otherwise, arising from, out of or in connection with the | |||||
software or the use or other dealings in the software. | |||||
http://ewbi.blogs.com/develops/2007/03/excel_formula_p.html | |||||
http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html | |||||
*/ | |||||
/** | |||||
* PHPExcel_Calculation_FormulaParser | |||||
* | |||||
* 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_Calculation | |||||
* @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_Calculation_FormulaParser | |||||
{ | |||||
/* Character constants */ | |||||
const QUOTE_DOUBLE = '"'; | |||||
const QUOTE_SINGLE = '\''; | |||||
const BRACKET_CLOSE = ']'; | |||||
const BRACKET_OPEN = '['; | |||||
const BRACE_OPEN = '{'; | |||||
const BRACE_CLOSE = '}'; | |||||
const PAREN_OPEN = '('; | |||||
const PAREN_CLOSE = ')'; | |||||
const SEMICOLON = ';'; | |||||
const WHITESPACE = ' '; | |||||
const COMMA = ','; | |||||
const ERROR_START = '#'; | |||||
const OPERATORS_SN = "+-"; | |||||
const OPERATORS_INFIX = "+-*/^&=><"; | |||||
const OPERATORS_POSTFIX = "%"; | |||||
/** | |||||
* Formula | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $formula; | |||||
/** | |||||
* Tokens | |||||
* | |||||
* @var PHPExcel_Calculation_FormulaToken[] | |||||
*/ | |||||
private $tokens = array(); | |||||
/** | |||||
* Create a new PHPExcel_Calculation_FormulaParser | |||||
* | |||||
* @param string $pFormula Formula to parse | |||||
* @throws PHPExcel_Calculation_Exception | |||||
*/ | |||||
public function __construct($pFormula = '') | |||||
{ | |||||
// Check parameters | |||||
if (is_null($pFormula)) { | |||||
throw new PHPExcel_Calculation_Exception("Invalid parameter passed: formula"); | |||||
} | |||||
// Initialise values | |||||
$this->formula = trim($pFormula); | |||||
// Parse! | |||||
$this->parseToTokens(); | |||||
} | |||||
/** | |||||
* Get Formula | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getFormula() | |||||
{ | |||||
return $this->formula; | |||||
} | |||||
/** | |||||
* Get Token | |||||
* | |||||
* @param int $pId Token id | |||||
* @return string | |||||
* @throws PHPExcel_Calculation_Exception | |||||
*/ | |||||
public function getToken($pId = 0) | |||||
{ | |||||
if (isset($this->tokens[$pId])) { | |||||
return $this->tokens[$pId]; | |||||
} else { | |||||
throw new PHPExcel_Calculation_Exception("Token with id $pId does not exist."); | |||||
} | |||||
} | |||||
/** | |||||
* Get Token count | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getTokenCount() | |||||
{ | |||||
return count($this->tokens); | |||||
} | |||||
/** | |||||
* Get Tokens | |||||
* | |||||
* @return PHPExcel_Calculation_FormulaToken[] | |||||
*/ | |||||
public function getTokens() | |||||
{ | |||||
return $this->tokens; | |||||
} | |||||
/** | |||||
* Parse to tokens | |||||
*/ | |||||
private function parseToTokens() | |||||
{ | |||||
// No attempt is made to verify formulas; assumes formulas are derived from Excel, where | |||||
// they can only exist if valid; stack overflows/underflows sunk as nulls without exceptions. | |||||
// Check if the formula has a valid starting = | |||||
$formulaLength = strlen($this->formula); | |||||
if ($formulaLength < 2 || $this->formula[0] != '=') { | |||||
return; | |||||
} | |||||
// Helper variables | |||||
$tokens1 = $tokens2 = $stack = array(); | |||||
$inString = $inPath = $inRange = $inError = false; | |||||
$token = $previousToken = $nextToken = null; | |||||
$index = 1; | |||||
$value = ''; | |||||
$ERRORS = array("#NULL!", "#DIV/0!", "#VALUE!", "#REF!", "#NAME?", "#NUM!", "#N/A"); | |||||
$COMPARATORS_MULTI = array(">=", "<=", "<>"); | |||||
while ($index < $formulaLength) { | |||||
// state-dependent character evaluation (order is important) | |||||
// double-quoted strings | |||||
// embeds are doubled | |||||
// end marks token | |||||
if ($inString) { | |||||
if ($this->formula[$index] == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { | |||||
if ((($index + 2) <= $formulaLength) && ($this->formula[$index + 1] == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE)) { | |||||
$value .= PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE; | |||||
++$index; | |||||
} else { | |||||
$inString = false; | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_TEXT); | |||||
$value = ""; | |||||
} | |||||
} else { | |||||
$value .= $this->formula[$index]; | |||||
} | |||||
++$index; | |||||
continue; | |||||
} | |||||
// single-quoted strings (links) | |||||
// embeds are double | |||||
// end does not mark a token | |||||
if ($inPath) { | |||||
if ($this->formula[$index] == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { | |||||
if ((($index + 2) <= $formulaLength) && ($this->formula[$index + 1] == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE)) { | |||||
$value .= PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE; | |||||
++$index; | |||||
} else { | |||||
$inPath = false; | |||||
} | |||||
} else { | |||||
$value .= $this->formula[$index]; | |||||
} | |||||
++$index; | |||||
continue; | |||||
} | |||||
// bracked strings (R1C1 range index or linked workbook name) | |||||
// no embeds (changed to "()" by Excel) | |||||
// end does not mark a token | |||||
if ($inRange) { | |||||
if ($this->formula[$index] == PHPExcel_Calculation_FormulaParser::BRACKET_CLOSE) { | |||||
$inRange = false; | |||||
} | |||||
$value .= $this->formula[$index]; | |||||
++$index; | |||||
continue; | |||||
} | |||||
// error values | |||||
// end marks a token, determined from absolute list of values | |||||
if ($inError) { | |||||
$value .= $this->formula[$index]; | |||||
++$index; | |||||
if (in_array($value, $ERRORS)) { | |||||
$inError = false; | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_ERROR); | |||||
$value = ""; | |||||
} | |||||
continue; | |||||
} | |||||
// scientific notation check | |||||
if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_SN, $this->formula[$index]) !== false) { | |||||
if (strlen($value) > 1) { | |||||
if (preg_match("/^[1-9]{1}(\.[0-9]+)?E{1}$/", $this->formula[$index]) != 0) { | |||||
$value .= $this->formula[$index]; | |||||
++$index; | |||||
continue; | |||||
} | |||||
} | |||||
} | |||||
// independent character evaluation (order not important) | |||||
// establish state-dependent character evaluations | |||||
if ($this->formula[$index] == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { | |||||
if (strlen($value > 0)) { | |||||
// unexpected | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); | |||||
$value = ""; | |||||
} | |||||
$inString = true; | |||||
++$index; | |||||
continue; | |||||
} | |||||
if ($this->formula[$index] == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { | |||||
if (strlen($value) > 0) { | |||||
// unexpected | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); | |||||
$value = ""; | |||||
} | |||||
$inPath = true; | |||||
++$index; | |||||
continue; | |||||
} | |||||
if ($this->formula[$index] == PHPExcel_Calculation_FormulaParser::BRACKET_OPEN) { | |||||
$inRange = true; | |||||
$value .= PHPExcel_Calculation_FormulaParser::BRACKET_OPEN; | |||||
++$index; | |||||
continue; | |||||
} | |||||
if ($this->formula[$index] == PHPExcel_Calculation_FormulaParser::ERROR_START) { | |||||
if (strlen($value) > 0) { | |||||
// unexpected | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); | |||||
$value = ""; | |||||
} | |||||
$inError = true; | |||||
$value .= PHPExcel_Calculation_FormulaParser::ERROR_START; | |||||
++$index; | |||||
continue; | |||||
} | |||||
// mark start and end of arrays and array rows | |||||
if ($this->formula[$index] == PHPExcel_Calculation_FormulaParser::BRACE_OPEN) { | |||||
if (strlen($value) > 0) { | |||||
// unexpected | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); | |||||
$value = ""; | |||||
} | |||||
$tmp = new PHPExcel_Calculation_FormulaToken("ARRAY", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); | |||||
$tokens1[] = $tmp; | |||||
$stack[] = clone $tmp; | |||||
$tmp = new PHPExcel_Calculation_FormulaToken("ARRAYROW", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); | |||||
$tokens1[] = $tmp; | |||||
$stack[] = clone $tmp; | |||||
++$index; | |||||
continue; | |||||
} | |||||
if ($this->formula[$index] == PHPExcel_Calculation_FormulaParser::SEMICOLON) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tmp = array_pop($stack); | |||||
$tmp->setValue(""); | |||||
$tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); | |||||
$tokens1[] = $tmp; | |||||
$tmp = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT); | |||||
$tokens1[] = $tmp; | |||||
$tmp = new PHPExcel_Calculation_FormulaToken("ARRAYROW", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); | |||||
$tokens1[] = $tmp; | |||||
$stack[] = clone $tmp; | |||||
++$index; | |||||
continue; | |||||
} | |||||
if ($this->formula[$index] == PHPExcel_Calculation_FormulaParser::BRACE_CLOSE) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tmp = array_pop($stack); | |||||
$tmp->setValue(""); | |||||
$tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); | |||||
$tokens1[] = $tmp; | |||||
$tmp = array_pop($stack); | |||||
$tmp->setValue(""); | |||||
$tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); | |||||
$tokens1[] = $tmp; | |||||
++$index; | |||||
continue; | |||||
} | |||||
// trim white-space | |||||
if ($this->formula[$index] == PHPExcel_Calculation_FormulaParser::WHITESPACE) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken("", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE); | |||||
++$index; | |||||
while (($this->formula[$index] == PHPExcel_Calculation_FormulaParser::WHITESPACE) && ($index < $formulaLength)) { | |||||
++$index; | |||||
} | |||||
continue; | |||||
} | |||||
// multi-character comparators | |||||
if (($index + 2) <= $formulaLength) { | |||||
if (in_array(substr($this->formula, $index, 2), $COMPARATORS_MULTI)) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken(substr($this->formula, $index, 2), PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); | |||||
$index += 2; | |||||
continue; | |||||
} | |||||
} | |||||
// standard infix operators | |||||
if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_INFIX, $this->formula[$index]) !== false) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] =new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($this->formula[$index], PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX); | |||||
++$index; | |||||
continue; | |||||
} | |||||
// standard postfix operators (only one) | |||||
if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_POSTFIX, $this->formula[$index]) !== false) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($this->formula[$index], PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX); | |||||
++$index; | |||||
continue; | |||||
} | |||||
// start subexpression or function | |||||
if ($this->formula[$index] == PHPExcel_Calculation_FormulaParser::PAREN_OPEN) { | |||||
if (strlen($value) > 0) { | |||||
$tmp = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); | |||||
$tokens1[] = $tmp; | |||||
$stack[] = clone $tmp; | |||||
$value = ""; | |||||
} else { | |||||
$tmp = new PHPExcel_Calculation_FormulaToken("", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); | |||||
$tokens1[] = $tmp; | |||||
$stack[] = clone $tmp; | |||||
} | |||||
++$index; | |||||
continue; | |||||
} | |||||
// function, subexpression, or array parameters, or operand unions | |||||
if ($this->formula[$index] == PHPExcel_Calculation_FormulaParser::COMMA) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tmp = array_pop($stack); | |||||
$tmp->setValue(""); | |||||
$tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); | |||||
$stack[] = $tmp; | |||||
if ($tmp->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_UNION); | |||||
} else { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT); | |||||
} | |||||
++$index; | |||||
continue; | |||||
} | |||||
// stop subexpression | |||||
if ($this->formula[$index] == PHPExcel_Calculation_FormulaParser::PAREN_CLOSE) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tmp = array_pop($stack); | |||||
$tmp->setValue(""); | |||||
$tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); | |||||
$tokens1[] = $tmp; | |||||
++$index; | |||||
continue; | |||||
} | |||||
// token accumulation | |||||
$value .= $this->formula[$index]; | |||||
++$index; | |||||
} | |||||
// dump remaining accumulation | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
} | |||||
// move tokenList to new set, excluding unnecessary white-space tokens and converting necessary ones to intersections | |||||
$tokenCount = count($tokens1); | |||||
for ($i = 0; $i < $tokenCount; ++$i) { | |||||
$token = $tokens1[$i]; | |||||
if (isset($tokens1[$i - 1])) { | |||||
$previousToken = $tokens1[$i - 1]; | |||||
} else { | |||||
$previousToken = null; | |||||
} | |||||
if (isset($tokens1[$i + 1])) { | |||||
$nextToken = $tokens1[$i + 1]; | |||||
} else { | |||||
$nextToken = null; | |||||
} | |||||
if (is_null($token)) { | |||||
continue; | |||||
} | |||||
if ($token->getTokenType() != PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE) { | |||||
$tokens2[] = $token; | |||||
continue; | |||||
} | |||||
if (is_null($previousToken)) { | |||||
continue; | |||||
} | |||||
if (! ( | |||||
(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || | |||||
(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || | |||||
($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) | |||||
) ) { | |||||
continue; | |||||
} | |||||
if (is_null($nextToken)) { | |||||
continue; | |||||
} | |||||
if (! ( | |||||
(($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) || | |||||
(($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) || | |||||
($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) | |||||
) ) { | |||||
continue; | |||||
} | |||||
$tokens2[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_INTERSECTION); | |||||
} | |||||
// move tokens to final list, switching infix "-" operators to prefix when appropriate, switching infix "+" operators | |||||
// to noop when appropriate, identifying operand and infix-operator subtypes, and pulling "@" from function names | |||||
$this->tokens = array(); | |||||
$tokenCount = count($tokens2); | |||||
for ($i = 0; $i < $tokenCount; ++$i) { | |||||
$token = $tokens2[$i]; | |||||
if (isset($tokens2[$i - 1])) { | |||||
$previousToken = $tokens2[$i - 1]; | |||||
} else { | |||||
$previousToken = null; | |||||
} | |||||
if (isset($tokens2[$i + 1])) { | |||||
$nextToken = $tokens2[$i + 1]; | |||||
} else { | |||||
$nextToken = null; | |||||
} | |||||
if (is_null($token)) { | |||||
continue; | |||||
} | |||||
if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "-") { | |||||
if ($i == 0) { | |||||
$token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX); | |||||
} elseif ((($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && | |||||
($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || | |||||
(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && | |||||
($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || | |||||
($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || | |||||
($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)) { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); | |||||
} else { | |||||
$token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX); | |||||
} | |||||
$this->tokens[] = $token; | |||||
continue; | |||||
} | |||||
if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "+") { | |||||
if ($i == 0) { | |||||
continue; | |||||
} elseif ((($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && | |||||
($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || | |||||
(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && | |||||
($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || | |||||
($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || | |||||
($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)) { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); | |||||
} else { | |||||
continue; | |||||
} | |||||
$this->tokens[] = $token; | |||||
continue; | |||||
} | |||||
if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && | |||||
$token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { | |||||
if (strpos("<>=", substr($token->getValue(), 0, 1)) !== false) { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); | |||||
} elseif ($token->getValue() == "&") { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_CONCATENATION); | |||||
} else { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); | |||||
} | |||||
$this->tokens[] = $token; | |||||
continue; | |||||
} | |||||
if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND && | |||||
$token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { | |||||
if (!is_numeric($token->getValue())) { | |||||
if (strtoupper($token->getValue()) == "TRUE" || strtoupper($token->getValue() == "FALSE")) { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); | |||||
} else { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_RANGE); | |||||
} | |||||
} else { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NUMBER); | |||||
} | |||||
$this->tokens[] = $token; | |||||
continue; | |||||
} | |||||
if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) { | |||||
if (strlen($token->getValue() > 0)) { | |||||
if (substr($token->getValue(), 0, 1) == "@") { | |||||
$token->setValue(substr($token->getValue(), 1)); | |||||
} | |||||
} | |||||
} | |||||
$this->tokens[] = $token; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,622 @@ | |||||
<?php | |||||
/* | |||||
PARTLY BASED ON: | |||||
Copyright (c) 2007 E. W. Bachtal, Inc. | |||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software | |||||
and associated documentation files (the "Software"), to deal in the Software without restriction, | |||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, | |||||
subject to the following conditions: | |||||
The above copyright notice and this permission notice shall be included in all copies or substantial | |||||
portions of the Software. | |||||
The software is provided "as is", without warranty of any kind, express or implied, including but not | |||||
limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In | |||||
no event shall the authors or copyright holders be liable for any claim, damages or other liability, | |||||
whether in an action of contract, tort or otherwise, arising from, out of or in connection with the | |||||
software or the use or other dealings in the software. | |||||
http://ewbi.blogs.com/develops/2007/03/excel_formula_p.html | |||||
http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html | |||||
*/ | |||||
/** | |||||
* PHPExcel_Calculation_FormulaParser | |||||
* | |||||
* 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_Calculation | |||||
* @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_Calculation_FormulaParser | |||||
{ | |||||
/* Character constants */ | |||||
const QUOTE_DOUBLE = '"'; | |||||
const QUOTE_SINGLE = '\''; | |||||
const BRACKET_CLOSE = ']'; | |||||
const BRACKET_OPEN = '['; | |||||
const BRACE_OPEN = '{'; | |||||
const BRACE_CLOSE = '}'; | |||||
const PAREN_OPEN = '('; | |||||
const PAREN_CLOSE = ')'; | |||||
const SEMICOLON = ';'; | |||||
const WHITESPACE = ' '; | |||||
const COMMA = ','; | |||||
const ERROR_START = '#'; | |||||
const OPERATORS_SN = "+-"; | |||||
const OPERATORS_INFIX = "+-*/^&=><"; | |||||
const OPERATORS_POSTFIX = "%"; | |||||
/** | |||||
* Formula | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $formula; | |||||
/** | |||||
* Tokens | |||||
* | |||||
* @var PHPExcel_Calculation_FormulaToken[] | |||||
*/ | |||||
private $tokens = array(); | |||||
/** | |||||
* Create a new PHPExcel_Calculation_FormulaParser | |||||
* | |||||
* @param string $pFormula Formula to parse | |||||
* @throws PHPExcel_Calculation_Exception | |||||
*/ | |||||
public function __construct($pFormula = '') | |||||
{ | |||||
// Check parameters | |||||
if (is_null($pFormula)) { | |||||
throw new PHPExcel_Calculation_Exception("Invalid parameter passed: formula"); | |||||
} | |||||
// Initialise values | |||||
$this->formula = trim($pFormula); | |||||
// Parse! | |||||
$this->parseToTokens(); | |||||
} | |||||
/** | |||||
* Get Formula | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getFormula() | |||||
{ | |||||
return $this->formula; | |||||
} | |||||
/** | |||||
* Get Token | |||||
* | |||||
* @param int $pId Token id | |||||
* @return string | |||||
* @throws PHPExcel_Calculation_Exception | |||||
*/ | |||||
public function getToken($pId = 0) | |||||
{ | |||||
if (isset($this->tokens[$pId])) { | |||||
return $this->tokens[$pId]; | |||||
} else { | |||||
throw new PHPExcel_Calculation_Exception("Token with id $pId does not exist."); | |||||
} | |||||
} | |||||
/** | |||||
* Get Token count | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getTokenCount() | |||||
{ | |||||
return count($this->tokens); | |||||
} | |||||
/** | |||||
* Get Tokens | |||||
* | |||||
* @return PHPExcel_Calculation_FormulaToken[] | |||||
*/ | |||||
public function getTokens() | |||||
{ | |||||
return $this->tokens; | |||||
} | |||||
/** | |||||
* Parse to tokens | |||||
*/ | |||||
private function parseToTokens() | |||||
{ | |||||
// No attempt is made to verify formulas; assumes formulas are derived from Excel, where | |||||
// they can only exist if valid; stack overflows/underflows sunk as nulls without exceptions. | |||||
// Check if the formula has a valid starting = | |||||
$formulaLength = strlen($this->formula); | |||||
if ($formulaLength < 2 || $this->formula{0} != '=') { | |||||
return; | |||||
} | |||||
// Helper variables | |||||
$tokens1 = $tokens2 = $stack = array(); | |||||
$inString = $inPath = $inRange = $inError = false; | |||||
$token = $previousToken = $nextToken = null; | |||||
$index = 1; | |||||
$value = ''; | |||||
$ERRORS = array("#NULL!", "#DIV/0!", "#VALUE!", "#REF!", "#NAME?", "#NUM!", "#N/A"); | |||||
$COMPARATORS_MULTI = array(">=", "<=", "<>"); | |||||
while ($index < $formulaLength) { | |||||
// state-dependent character evaluation (order is important) | |||||
// double-quoted strings | |||||
// embeds are doubled | |||||
// end marks token | |||||
if ($inString) { | |||||
if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { | |||||
if ((($index + 2) <= $formulaLength) && ($this->formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE)) { | |||||
$value .= PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE; | |||||
++$index; | |||||
} else { | |||||
$inString = false; | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_TEXT); | |||||
$value = ""; | |||||
} | |||||
} else { | |||||
$value .= $this->formula{$index}; | |||||
} | |||||
++$index; | |||||
continue; | |||||
} | |||||
// single-quoted strings (links) | |||||
// embeds are double | |||||
// end does not mark a token | |||||
if ($inPath) { | |||||
if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { | |||||
if ((($index + 2) <= $formulaLength) && ($this->formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE)) { | |||||
$value .= PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE; | |||||
++$index; | |||||
} else { | |||||
$inPath = false; | |||||
} | |||||
} else { | |||||
$value .= $this->formula{$index}; | |||||
} | |||||
++$index; | |||||
continue; | |||||
} | |||||
// bracked strings (R1C1 range index or linked workbook name) | |||||
// no embeds (changed to "()" by Excel) | |||||
// end does not mark a token | |||||
if ($inRange) { | |||||
if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_CLOSE) { | |||||
$inRange = false; | |||||
} | |||||
$value .= $this->formula{$index}; | |||||
++$index; | |||||
continue; | |||||
} | |||||
// error values | |||||
// end marks a token, determined from absolute list of values | |||||
if ($inError) { | |||||
$value .= $this->formula{$index}; | |||||
++$index; | |||||
if (in_array($value, $ERRORS)) { | |||||
$inError = false; | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_ERROR); | |||||
$value = ""; | |||||
} | |||||
continue; | |||||
} | |||||
// scientific notation check | |||||
if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_SN, $this->formula{$index}) !== false) { | |||||
if (strlen($value) > 1) { | |||||
if (preg_match("/^[1-9]{1}(\.[0-9]+)?E{1}$/", $this->formula{$index}) != 0) { | |||||
$value .= $this->formula{$index}; | |||||
++$index; | |||||
continue; | |||||
} | |||||
} | |||||
} | |||||
// independent character evaluation (order not important) | |||||
// establish state-dependent character evaluations | |||||
if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { | |||||
if (strlen($value > 0)) { | |||||
// unexpected | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); | |||||
$value = ""; | |||||
} | |||||
$inString = true; | |||||
++$index; | |||||
continue; | |||||
} | |||||
if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { | |||||
if (strlen($value) > 0) { | |||||
// unexpected | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); | |||||
$value = ""; | |||||
} | |||||
$inPath = true; | |||||
++$index; | |||||
continue; | |||||
} | |||||
if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_OPEN) { | |||||
$inRange = true; | |||||
$value .= PHPExcel_Calculation_FormulaParser::BRACKET_OPEN; | |||||
++$index; | |||||
continue; | |||||
} | |||||
if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::ERROR_START) { | |||||
if (strlen($value) > 0) { | |||||
// unexpected | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); | |||||
$value = ""; | |||||
} | |||||
$inError = true; | |||||
$value .= PHPExcel_Calculation_FormulaParser::ERROR_START; | |||||
++$index; | |||||
continue; | |||||
} | |||||
// mark start and end of arrays and array rows | |||||
if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_OPEN) { | |||||
if (strlen($value) > 0) { | |||||
// unexpected | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); | |||||
$value = ""; | |||||
} | |||||
$tmp = new PHPExcel_Calculation_FormulaToken("ARRAY", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); | |||||
$tokens1[] = $tmp; | |||||
$stack[] = clone $tmp; | |||||
$tmp = new PHPExcel_Calculation_FormulaToken("ARRAYROW", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); | |||||
$tokens1[] = $tmp; | |||||
$stack[] = clone $tmp; | |||||
++$index; | |||||
continue; | |||||
} | |||||
if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::SEMICOLON) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tmp = array_pop($stack); | |||||
$tmp->setValue(""); | |||||
$tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); | |||||
$tokens1[] = $tmp; | |||||
$tmp = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT); | |||||
$tokens1[] = $tmp; | |||||
$tmp = new PHPExcel_Calculation_FormulaToken("ARRAYROW", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); | |||||
$tokens1[] = $tmp; | |||||
$stack[] = clone $tmp; | |||||
++$index; | |||||
continue; | |||||
} | |||||
if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_CLOSE) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tmp = array_pop($stack); | |||||
$tmp->setValue(""); | |||||
$tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); | |||||
$tokens1[] = $tmp; | |||||
$tmp = array_pop($stack); | |||||
$tmp->setValue(""); | |||||
$tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); | |||||
$tokens1[] = $tmp; | |||||
++$index; | |||||
continue; | |||||
} | |||||
// trim white-space | |||||
if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken("", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE); | |||||
++$index; | |||||
while (($this->formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) && ($index < $formulaLength)) { | |||||
++$index; | |||||
} | |||||
continue; | |||||
} | |||||
// multi-character comparators | |||||
if (($index + 2) <= $formulaLength) { | |||||
if (in_array(substr($this->formula, $index, 2), $COMPARATORS_MULTI)) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken(substr($this->formula, $index, 2), PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); | |||||
$index += 2; | |||||
continue; | |||||
} | |||||
} | |||||
// standard infix operators | |||||
if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_INFIX, $this->formula{$index}) !== false) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] =new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($this->formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX); | |||||
++$index; | |||||
continue; | |||||
} | |||||
// standard postfix operators (only one) | |||||
if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_POSTFIX, $this->formula{$index}) !== false) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($this->formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX); | |||||
++$index; | |||||
continue; | |||||
} | |||||
// start subexpression or function | |||||
if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_OPEN) { | |||||
if (strlen($value) > 0) { | |||||
$tmp = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); | |||||
$tokens1[] = $tmp; | |||||
$stack[] = clone $tmp; | |||||
$value = ""; | |||||
} else { | |||||
$tmp = new PHPExcel_Calculation_FormulaToken("", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); | |||||
$tokens1[] = $tmp; | |||||
$stack[] = clone $tmp; | |||||
} | |||||
++$index; | |||||
continue; | |||||
} | |||||
// function, subexpression, or array parameters, or operand unions | |||||
if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::COMMA) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tmp = array_pop($stack); | |||||
$tmp->setValue(""); | |||||
$tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); | |||||
$stack[] = $tmp; | |||||
if ($tmp->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_UNION); | |||||
} else { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT); | |||||
} | |||||
++$index; | |||||
continue; | |||||
} | |||||
// stop subexpression | |||||
if ($this->formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_CLOSE) { | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
$value = ""; | |||||
} | |||||
$tmp = array_pop($stack); | |||||
$tmp->setValue(""); | |||||
$tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); | |||||
$tokens1[] = $tmp; | |||||
++$index; | |||||
continue; | |||||
} | |||||
// token accumulation | |||||
$value .= $this->formula{$index}; | |||||
++$index; | |||||
} | |||||
// dump remaining accumulation | |||||
if (strlen($value) > 0) { | |||||
$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); | |||||
} | |||||
// move tokenList to new set, excluding unnecessary white-space tokens and converting necessary ones to intersections | |||||
$tokenCount = count($tokens1); | |||||
for ($i = 0; $i < $tokenCount; ++$i) { | |||||
$token = $tokens1[$i]; | |||||
if (isset($tokens1[$i - 1])) { | |||||
$previousToken = $tokens1[$i - 1]; | |||||
} else { | |||||
$previousToken = null; | |||||
} | |||||
if (isset($tokens1[$i + 1])) { | |||||
$nextToken = $tokens1[$i + 1]; | |||||
} else { | |||||
$nextToken = null; | |||||
} | |||||
if (is_null($token)) { | |||||
continue; | |||||
} | |||||
if ($token->getTokenType() != PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE) { | |||||
$tokens2[] = $token; | |||||
continue; | |||||
} | |||||
if (is_null($previousToken)) { | |||||
continue; | |||||
} | |||||
if (! ( | |||||
(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || | |||||
(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || | |||||
($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) | |||||
) ) { | |||||
continue; | |||||
} | |||||
if (is_null($nextToken)) { | |||||
continue; | |||||
} | |||||
if (! ( | |||||
(($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) || | |||||
(($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) || | |||||
($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) | |||||
) ) { | |||||
continue; | |||||
} | |||||
$tokens2[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_INTERSECTION); | |||||
} | |||||
// move tokens to final list, switching infix "-" operators to prefix when appropriate, switching infix "+" operators | |||||
// to noop when appropriate, identifying operand and infix-operator subtypes, and pulling "@" from function names | |||||
$this->tokens = array(); | |||||
$tokenCount = count($tokens2); | |||||
for ($i = 0; $i < $tokenCount; ++$i) { | |||||
$token = $tokens2[$i]; | |||||
if (isset($tokens2[$i - 1])) { | |||||
$previousToken = $tokens2[$i - 1]; | |||||
} else { | |||||
$previousToken = null; | |||||
} | |||||
if (isset($tokens2[$i + 1])) { | |||||
$nextToken = $tokens2[$i + 1]; | |||||
} else { | |||||
$nextToken = null; | |||||
} | |||||
if (is_null($token)) { | |||||
continue; | |||||
} | |||||
if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "-") { | |||||
if ($i == 0) { | |||||
$token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX); | |||||
} elseif ((($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && | |||||
($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || | |||||
(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && | |||||
($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || | |||||
($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || | |||||
($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)) { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); | |||||
} else { | |||||
$token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX); | |||||
} | |||||
$this->tokens[] = $token; | |||||
continue; | |||||
} | |||||
if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "+") { | |||||
if ($i == 0) { | |||||
continue; | |||||
} elseif ((($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && | |||||
($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || | |||||
(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && | |||||
($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || | |||||
($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || | |||||
($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)) { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); | |||||
} else { | |||||
continue; | |||||
} | |||||
$this->tokens[] = $token; | |||||
continue; | |||||
} | |||||
if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && | |||||
$token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { | |||||
if (strpos("<>=", substr($token->getValue(), 0, 1)) !== false) { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); | |||||
} elseif ($token->getValue() == "&") { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_CONCATENATION); | |||||
} else { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); | |||||
} | |||||
$this->tokens[] = $token; | |||||
continue; | |||||
} | |||||
if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND && | |||||
$token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { | |||||
if (!is_numeric($token->getValue())) { | |||||
if (strtoupper($token->getValue()) == "TRUE" || strtoupper($token->getValue() == "FALSE")) { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); | |||||
} else { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_RANGE); | |||||
} | |||||
} else { | |||||
$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NUMBER); | |||||
} | |||||
$this->tokens[] = $token; | |||||
continue; | |||||
} | |||||
if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) { | |||||
if (strlen($token->getValue() > 0)) { | |||||
if (substr($token->getValue(), 0, 1) == "@") { | |||||
$token->setValue(substr($token->getValue(), 1)); | |||||
} | |||||
} | |||||
} | |||||
$this->tokens[] = $token; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,176 @@ | |||||
<?php | |||||
/* | |||||
PARTLY BASED ON: | |||||
Copyright (c) 2007 E. W. Bachtal, Inc. | |||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software | |||||
and associated documentation files (the "Software"), to deal in the Software without restriction, | |||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, | |||||
subject to the following conditions: | |||||
The above copyright notice and this permission notice shall be included in all copies or substantial | |||||
portions of the Software. | |||||
The software is provided "as is", without warranty of any kind, express or implied, including but not | |||||
limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In | |||||
no event shall the authors or copyright holders be liable for any claim, damages or other liability, | |||||
whether in an action of contract, tort or otherwise, arising from, out of or in connection with the | |||||
software or the use or other dealings in the software. | |||||
http://ewbi.blogs.com/develops/2007/03/excel_formula_p.html | |||||
http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html | |||||
*/ | |||||
/** | |||||
* PHPExcel_Calculation_FormulaToken | |||||
* | |||||
* 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_Calculation | |||||
* @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_Calculation_FormulaToken | |||||
{ | |||||
/* Token types */ | |||||
const TOKEN_TYPE_NOOP = 'Noop'; | |||||
const TOKEN_TYPE_OPERAND = 'Operand'; | |||||
const TOKEN_TYPE_FUNCTION = 'Function'; | |||||
const TOKEN_TYPE_SUBEXPRESSION = 'Subexpression'; | |||||
const TOKEN_TYPE_ARGUMENT = 'Argument'; | |||||
const TOKEN_TYPE_OPERATORPREFIX = 'OperatorPrefix'; | |||||
const TOKEN_TYPE_OPERATORINFIX = 'OperatorInfix'; | |||||
const TOKEN_TYPE_OPERATORPOSTFIX = 'OperatorPostfix'; | |||||
const TOKEN_TYPE_WHITESPACE = 'Whitespace'; | |||||
const TOKEN_TYPE_UNKNOWN = 'Unknown'; | |||||
/* Token subtypes */ | |||||
const TOKEN_SUBTYPE_NOTHING = 'Nothing'; | |||||
const TOKEN_SUBTYPE_START = 'Start'; | |||||
const TOKEN_SUBTYPE_STOP = 'Stop'; | |||||
const TOKEN_SUBTYPE_TEXT = 'Text'; | |||||
const TOKEN_SUBTYPE_NUMBER = 'Number'; | |||||
const TOKEN_SUBTYPE_LOGICAL = 'Logical'; | |||||
const TOKEN_SUBTYPE_ERROR = 'Error'; | |||||
const TOKEN_SUBTYPE_RANGE = 'Range'; | |||||
const TOKEN_SUBTYPE_MATH = 'Math'; | |||||
const TOKEN_SUBTYPE_CONCATENATION = 'Concatenation'; | |||||
const TOKEN_SUBTYPE_INTERSECTION = 'Intersection'; | |||||
const TOKEN_SUBTYPE_UNION = 'Union'; | |||||
/** | |||||
* Value | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $value; | |||||
/** | |||||
* Token Type (represented by TOKEN_TYPE_*) | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $tokenType; | |||||
/** | |||||
* Token SubType (represented by TOKEN_SUBTYPE_*) | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $tokenSubType; | |||||
/** | |||||
* Create a new PHPExcel_Calculation_FormulaToken | |||||
* | |||||
* @param string $pValue | |||||
* @param string $pTokenType Token type (represented by TOKEN_TYPE_*) | |||||
* @param string $pTokenSubType Token Subtype (represented by TOKEN_SUBTYPE_*) | |||||
*/ | |||||
public function __construct($pValue, $pTokenType = PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN, $pTokenSubType = PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) | |||||
{ | |||||
// Initialise values | |||||
$this->value = $pValue; | |||||
$this->tokenType = $pTokenType; | |||||
$this->tokenSubType = $pTokenSubType; | |||||
} | |||||
/** | |||||
* Get Value | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getValue() | |||||
{ | |||||
return $this->value; | |||||
} | |||||
/** | |||||
* Set Value | |||||
* | |||||
* @param string $value | |||||
*/ | |||||
public function setValue($value) | |||||
{ | |||||
$this->value = $value; | |||||
} | |||||
/** | |||||
* Get Token Type (represented by TOKEN_TYPE_*) | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getTokenType() | |||||
{ | |||||
return $this->tokenType; | |||||
} | |||||
/** | |||||
* Set Token Type | |||||
* | |||||
* @param string $value | |||||
*/ | |||||
public function setTokenType($value = PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN) | |||||
{ | |||||
$this->tokenType = $value; | |||||
} | |||||
/** | |||||
* Get Token SubType (represented by TOKEN_SUBTYPE_*) | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getTokenSubType() | |||||
{ | |||||
return $this->tokenSubType; | |||||
} | |||||
/** | |||||
* Set Token SubType | |||||
* | |||||
* @param string $value | |||||
*/ | |||||
public function setTokenSubType($value = PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) | |||||
{ | |||||
$this->tokenSubType = $value; | |||||
} | |||||
} |
@ -0,0 +1,148 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Calculation_Function | |||||
* | |||||
* 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_Calculation | |||||
* @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_Calculation_Function | |||||
{ | |||||
/* Function categories */ | |||||
const CATEGORY_CUBE = 'Cube'; | |||||
const CATEGORY_DATABASE = 'Database'; | |||||
const CATEGORY_DATE_AND_TIME = 'Date and Time'; | |||||
const CATEGORY_ENGINEERING = 'Engineering'; | |||||
const CATEGORY_FINANCIAL = 'Financial'; | |||||
const CATEGORY_INFORMATION = 'Information'; | |||||
const CATEGORY_LOGICAL = 'Logical'; | |||||
const CATEGORY_LOOKUP_AND_REFERENCE = 'Lookup and Reference'; | |||||
const CATEGORY_MATH_AND_TRIG = 'Math and Trig'; | |||||
const CATEGORY_STATISTICAL = 'Statistical'; | |||||
const CATEGORY_TEXT_AND_DATA = 'Text and Data'; | |||||
/** | |||||
* Category (represented by CATEGORY_*) | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $category; | |||||
/** | |||||
* Excel name | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $excelName; | |||||
/** | |||||
* PHPExcel name | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $phpExcelName; | |||||
/** | |||||
* Create a new PHPExcel_Calculation_Function | |||||
* | |||||
* @param string $pCategory Category (represented by CATEGORY_*) | |||||
* @param string $pExcelName Excel function name | |||||
* @param string $pPHPExcelName PHPExcel function mapping | |||||
* @throws PHPExcel_Calculation_Exception | |||||
*/ | |||||
public function __construct($pCategory = null, $pExcelName = null, $pPHPExcelName = null) | |||||
{ | |||||
if (($pCategory !== null) && ($pExcelName !== null) && ($pPHPExcelName !== null)) { | |||||
// Initialise values | |||||
$this->category = $pCategory; | |||||
$this->excelName = $pExcelName; | |||||
$this->phpExcelName = $pPHPExcelName; | |||||
} else { | |||||
throw new PHPExcel_Calculation_Exception("Invalid parameters passed."); | |||||
} | |||||
} | |||||
/** | |||||
* Get Category (represented by CATEGORY_*) | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getCategory() | |||||
{ | |||||
return $this->category; | |||||
} | |||||
/** | |||||
* Set Category (represented by CATEGORY_*) | |||||
* | |||||
* @param string $value | |||||
* @throws PHPExcel_Calculation_Exception | |||||
*/ | |||||
public function setCategory($value = null) | |||||
{ | |||||
if (!is_null($value)) { | |||||
$this->category = $value; | |||||
} else { | |||||
throw new PHPExcel_Calculation_Exception("Invalid parameter passed."); | |||||
} | |||||
} | |||||
/** | |||||
* Get Excel name | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getExcelName() | |||||
{ | |||||
return $this->excelName; | |||||
} | |||||
/** | |||||
* Set Excel name | |||||
* | |||||
* @param string $value | |||||
*/ | |||||
public function setExcelName($value) | |||||
{ | |||||
$this->excelName = $value; | |||||
} | |||||
/** | |||||
* Get PHPExcel name | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getPHPExcelName() | |||||
{ | |||||
return $this->phpExcelName; | |||||
} | |||||
/** | |||||
* Set PHPExcel name | |||||
* | |||||
* @param string $value | |||||
*/ | |||||
public function setPHPExcelName($value) | |||||
{ | |||||
$this->phpExcelName = $value; | |||||
} | |||||
} |
@ -0,0 +1,760 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** MAX_VALUE */ | |||||
define('MAX_VALUE', 1.2e308); | |||||
/** 2 / PI */ | |||||
define('M_2DIVPI', 0.63661977236758134307553505349006); | |||||
/** MAX_ITERATIONS */ | |||||
define('MAX_ITERATIONS', 256); | |||||
/** PRECISION */ | |||||
define('PRECISION', 8.88E-016); | |||||
/** | |||||
* PHPExcel_Calculation_Functions | |||||
* | |||||
* 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_Calculation | |||||
* @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_Calculation_Functions | |||||
{ | |||||
/** constants */ | |||||
const COMPATIBILITY_EXCEL = 'Excel'; | |||||
const COMPATIBILITY_GNUMERIC = 'Gnumeric'; | |||||
const COMPATIBILITY_OPENOFFICE = 'OpenOfficeCalc'; | |||||
const RETURNDATE_PHP_NUMERIC = 'P'; | |||||
const RETURNDATE_PHP_OBJECT = 'O'; | |||||
const RETURNDATE_EXCEL = 'E'; | |||||
/** | |||||
* Compatibility mode to use for error checking and responses | |||||
* | |||||
* @access private | |||||
* @var string | |||||
*/ | |||||
protected static $compatibilityMode = self::COMPATIBILITY_EXCEL; | |||||
/** | |||||
* Data Type to use when returning date values | |||||
* | |||||
* @access private | |||||
* @var string | |||||
*/ | |||||
protected static $returnDateType = self::RETURNDATE_EXCEL; | |||||
/** | |||||
* List of error codes | |||||
* | |||||
* @access private | |||||
* @var array | |||||
*/ | |||||
protected static $errorCodes = array( | |||||
'null' => '#NULL!', | |||||
'divisionbyzero' => '#DIV/0!', | |||||
'value' => '#VALUE!', | |||||
'reference' => '#REF!', | |||||
'name' => '#NAME?', | |||||
'num' => '#NUM!', | |||||
'na' => '#N/A', | |||||
'gettingdata' => '#GETTING_DATA' | |||||
); | |||||
/** | |||||
* Set the Compatibility Mode | |||||
* | |||||
* @access public | |||||
* @category Function Configuration | |||||
* @param string $compatibilityMode Compatibility Mode | |||||
* Permitted values are: | |||||
* PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL 'Excel' | |||||
* PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC 'Gnumeric' | |||||
* PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' | |||||
* @return boolean (Success or Failure) | |||||
*/ | |||||
public static function setCompatibilityMode($compatibilityMode) | |||||
{ | |||||
if (($compatibilityMode == self::COMPATIBILITY_EXCEL) || | |||||
($compatibilityMode == self::COMPATIBILITY_GNUMERIC) || | |||||
($compatibilityMode == self::COMPATIBILITY_OPENOFFICE)) { | |||||
self::$compatibilityMode = $compatibilityMode; | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* Return the current Compatibility Mode | |||||
* | |||||
* @access public | |||||
* @category Function Configuration | |||||
* @return string Compatibility Mode | |||||
* Possible Return values are: | |||||
* PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL 'Excel' | |||||
* PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC 'Gnumeric' | |||||
* PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' | |||||
*/ | |||||
public static function getCompatibilityMode() | |||||
{ | |||||
return self::$compatibilityMode; | |||||
} | |||||
/** | |||||
* Set the Return Date Format used by functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object) | |||||
* | |||||
* @access public | |||||
* @category Function Configuration | |||||
* @param string $returnDateType Return Date Format | |||||
* Permitted values are: | |||||
* PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC 'P' | |||||
* PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT 'O' | |||||
* PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E' | |||||
* @return boolean Success or failure | |||||
*/ | |||||
public static function setReturnDateType($returnDateType) | |||||
{ | |||||
if (($returnDateType == self::RETURNDATE_PHP_NUMERIC) || | |||||
($returnDateType == self::RETURNDATE_PHP_OBJECT) || | |||||
($returnDateType == self::RETURNDATE_EXCEL)) { | |||||
self::$returnDateType = $returnDateType; | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* Return the current Return Date Format for functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object) | |||||
* | |||||
* @access public | |||||
* @category Function Configuration | |||||
* @return string Return Date Format | |||||
* Possible Return values are: | |||||
* PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC 'P' | |||||
* PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT 'O' | |||||
* PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E' | |||||
*/ | |||||
public static function getReturnDateType() | |||||
{ | |||||
return self::$returnDateType; | |||||
} | |||||
/** | |||||
* DUMMY | |||||
* | |||||
* @access public | |||||
* @category Error Returns | |||||
* @return string #Not Yet Implemented | |||||
*/ | |||||
public static function DUMMY() | |||||
{ | |||||
return '#Not Yet Implemented'; | |||||
} | |||||
/** | |||||
* DIV0 | |||||
* | |||||
* @access public | |||||
* @category Error Returns | |||||
* @return string #Not Yet Implemented | |||||
*/ | |||||
public static function DIV0() | |||||
{ | |||||
return self::$errorCodes['divisionbyzero']; | |||||
} | |||||
/** | |||||
* NA | |||||
* | |||||
* Excel Function: | |||||
* =NA() | |||||
* | |||||
* Returns the error value #N/A | |||||
* #N/A is the error value that means "no value is available." | |||||
* | |||||
* @access public | |||||
* @category Logical Functions | |||||
* @return string #N/A! | |||||
*/ | |||||
public static function NA() | |||||
{ | |||||
return self::$errorCodes['na']; | |||||
} | |||||
/** | |||||
* NaN | |||||
* | |||||
* Returns the error value #NUM! | |||||
* | |||||
* @access public | |||||
* @category Error Returns | |||||
* @return string #NUM! | |||||
*/ | |||||
public static function NaN() | |||||
{ | |||||
return self::$errorCodes['num']; | |||||
} | |||||
/** | |||||
* NAME | |||||
* | |||||
* Returns the error value #NAME? | |||||
* | |||||
* @access public | |||||
* @category Error Returns | |||||
* @return string #NAME? | |||||
*/ | |||||
public static function NAME() | |||||
{ | |||||
return self::$errorCodes['name']; | |||||
} | |||||
/** | |||||
* REF | |||||
* | |||||
* Returns the error value #REF! | |||||
* | |||||
* @access public | |||||
* @category Error Returns | |||||
* @return string #REF! | |||||
*/ | |||||
public static function REF() | |||||
{ | |||||
return self::$errorCodes['reference']; | |||||
} | |||||
/** | |||||
* NULL | |||||
* | |||||
* Returns the error value #NULL! | |||||
* | |||||
* @access public | |||||
* @category Error Returns | |||||
* @return string #NULL! | |||||
*/ | |||||
public static function NULL() | |||||
{ | |||||
return self::$errorCodes['null']; | |||||
} | |||||
/** | |||||
* VALUE | |||||
* | |||||
* Returns the error value #VALUE! | |||||
* | |||||
* @access public | |||||
* @category Error Returns | |||||
* @return string #VALUE! | |||||
*/ | |||||
public static function VALUE() | |||||
{ | |||||
return self::$errorCodes['value']; | |||||
} | |||||
public static function isMatrixValue($idx) | |||||
{ | |||||
return ((substr_count($idx, '.') <= 1) || (preg_match('/\.[A-Z]/', $idx) > 0)); | |||||
} | |||||
public static function isValue($idx) | |||||
{ | |||||
return (substr_count($idx, '.') == 0); | |||||
} | |||||
public static function isCellValue($idx) | |||||
{ | |||||
return (substr_count($idx, '.') > 1); | |||||
} | |||||
public static function ifCondition($condition) | |||||
{ | |||||
$condition = PHPExcel_Calculation_Functions::flattenSingleValue($condition); | |||||
if (!isset($condition[0])) { | |||||
$condition = '=""'; | |||||
} | |||||
if (!in_array($condition[0], array('>', '<', '='))) { | |||||
if (!is_numeric($condition)) { | |||||
$condition = PHPExcel_Calculation::wrapResult(strtoupper($condition)); | |||||
} | |||||
return '=' . $condition; | |||||
} else { | |||||
preg_match('/([<>=]+)(.*)/', $condition, $matches); | |||||
list(, $operator, $operand) = $matches; | |||||
if (!is_numeric($operand)) { | |||||
$operand = str_replace('"', '""', $operand); | |||||
$operand = PHPExcel_Calculation::wrapResult(strtoupper($operand)); | |||||
} | |||||
return $operator.$operand; | |||||
} | |||||
} | |||||
/** | |||||
* ERROR_TYPE | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function ERROR_TYPE($value = '') | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
$i = 1; | |||||
foreach (self::$errorCodes as $errorCode) { | |||||
if ($value === $errorCode) { | |||||
return $i; | |||||
} | |||||
++$i; | |||||
} | |||||
return self::NA(); | |||||
} | |||||
/** | |||||
* IS_BLANK | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_BLANK($value = null) | |||||
{ | |||||
if (!is_null($value)) { | |||||
$value = self::flattenSingleValue($value); | |||||
} | |||||
return is_null($value); | |||||
} | |||||
/** | |||||
* IS_ERR | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_ERR($value = '') | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
return self::IS_ERROR($value) && (!self::IS_NA($value)); | |||||
} | |||||
/** | |||||
* IS_ERROR | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_ERROR($value = '') | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
if (!is_string($value)) { | |||||
return false; | |||||
} | |||||
return in_array($value, array_values(self::$errorCodes)); | |||||
} | |||||
/** | |||||
* IS_NA | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_NA($value = '') | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
return ($value === self::NA()); | |||||
} | |||||
/** | |||||
* IS_EVEN | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_EVEN($value = null) | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
if ($value === null) { | |||||
return self::NAME(); | |||||
} elseif ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) { | |||||
return self::VALUE(); | |||||
} | |||||
return ($value % 2 == 0); | |||||
} | |||||
/** | |||||
* IS_ODD | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_ODD($value = null) | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
if ($value === null) { | |||||
return self::NAME(); | |||||
} elseif ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) { | |||||
return self::VALUE(); | |||||
} | |||||
return (abs($value) % 2 == 1); | |||||
} | |||||
/** | |||||
* IS_NUMBER | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_NUMBER($value = null) | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
if (is_string($value)) { | |||||
return false; | |||||
} | |||||
return is_numeric($value); | |||||
} | |||||
/** | |||||
* IS_LOGICAL | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_LOGICAL($value = null) | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
return is_bool($value); | |||||
} | |||||
/** | |||||
* IS_TEXT | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_TEXT($value = null) | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
return (is_string($value) && !self::IS_ERROR($value)); | |||||
} | |||||
/** | |||||
* IS_NONTEXT | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_NONTEXT($value = null) | |||||
{ | |||||
return !self::IS_TEXT($value); | |||||
} | |||||
/** | |||||
* VERSION | |||||
* | |||||
* @return string Version information | |||||
*/ | |||||
public static function VERSION() | |||||
{ | |||||
return 'PHPExcel ##VERSION##, ##DATE##'; | |||||
} | |||||
/** | |||||
* N | |||||
* | |||||
* Returns a value converted to a number | |||||
* | |||||
* @param value The value you want converted | |||||
* @return number N converts values listed in the following table | |||||
* If value is or refers to N returns | |||||
* A number That number | |||||
* A date The serial number of that date | |||||
* TRUE 1 | |||||
* FALSE 0 | |||||
* An error value The error value | |||||
* Anything else 0 | |||||
*/ | |||||
public static function N($value = null) | |||||
{ | |||||
while (is_array($value)) { | |||||
$value = array_shift($value); | |||||
} | |||||
switch (gettype($value)) { | |||||
case 'double': | |||||
case 'float': | |||||
case 'integer': | |||||
return $value; | |||||
case 'boolean': | |||||
return (integer) $value; | |||||
case 'string': | |||||
// Errors | |||||
if ((strlen($value) > 0) && ($value[0] == '#')) { | |||||
return $value; | |||||
} | |||||
break; | |||||
} | |||||
return 0; | |||||
} | |||||
/** | |||||
* TYPE | |||||
* | |||||
* Returns a number that identifies the type of a value | |||||
* | |||||
* @param value The value you want tested | |||||
* @return number N converts values listed in the following table | |||||
* If value is or refers to N returns | |||||
* A number 1 | |||||
* Text 2 | |||||
* Logical Value 4 | |||||
* An error value 16 | |||||
* Array or Matrix 64 | |||||
*/ | |||||
public static function TYPE($value = null) | |||||
{ | |||||
$value = self::flattenArrayIndexed($value); | |||||
if (is_array($value) && (count($value) > 1)) { | |||||
end($value); | |||||
$a = key($value); | |||||
// Range of cells is an error | |||||
if (self::isCellValue($a)) { | |||||
return 16; | |||||
// Test for Matrix | |||||
} elseif (self::isMatrixValue($a)) { | |||||
return 64; | |||||
} | |||||
} elseif (empty($value)) { | |||||
// Empty Cell | |||||
return 1; | |||||
} | |||||
$value = self::flattenSingleValue($value); | |||||
if (($value === null) || (is_float($value)) || (is_int($value))) { | |||||
return 1; | |||||
} elseif (is_bool($value)) { | |||||
return 4; | |||||
} elseif (is_array($value)) { | |||||
return 64; | |||||
} elseif (is_string($value)) { | |||||
// Errors | |||||
if ((strlen($value) > 0) && ($value[0] == '#')) { | |||||
return 16; | |||||
} | |||||
return 2; | |||||
} | |||||
return 0; | |||||
} | |||||
/** | |||||
* Convert a multi-dimensional array to a simple 1-dimensional array | |||||
* | |||||
* @param array $array Array to be flattened | |||||
* @return array Flattened array | |||||
*/ | |||||
public static function flattenArray($array) | |||||
{ | |||||
if (!is_array($array)) { | |||||
return (array) $array; | |||||
} | |||||
$arrayValues = array(); | |||||
foreach ($array as $value) { | |||||
if (is_array($value)) { | |||||
foreach ($value as $val) { | |||||
if (is_array($val)) { | |||||
foreach ($val as $v) { | |||||
$arrayValues[] = $v; | |||||
} | |||||
} else { | |||||
$arrayValues[] = $val; | |||||
} | |||||
} | |||||
} else { | |||||
$arrayValues[] = $value; | |||||
} | |||||
} | |||||
return $arrayValues; | |||||
} | |||||
/** | |||||
* Convert a multi-dimensional array to a simple 1-dimensional array, but retain an element of indexing | |||||
* | |||||
* @param array $array Array to be flattened | |||||
* @return array Flattened array | |||||
*/ | |||||
public static function flattenArrayIndexed($array) | |||||
{ | |||||
if (!is_array($array)) { | |||||
return (array) $array; | |||||
} | |||||
$arrayValues = array(); | |||||
foreach ($array as $k1 => $value) { | |||||
if (is_array($value)) { | |||||
foreach ($value as $k2 => $val) { | |||||
if (is_array($val)) { | |||||
foreach ($val as $k3 => $v) { | |||||
$arrayValues[$k1.'.'.$k2.'.'.$k3] = $v; | |||||
} | |||||
} else { | |||||
$arrayValues[$k1.'.'.$k2] = $val; | |||||
} | |||||
} | |||||
} else { | |||||
$arrayValues[$k1] = $value; | |||||
} | |||||
} | |||||
return $arrayValues; | |||||
} | |||||
/** | |||||
* Convert an array to a single scalar value by extracting the first element | |||||
* | |||||
* @param mixed $value Array or scalar value | |||||
* @return mixed | |||||
*/ | |||||
public static function flattenSingleValue($value = '') | |||||
{ | |||||
while (is_array($value)) { | |||||
$value = array_pop($value); | |||||
} | |||||
return $value; | |||||
} | |||||
} | |||||
// | |||||
// There are a few mathematical functions that aren't available on all versions of PHP for all platforms | |||||
// These functions aren't available in Windows implementations of PHP prior to version 5.3.0 | |||||
// So we test if they do exist for this version of PHP/operating platform; and if not we create them | |||||
// | |||||
if (!function_exists('acosh')) { | |||||
function acosh($x) | |||||
{ | |||||
return 2 * log(sqrt(($x + 1) / 2) + sqrt(($x - 1) / 2)); | |||||
} // function acosh() | |||||
} | |||||
if (!function_exists('asinh')) { | |||||
function asinh($x) | |||||
{ | |||||
return log($x + sqrt(1 + $x * $x)); | |||||
} // function asinh() | |||||
} | |||||
if (!function_exists('atanh')) { | |||||
function atanh($x) | |||||
{ | |||||
return (log(1 + $x) - log(1 - $x)) / 2; | |||||
} // function atanh() | |||||
} | |||||
// | |||||
// Strangely, PHP doesn't have a mb_str_replace multibyte function | |||||
// As we'll only ever use this function with UTF-8 characters, we can simply "hard-code" the character set | |||||
// | |||||
if ((!function_exists('mb_str_replace')) && | |||||
(function_exists('mb_substr')) && (function_exists('mb_strlen')) && (function_exists('mb_strpos'))) { | |||||
function mb_str_replace($search, $replace, $subject) | |||||
{ | |||||
if (is_array($subject)) { | |||||
$ret = array(); | |||||
foreach ($subject as $key => $val) { | |||||
$ret[$key] = mb_str_replace($search, $replace, $val); | |||||
} | |||||
return $ret; | |||||
} | |||||
foreach ((array) $search as $key => $s) { | |||||
if ($s == '' && $s !== 0) { | |||||
continue; | |||||
} | |||||
$r = !is_array($replace) ? $replace : (array_key_exists($key, $replace) ? $replace[$key] : ''); | |||||
$pos = mb_strpos($subject, $s, 0, 'UTF-8'); | |||||
while ($pos !== false) { | |||||
$subject = mb_substr($subject, 0, $pos, 'UTF-8') . $r . mb_substr($subject, $pos + mb_strlen($s, 'UTF-8'), 65535, 'UTF-8'); | |||||
$pos = mb_strpos($subject, $s, $pos + mb_strlen($r, 'UTF-8'), 'UTF-8'); | |||||
} | |||||
} | |||||
return $subject; | |||||
} | |||||
} |
@ -0,0 +1,760 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** MAX_VALUE */ | |||||
define('MAX_VALUE', 1.2e308); | |||||
/** 2 / PI */ | |||||
define('M_2DIVPI', 0.63661977236758134307553505349006); | |||||
/** MAX_ITERATIONS */ | |||||
define('MAX_ITERATIONS', 256); | |||||
/** PRECISION */ | |||||
define('PRECISION', 8.88E-016); | |||||
/** | |||||
* PHPExcel_Calculation_Functions | |||||
* | |||||
* 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_Calculation | |||||
* @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_Calculation_Functions | |||||
{ | |||||
/** constants */ | |||||
const COMPATIBILITY_EXCEL = 'Excel'; | |||||
const COMPATIBILITY_GNUMERIC = 'Gnumeric'; | |||||
const COMPATIBILITY_OPENOFFICE = 'OpenOfficeCalc'; | |||||
const RETURNDATE_PHP_NUMERIC = 'P'; | |||||
const RETURNDATE_PHP_OBJECT = 'O'; | |||||
const RETURNDATE_EXCEL = 'E'; | |||||
/** | |||||
* Compatibility mode to use for error checking and responses | |||||
* | |||||
* @access private | |||||
* @var string | |||||
*/ | |||||
protected static $compatibilityMode = self::COMPATIBILITY_EXCEL; | |||||
/** | |||||
* Data Type to use when returning date values | |||||
* | |||||
* @access private | |||||
* @var string | |||||
*/ | |||||
protected static $returnDateType = self::RETURNDATE_EXCEL; | |||||
/** | |||||
* List of error codes | |||||
* | |||||
* @access private | |||||
* @var array | |||||
*/ | |||||
protected static $errorCodes = array( | |||||
'null' => '#NULL!', | |||||
'divisionbyzero' => '#DIV/0!', | |||||
'value' => '#VALUE!', | |||||
'reference' => '#REF!', | |||||
'name' => '#NAME?', | |||||
'num' => '#NUM!', | |||||
'na' => '#N/A', | |||||
'gettingdata' => '#GETTING_DATA' | |||||
); | |||||
/** | |||||
* Set the Compatibility Mode | |||||
* | |||||
* @access public | |||||
* @category Function Configuration | |||||
* @param string $compatibilityMode Compatibility Mode | |||||
* Permitted values are: | |||||
* PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL 'Excel' | |||||
* PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC 'Gnumeric' | |||||
* PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' | |||||
* @return boolean (Success or Failure) | |||||
*/ | |||||
public static function setCompatibilityMode($compatibilityMode) | |||||
{ | |||||
if (($compatibilityMode == self::COMPATIBILITY_EXCEL) || | |||||
($compatibilityMode == self::COMPATIBILITY_GNUMERIC) || | |||||
($compatibilityMode == self::COMPATIBILITY_OPENOFFICE)) { | |||||
self::$compatibilityMode = $compatibilityMode; | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* Return the current Compatibility Mode | |||||
* | |||||
* @access public | |||||
* @category Function Configuration | |||||
* @return string Compatibility Mode | |||||
* Possible Return values are: | |||||
* PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL 'Excel' | |||||
* PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC 'Gnumeric' | |||||
* PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' | |||||
*/ | |||||
public static function getCompatibilityMode() | |||||
{ | |||||
return self::$compatibilityMode; | |||||
} | |||||
/** | |||||
* Set the Return Date Format used by functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object) | |||||
* | |||||
* @access public | |||||
* @category Function Configuration | |||||
* @param string $returnDateType Return Date Format | |||||
* Permitted values are: | |||||
* PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC 'P' | |||||
* PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT 'O' | |||||
* PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E' | |||||
* @return boolean Success or failure | |||||
*/ | |||||
public static function setReturnDateType($returnDateType) | |||||
{ | |||||
if (($returnDateType == self::RETURNDATE_PHP_NUMERIC) || | |||||
($returnDateType == self::RETURNDATE_PHP_OBJECT) || | |||||
($returnDateType == self::RETURNDATE_EXCEL)) { | |||||
self::$returnDateType = $returnDateType; | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* Return the current Return Date Format for functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object) | |||||
* | |||||
* @access public | |||||
* @category Function Configuration | |||||
* @return string Return Date Format | |||||
* Possible Return values are: | |||||
* PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC 'P' | |||||
* PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT 'O' | |||||
* PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E' | |||||
*/ | |||||
public static function getReturnDateType() | |||||
{ | |||||
return self::$returnDateType; | |||||
} | |||||
/** | |||||
* DUMMY | |||||
* | |||||
* @access public | |||||
* @category Error Returns | |||||
* @return string #Not Yet Implemented | |||||
*/ | |||||
public static function DUMMY() | |||||
{ | |||||
return '#Not Yet Implemented'; | |||||
} | |||||
/** | |||||
* DIV0 | |||||
* | |||||
* @access public | |||||
* @category Error Returns | |||||
* @return string #Not Yet Implemented | |||||
*/ | |||||
public static function DIV0() | |||||
{ | |||||
return self::$errorCodes['divisionbyzero']; | |||||
} | |||||
/** | |||||
* NA | |||||
* | |||||
* Excel Function: | |||||
* =NA() | |||||
* | |||||
* Returns the error value #N/A | |||||
* #N/A is the error value that means "no value is available." | |||||
* | |||||
* @access public | |||||
* @category Logical Functions | |||||
* @return string #N/A! | |||||
*/ | |||||
public static function NA() | |||||
{ | |||||
return self::$errorCodes['na']; | |||||
} | |||||
/** | |||||
* NaN | |||||
* | |||||
* Returns the error value #NUM! | |||||
* | |||||
* @access public | |||||
* @category Error Returns | |||||
* @return string #NUM! | |||||
*/ | |||||
public static function NaN() | |||||
{ | |||||
return self::$errorCodes['num']; | |||||
} | |||||
/** | |||||
* NAME | |||||
* | |||||
* Returns the error value #NAME? | |||||
* | |||||
* @access public | |||||
* @category Error Returns | |||||
* @return string #NAME? | |||||
*/ | |||||
public static function NAME() | |||||
{ | |||||
return self::$errorCodes['name']; | |||||
} | |||||
/** | |||||
* REF | |||||
* | |||||
* Returns the error value #REF! | |||||
* | |||||
* @access public | |||||
* @category Error Returns | |||||
* @return string #REF! | |||||
*/ | |||||
public static function REF() | |||||
{ | |||||
return self::$errorCodes['reference']; | |||||
} | |||||
/** | |||||
* NULL | |||||
* | |||||
* Returns the error value #NULL! | |||||
* | |||||
* @access public | |||||
* @category Error Returns | |||||
* @return string #NULL! | |||||
*/ | |||||
public static function NULL() | |||||
{ | |||||
return self::$errorCodes['null']; | |||||
} | |||||
/** | |||||
* VALUE | |||||
* | |||||
* Returns the error value #VALUE! | |||||
* | |||||
* @access public | |||||
* @category Error Returns | |||||
* @return string #VALUE! | |||||
*/ | |||||
public static function VALUE() | |||||
{ | |||||
return self::$errorCodes['value']; | |||||
} | |||||
public static function isMatrixValue($idx) | |||||
{ | |||||
return ((substr_count($idx, '.') <= 1) || (preg_match('/\.[A-Z]/', $idx) > 0)); | |||||
} | |||||
public static function isValue($idx) | |||||
{ | |||||
return (substr_count($idx, '.') == 0); | |||||
} | |||||
public static function isCellValue($idx) | |||||
{ | |||||
return (substr_count($idx, '.') > 1); | |||||
} | |||||
public static function ifCondition($condition) | |||||
{ | |||||
$condition = PHPExcel_Calculation_Functions::flattenSingleValue($condition); | |||||
if (!isset($condition{0})) { | |||||
$condition = '=""'; | |||||
} | |||||
if (!in_array($condition{0}, array('>', '<', '='))) { | |||||
if (!is_numeric($condition)) { | |||||
$condition = PHPExcel_Calculation::wrapResult(strtoupper($condition)); | |||||
} | |||||
return '=' . $condition; | |||||
} else { | |||||
preg_match('/([<>=]+)(.*)/', $condition, $matches); | |||||
list(, $operator, $operand) = $matches; | |||||
if (!is_numeric($operand)) { | |||||
$operand = str_replace('"', '""', $operand); | |||||
$operand = PHPExcel_Calculation::wrapResult(strtoupper($operand)); | |||||
} | |||||
return $operator.$operand; | |||||
} | |||||
} | |||||
/** | |||||
* ERROR_TYPE | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function ERROR_TYPE($value = '') | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
$i = 1; | |||||
foreach (self::$errorCodes as $errorCode) { | |||||
if ($value === $errorCode) { | |||||
return $i; | |||||
} | |||||
++$i; | |||||
} | |||||
return self::NA(); | |||||
} | |||||
/** | |||||
* IS_BLANK | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_BLANK($value = null) | |||||
{ | |||||
if (!is_null($value)) { | |||||
$value = self::flattenSingleValue($value); | |||||
} | |||||
return is_null($value); | |||||
} | |||||
/** | |||||
* IS_ERR | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_ERR($value = '') | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
return self::IS_ERROR($value) && (!self::IS_NA($value)); | |||||
} | |||||
/** | |||||
* IS_ERROR | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_ERROR($value = '') | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
if (!is_string($value)) { | |||||
return false; | |||||
} | |||||
return in_array($value, array_values(self::$errorCodes)); | |||||
} | |||||
/** | |||||
* IS_NA | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_NA($value = '') | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
return ($value === self::NA()); | |||||
} | |||||
/** | |||||
* IS_EVEN | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_EVEN($value = null) | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
if ($value === null) { | |||||
return self::NAME(); | |||||
} elseif ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) { | |||||
return self::VALUE(); | |||||
} | |||||
return ($value % 2 == 0); | |||||
} | |||||
/** | |||||
* IS_ODD | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_ODD($value = null) | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
if ($value === null) { | |||||
return self::NAME(); | |||||
} elseif ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) { | |||||
return self::VALUE(); | |||||
} | |||||
return (abs($value) % 2 == 1); | |||||
} | |||||
/** | |||||
* IS_NUMBER | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_NUMBER($value = null) | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
if (is_string($value)) { | |||||
return false; | |||||
} | |||||
return is_numeric($value); | |||||
} | |||||
/** | |||||
* IS_LOGICAL | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_LOGICAL($value = null) | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
return is_bool($value); | |||||
} | |||||
/** | |||||
* IS_TEXT | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_TEXT($value = null) | |||||
{ | |||||
$value = self::flattenSingleValue($value); | |||||
return (is_string($value) && !self::IS_ERROR($value)); | |||||
} | |||||
/** | |||||
* IS_NONTEXT | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function IS_NONTEXT($value = null) | |||||
{ | |||||
return !self::IS_TEXT($value); | |||||
} | |||||
/** | |||||
* VERSION | |||||
* | |||||
* @return string Version information | |||||
*/ | |||||
public static function VERSION() | |||||
{ | |||||
return 'PHPExcel ##VERSION##, ##DATE##'; | |||||
} | |||||
/** | |||||
* N | |||||
* | |||||
* Returns a value converted to a number | |||||
* | |||||
* @param value The value you want converted | |||||
* @return number N converts values listed in the following table | |||||
* If value is or refers to N returns | |||||
* A number That number | |||||
* A date The serial number of that date | |||||
* TRUE 1 | |||||
* FALSE 0 | |||||
* An error value The error value | |||||
* Anything else 0 | |||||
*/ | |||||
public static function N($value = null) | |||||
{ | |||||
while (is_array($value)) { | |||||
$value = array_shift($value); | |||||
} | |||||
switch (gettype($value)) { | |||||
case 'double': | |||||
case 'float': | |||||
case 'integer': | |||||
return $value; | |||||
case 'boolean': | |||||
return (integer) $value; | |||||
case 'string': | |||||
// Errors | |||||
if ((strlen($value) > 0) && ($value{0} == '#')) { | |||||
return $value; | |||||
} | |||||
break; | |||||
} | |||||
return 0; | |||||
} | |||||
/** | |||||
* TYPE | |||||
* | |||||
* Returns a number that identifies the type of a value | |||||
* | |||||
* @param value The value you want tested | |||||
* @return number N converts values listed in the following table | |||||
* If value is or refers to N returns | |||||
* A number 1 | |||||
* Text 2 | |||||
* Logical Value 4 | |||||
* An error value 16 | |||||
* Array or Matrix 64 | |||||
*/ | |||||
public static function TYPE($value = null) | |||||
{ | |||||
$value = self::flattenArrayIndexed($value); | |||||
if (is_array($value) && (count($value) > 1)) { | |||||
end($value); | |||||
$a = key($value); | |||||
// Range of cells is an error | |||||
if (self::isCellValue($a)) { | |||||
return 16; | |||||
// Test for Matrix | |||||
} elseif (self::isMatrixValue($a)) { | |||||
return 64; | |||||
} | |||||
} elseif (empty($value)) { | |||||
// Empty Cell | |||||
return 1; | |||||
} | |||||
$value = self::flattenSingleValue($value); | |||||
if (($value === null) || (is_float($value)) || (is_int($value))) { | |||||
return 1; | |||||
} elseif (is_bool($value)) { | |||||
return 4; | |||||
} elseif (is_array($value)) { | |||||
return 64; | |||||
} elseif (is_string($value)) { | |||||
// Errors | |||||
if ((strlen($value) > 0) && ($value{0} == '#')) { | |||||
return 16; | |||||
} | |||||
return 2; | |||||
} | |||||
return 0; | |||||
} | |||||
/** | |||||
* Convert a multi-dimensional array to a simple 1-dimensional array | |||||
* | |||||
* @param array $array Array to be flattened | |||||
* @return array Flattened array | |||||
*/ | |||||
public static function flattenArray($array) | |||||
{ | |||||
if (!is_array($array)) { | |||||
return (array) $array; | |||||
} | |||||
$arrayValues = array(); | |||||
foreach ($array as $value) { | |||||
if (is_array($value)) { | |||||
foreach ($value as $val) { | |||||
if (is_array($val)) { | |||||
foreach ($val as $v) { | |||||
$arrayValues[] = $v; | |||||
} | |||||
} else { | |||||
$arrayValues[] = $val; | |||||
} | |||||
} | |||||
} else { | |||||
$arrayValues[] = $value; | |||||
} | |||||
} | |||||
return $arrayValues; | |||||
} | |||||
/** | |||||
* Convert a multi-dimensional array to a simple 1-dimensional array, but retain an element of indexing | |||||
* | |||||
* @param array $array Array to be flattened | |||||
* @return array Flattened array | |||||
*/ | |||||
public static function flattenArrayIndexed($array) | |||||
{ | |||||
if (!is_array($array)) { | |||||
return (array) $array; | |||||
} | |||||
$arrayValues = array(); | |||||
foreach ($array as $k1 => $value) { | |||||
if (is_array($value)) { | |||||
foreach ($value as $k2 => $val) { | |||||
if (is_array($val)) { | |||||
foreach ($val as $k3 => $v) { | |||||
$arrayValues[$k1.'.'.$k2.'.'.$k3] = $v; | |||||
} | |||||
} else { | |||||
$arrayValues[$k1.'.'.$k2] = $val; | |||||
} | |||||
} | |||||
} else { | |||||
$arrayValues[$k1] = $value; | |||||
} | |||||
} | |||||
return $arrayValues; | |||||
} | |||||
/** | |||||
* Convert an array to a single scalar value by extracting the first element | |||||
* | |||||
* @param mixed $value Array or scalar value | |||||
* @return mixed | |||||
*/ | |||||
public static function flattenSingleValue($value = '') | |||||
{ | |||||
while (is_array($value)) { | |||||
$value = array_pop($value); | |||||
} | |||||
return $value; | |||||
} | |||||
} | |||||
// | |||||
// There are a few mathematical functions that aren't available on all versions of PHP for all platforms | |||||
// These functions aren't available in Windows implementations of PHP prior to version 5.3.0 | |||||
// So we test if they do exist for this version of PHP/operating platform; and if not we create them | |||||
// | |||||
if (!function_exists('acosh')) { | |||||
function acosh($x) | |||||
{ | |||||
return 2 * log(sqrt(($x + 1) / 2) + sqrt(($x - 1) / 2)); | |||||
} // function acosh() | |||||
} | |||||
if (!function_exists('asinh')) { | |||||
function asinh($x) | |||||
{ | |||||
return log($x + sqrt(1 + $x * $x)); | |||||
} // function asinh() | |||||
} | |||||
if (!function_exists('atanh')) { | |||||
function atanh($x) | |||||
{ | |||||
return (log(1 + $x) - log(1 - $x)) / 2; | |||||
} // function atanh() | |||||
} | |||||
// | |||||
// Strangely, PHP doesn't have a mb_str_replace multibyte function | |||||
// As we'll only ever use this function with UTF-8 characters, we can simply "hard-code" the character set | |||||
// | |||||
if ((!function_exists('mb_str_replace')) && | |||||
(function_exists('mb_substr')) && (function_exists('mb_strlen')) && (function_exists('mb_strpos'))) { | |||||
function mb_str_replace($search, $replace, $subject) | |||||
{ | |||||
if (is_array($subject)) { | |||||
$ret = array(); | |||||
foreach ($subject as $key => $val) { | |||||
$ret[$key] = mb_str_replace($search, $replace, $val); | |||||
} | |||||
return $ret; | |||||
} | |||||
foreach ((array) $search as $key => $s) { | |||||
if ($s == '' && $s !== 0) { | |||||
continue; | |||||
} | |||||
$r = !is_array($replace) ? $replace : (array_key_exists($key, $replace) ? $replace[$key] : ''); | |||||
$pos = mb_strpos($subject, $s, 0, 'UTF-8'); | |||||
while ($pos !== false) { | |||||
$subject = mb_substr($subject, 0, $pos, 'UTF-8') . $r . mb_substr($subject, $pos + mb_strlen($s, 'UTF-8'), 65535, 'UTF-8'); | |||||
$pos = mb_strpos($subject, $s, $pos + mb_strlen($r, 'UTF-8'), 'UTF-8'); | |||||
} | |||||
} | |||||
return $subject; | |||||
} | |||||
} |
@ -0,0 +1,285 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_Calculation_Logical | |||||
* | |||||
* 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_Calculation | |||||
* @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_Calculation_Logical | |||||
{ | |||||
/** | |||||
* TRUE | |||||
* | |||||
* Returns the boolean TRUE. | |||||
* | |||||
* Excel Function: | |||||
* =TRUE() | |||||
* | |||||
* @access public | |||||
* @category Logical Functions | |||||
* @return boolean True | |||||
*/ | |||||
public static function TRUE() | |||||
{ | |||||
return true; | |||||
} | |||||
/** | |||||
* FALSE | |||||
* | |||||
* Returns the boolean FALSE. | |||||
* | |||||
* Excel Function: | |||||
* =FALSE() | |||||
* | |||||
* @access public | |||||
* @category Logical Functions | |||||
* @return boolean False | |||||
*/ | |||||
public static function FALSE() | |||||
{ | |||||
return false; | |||||
} | |||||
/** | |||||
* LOGICAL_AND | |||||
* | |||||
* Returns boolean TRUE if all its arguments are TRUE; returns FALSE if one or more argument is FALSE. | |||||
* | |||||
* Excel Function: | |||||
* =AND(logical1[,logical2[, ...]]) | |||||
* | |||||
* The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays | |||||
* or references that contain logical values. | |||||
* | |||||
* Boolean arguments are treated as True or False as appropriate | |||||
* Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False | |||||
* If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds | |||||
* the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value | |||||
* | |||||
* @access public | |||||
* @category Logical Functions | |||||
* @param mixed $arg,... Data values | |||||
* @return boolean The logical AND of the arguments. | |||||
*/ | |||||
public static function LOGICAL_AND() | |||||
{ | |||||
// Return value | |||||
$returnValue = true; | |||||
// Loop through the arguments | |||||
$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); | |||||
$argCount = -1; | |||||
foreach ($aArgs as $argCount => $arg) { | |||||
// Is it a boolean value? | |||||
if (is_bool($arg)) { | |||||
$returnValue = $returnValue && $arg; | |||||
} elseif ((is_numeric($arg)) && (!is_string($arg))) { | |||||
$returnValue = $returnValue && ($arg != 0); | |||||
} elseif (is_string($arg)) { | |||||
$arg = strtoupper($arg); | |||||
if (($arg == 'TRUE') || ($arg == PHPExcel_Calculation::getTRUE())) { | |||||
$arg = true; | |||||
} elseif (($arg == 'FALSE') || ($arg == PHPExcel_Calculation::getFALSE())) { | |||||
$arg = false; | |||||
} else { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
$returnValue = $returnValue && ($arg != 0); | |||||
} | |||||
} | |||||
// Return | |||||
if ($argCount < 0) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
return $returnValue; | |||||
} | |||||
/** | |||||
* LOGICAL_OR | |||||
* | |||||
* Returns boolean TRUE if any argument is TRUE; returns FALSE if all arguments are FALSE. | |||||
* | |||||
* Excel Function: | |||||
* =OR(logical1[,logical2[, ...]]) | |||||
* | |||||
* The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays | |||||
* or references that contain logical values. | |||||
* | |||||
* Boolean arguments are treated as True or False as appropriate | |||||
* Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False | |||||
* If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds | |||||
* the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value | |||||
* | |||||
* @access public | |||||
* @category Logical Functions | |||||
* @param mixed $arg,... Data values | |||||
* @return boolean The logical OR of the arguments. | |||||
*/ | |||||
public static function LOGICAL_OR() | |||||
{ | |||||
// Return value | |||||
$returnValue = false; | |||||
// Loop through the arguments | |||||
$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); | |||||
$argCount = -1; | |||||
foreach ($aArgs as $argCount => $arg) { | |||||
// Is it a boolean value? | |||||
if (is_bool($arg)) { | |||||
$returnValue = $returnValue || $arg; | |||||
} elseif ((is_numeric($arg)) && (!is_string($arg))) { | |||||
$returnValue = $returnValue || ($arg != 0); | |||||
} elseif (is_string($arg)) { | |||||
$arg = strtoupper($arg); | |||||
if (($arg == 'TRUE') || ($arg == PHPExcel_Calculation::getTRUE())) { | |||||
$arg = true; | |||||
} elseif (($arg == 'FALSE') || ($arg == PHPExcel_Calculation::getFALSE())) { | |||||
$arg = false; | |||||
} else { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
$returnValue = $returnValue || ($arg != 0); | |||||
} | |||||
} | |||||
// Return | |||||
if ($argCount < 0) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
return $returnValue; | |||||
} | |||||
/** | |||||
* NOT | |||||
* | |||||
* Returns the boolean inverse of the argument. | |||||
* | |||||
* Excel Function: | |||||
* =NOT(logical) | |||||
* | |||||
* The argument must evaluate to a logical value such as TRUE or FALSE | |||||
* | |||||
* Boolean arguments are treated as True or False as appropriate | |||||
* Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False | |||||
* If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds | |||||
* the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value | |||||
* | |||||
* @access public | |||||
* @category Logical Functions | |||||
* @param mixed $logical A value or expression that can be evaluated to TRUE or FALSE | |||||
* @return boolean The boolean inverse of the argument. | |||||
*/ | |||||
public static function NOT($logical = false) | |||||
{ | |||||
$logical = PHPExcel_Calculation_Functions::flattenSingleValue($logical); | |||||
if (is_string($logical)) { | |||||
$logical = strtoupper($logical); | |||||
if (($logical == 'TRUE') || ($logical == PHPExcel_Calculation::getTRUE())) { | |||||
return false; | |||||
} elseif (($logical == 'FALSE') || ($logical == PHPExcel_Calculation::getFALSE())) { | |||||
return true; | |||||
} else { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
} | |||||
return !$logical; | |||||
} | |||||
/** | |||||
* STATEMENT_IF | |||||
* | |||||
* Returns one value if a condition you specify evaluates to TRUE and another value if it evaluates to FALSE. | |||||
* | |||||
* Excel Function: | |||||
* =IF(condition[,returnIfTrue[,returnIfFalse]]) | |||||
* | |||||
* Condition is any value or expression that can be evaluated to TRUE or FALSE. | |||||
* For example, A10=100 is a logical expression; if the value in cell A10 is equal to 100, | |||||
* the expression evaluates to TRUE. Otherwise, the expression evaluates to FALSE. | |||||
* This argument can use any comparison calculation operator. | |||||
* ReturnIfTrue is the value that is returned if condition evaluates to TRUE. | |||||
* For example, if this argument is the text string "Within budget" and the condition argument evaluates to TRUE, | |||||
* then the IF function returns the text "Within budget" | |||||
* If condition is TRUE and ReturnIfTrue is blank, this argument returns 0 (zero). To display the word TRUE, use | |||||
* the logical value TRUE for this argument. | |||||
* ReturnIfTrue can be another formula. | |||||
* ReturnIfFalse is the value that is returned if condition evaluates to FALSE. | |||||
* For example, if this argument is the text string "Over budget" and the condition argument evaluates to FALSE, | |||||
* then the IF function returns the text "Over budget". | |||||
* If condition is FALSE and ReturnIfFalse is omitted, then the logical value FALSE is returned. | |||||
* If condition is FALSE and ReturnIfFalse is blank, then the value 0 (zero) is returned. | |||||
* ReturnIfFalse can be another formula. | |||||
* | |||||
* @access public | |||||
* @category Logical Functions | |||||
* @param mixed $condition Condition to evaluate | |||||
* @param mixed $returnIfTrue Value to return when condition is true | |||||
* @param mixed $returnIfFalse Optional value to return when condition is false | |||||
* @return mixed The value of returnIfTrue or returnIfFalse determined by condition | |||||
*/ | |||||
public static function STATEMENT_IF($condition = true, $returnIfTrue = 0, $returnIfFalse = false) | |||||
{ | |||||
$condition = (is_null($condition)) ? true : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($condition); | |||||
$returnIfTrue = (is_null($returnIfTrue)) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($returnIfTrue); | |||||
$returnIfFalse = (is_null($returnIfFalse)) ? false : PHPExcel_Calculation_Functions::flattenSingleValue($returnIfFalse); | |||||
return ($condition) ? $returnIfTrue : $returnIfFalse; | |||||
} | |||||
/** | |||||
* IFERROR | |||||
* | |||||
* Excel Function: | |||||
* =IFERROR(testValue,errorpart) | |||||
* | |||||
* @access public | |||||
* @category Logical Functions | |||||
* @param mixed $testValue Value to check, is also the value returned when no error | |||||
* @param mixed $errorpart Value to return when testValue is an error condition | |||||
* @return mixed The value of errorpart or testValue determined by error condition | |||||
*/ | |||||
public static function IFERROR($testValue = '', $errorpart = '') | |||||
{ | |||||
$testValue = (is_null($testValue)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($testValue); | |||||
$errorpart = (is_null($errorpart)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($errorpart); | |||||
return self::STATEMENT_IF(PHPExcel_Calculation_Functions::IS_ERROR($testValue), $errorpart, $testValue); | |||||
} | |||||
} |
@ -0,0 +1,879 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_Calculation_LookupRef | |||||
* | |||||
* 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_Calculation | |||||
* @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_Calculation_LookupRef | |||||
{ | |||||
/** | |||||
* CELL_ADDRESS | |||||
* | |||||
* Creates a cell address as text, given specified row and column numbers. | |||||
* | |||||
* Excel Function: | |||||
* =ADDRESS(row, column, [relativity], [referenceStyle], [sheetText]) | |||||
* | |||||
* @param row Row number to use in the cell reference | |||||
* @param column Column number to use in the cell reference | |||||
* @param relativity Flag indicating the type of reference to return | |||||
* 1 or omitted Absolute | |||||
* 2 Absolute row; relative column | |||||
* 3 Relative row; absolute column | |||||
* 4 Relative | |||||
* @param referenceStyle A logical value that specifies the A1 or R1C1 reference style. | |||||
* TRUE or omitted CELL_ADDRESS returns an A1-style reference | |||||
* FALSE CELL_ADDRESS returns an R1C1-style reference | |||||
* @param sheetText Optional Name of worksheet to use | |||||
* @return string | |||||
*/ | |||||
public static function CELL_ADDRESS($row, $column, $relativity = 1, $referenceStyle = true, $sheetText = '') | |||||
{ | |||||
$row = PHPExcel_Calculation_Functions::flattenSingleValue($row); | |||||
$column = PHPExcel_Calculation_Functions::flattenSingleValue($column); | |||||
$relativity = PHPExcel_Calculation_Functions::flattenSingleValue($relativity); | |||||
$sheetText = PHPExcel_Calculation_Functions::flattenSingleValue($sheetText); | |||||
if (($row < 1) || ($column < 1)) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
if ($sheetText > '') { | |||||
if (strpos($sheetText, ' ') !== false) { | |||||
$sheetText = "'".$sheetText."'"; | |||||
} | |||||
$sheetText .='!'; | |||||
} | |||||
if ((!is_bool($referenceStyle)) || $referenceStyle) { | |||||
$rowRelative = $columnRelative = '$'; | |||||
$column = PHPExcel_Cell::stringFromColumnIndex($column-1); | |||||
if (($relativity == 2) || ($relativity == 4)) { | |||||
$columnRelative = ''; | |||||
} | |||||
if (($relativity == 3) || ($relativity == 4)) { | |||||
$rowRelative = ''; | |||||
} | |||||
return $sheetText.$columnRelative.$column.$rowRelative.$row; | |||||
} else { | |||||
if (($relativity == 2) || ($relativity == 4)) { | |||||
$column = '['.$column.']'; | |||||
} | |||||
if (($relativity == 3) || ($relativity == 4)) { | |||||
$row = '['.$row.']'; | |||||
} | |||||
return $sheetText.'R'.$row.'C'.$column; | |||||
} | |||||
} | |||||
/** | |||||
* COLUMN | |||||
* | |||||
* Returns the column number of the given cell reference | |||||
* If the cell reference is a range of cells, COLUMN returns the column numbers of each column in the reference as a horizontal array. | |||||
* If cell reference is omitted, and the function is being called through the calculation engine, then it is assumed to be the | |||||
* reference of the cell in which the COLUMN function appears; otherwise this function returns 0. | |||||
* | |||||
* Excel Function: | |||||
* =COLUMN([cellAddress]) | |||||
* | |||||
* @param cellAddress A reference to a range of cells for which you want the column numbers | |||||
* @return integer or array of integer | |||||
*/ | |||||
public static function COLUMN($cellAddress = null) | |||||
{ | |||||
if (is_null($cellAddress) || trim($cellAddress) === '') { | |||||
return 0; | |||||
} | |||||
if (is_array($cellAddress)) { | |||||
foreach ($cellAddress as $columnKey => $value) { | |||||
$columnKey = preg_replace('/[^a-z]/i', '', $columnKey); | |||||
return (integer) PHPExcel_Cell::columnIndexFromString($columnKey); | |||||
} | |||||
} else { | |||||
if (strpos($cellAddress, '!') !== false) { | |||||
list($sheet, $cellAddress) = explode('!', $cellAddress); | |||||
} | |||||
if (strpos($cellAddress, ':') !== false) { | |||||
list($startAddress, $endAddress) = explode(':', $cellAddress); | |||||
$startAddress = preg_replace('/[^a-z]/i', '', $startAddress); | |||||
$endAddress = preg_replace('/[^a-z]/i', '', $endAddress); | |||||
$returnValue = array(); | |||||
do { | |||||
$returnValue[] = (integer) PHPExcel_Cell::columnIndexFromString($startAddress); | |||||
} while ($startAddress++ != $endAddress); | |||||
return $returnValue; | |||||
} else { | |||||
$cellAddress = preg_replace('/[^a-z]/i', '', $cellAddress); | |||||
return (integer) PHPExcel_Cell::columnIndexFromString($cellAddress); | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* COLUMNS | |||||
* | |||||
* Returns the number of columns in an array or reference. | |||||
* | |||||
* Excel Function: | |||||
* =COLUMNS(cellAddress) | |||||
* | |||||
* @param cellAddress An array or array formula, or a reference to a range of cells for which you want the number of columns | |||||
* @return integer The number of columns in cellAddress | |||||
*/ | |||||
public static function COLUMNS($cellAddress = null) | |||||
{ | |||||
if (is_null($cellAddress) || $cellAddress === '') { | |||||
return 1; | |||||
} elseif (!is_array($cellAddress)) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
reset($cellAddress); | |||||
$isMatrix = (is_numeric(key($cellAddress))); | |||||
list($columns, $rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress); | |||||
if ($isMatrix) { | |||||
return $rows; | |||||
} else { | |||||
return $columns; | |||||
} | |||||
} | |||||
/** | |||||
* ROW | |||||
* | |||||
* Returns the row number of the given cell reference | |||||
* If the cell reference is a range of cells, ROW returns the row numbers of each row in the reference as a vertical array. | |||||
* If cell reference is omitted, and the function is being called through the calculation engine, then it is assumed to be the | |||||
* reference of the cell in which the ROW function appears; otherwise this function returns 0. | |||||
* | |||||
* Excel Function: | |||||
* =ROW([cellAddress]) | |||||
* | |||||
* @param cellAddress A reference to a range of cells for which you want the row numbers | |||||
* @return integer or array of integer | |||||
*/ | |||||
public static function ROW($cellAddress = null) | |||||
{ | |||||
if (is_null($cellAddress) || trim($cellAddress) === '') { | |||||
return 0; | |||||
} | |||||
if (is_array($cellAddress)) { | |||||
foreach ($cellAddress as $columnKey => $rowValue) { | |||||
foreach ($rowValue as $rowKey => $cellValue) { | |||||
return (integer) preg_replace('/[^0-9]/i', '', $rowKey); | |||||
} | |||||
} | |||||
} else { | |||||
if (strpos($cellAddress, '!') !== false) { | |||||
list($sheet, $cellAddress) = explode('!', $cellAddress); | |||||
} | |||||
if (strpos($cellAddress, ':') !== false) { | |||||
list($startAddress, $endAddress) = explode(':', $cellAddress); | |||||
$startAddress = preg_replace('/[^0-9]/', '', $startAddress); | |||||
$endAddress = preg_replace('/[^0-9]/', '', $endAddress); | |||||
$returnValue = array(); | |||||
do { | |||||
$returnValue[][] = (integer) $startAddress; | |||||
} while ($startAddress++ != $endAddress); | |||||
return $returnValue; | |||||
} else { | |||||
list($cellAddress) = explode(':', $cellAddress); | |||||
return (integer) preg_replace('/[^0-9]/', '', $cellAddress); | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* ROWS | |||||
* | |||||
* Returns the number of rows in an array or reference. | |||||
* | |||||
* Excel Function: | |||||
* =ROWS(cellAddress) | |||||
* | |||||
* @param cellAddress An array or array formula, or a reference to a range of cells for which you want the number of rows | |||||
* @return integer The number of rows in cellAddress | |||||
*/ | |||||
public static function ROWS($cellAddress = null) | |||||
{ | |||||
if (is_null($cellAddress) || $cellAddress === '') { | |||||
return 1; | |||||
} elseif (!is_array($cellAddress)) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
reset($cellAddress); | |||||
$isMatrix = (is_numeric(key($cellAddress))); | |||||
list($columns, $rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress); | |||||
if ($isMatrix) { | |||||
return $columns; | |||||
} else { | |||||
return $rows; | |||||
} | |||||
} | |||||
/** | |||||
* HYPERLINK | |||||
* | |||||
* Excel Function: | |||||
* =HYPERLINK(linkURL,displayName) | |||||
* | |||||
* @access public | |||||
* @category Logical Functions | |||||
* @param string $linkURL Value to check, is also the value returned when no error | |||||
* @param string $displayName Value to return when testValue is an error condition | |||||
* @param PHPExcel_Cell $pCell The cell to set the hyperlink in | |||||
* @return mixed The value of $displayName (or $linkURL if $displayName was blank) | |||||
*/ | |||||
public static function HYPERLINK($linkURL = '', $displayName = null, PHPExcel_Cell $pCell = null) | |||||
{ | |||||
$args = func_get_args(); | |||||
$pCell = array_pop($args); | |||||
$linkURL = (is_null($linkURL)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($linkURL); | |||||
$displayName = (is_null($displayName)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($displayName); | |||||
if ((!is_object($pCell)) || (trim($linkURL) == '')) { | |||||
return PHPExcel_Calculation_Functions::REF(); | |||||
} | |||||
if ((is_object($displayName)) || trim($displayName) == '') { | |||||
$displayName = $linkURL; | |||||
} | |||||
$pCell->getHyperlink()->setUrl($linkURL); | |||||
$pCell->getHyperlink()->setTooltip($displayName); | |||||
return $displayName; | |||||
} | |||||
/** | |||||
* INDIRECT | |||||
* | |||||
* Returns the reference specified by a text string. | |||||
* References are immediately evaluated to display their contents. | |||||
* | |||||
* Excel Function: | |||||
* =INDIRECT(cellAddress) | |||||
* | |||||
* NOTE - INDIRECT() does not yet support the optional a1 parameter introduced in Excel 2010 | |||||
* | |||||
* @param cellAddress $cellAddress The cell address of the current cell (containing this formula) | |||||
* @param PHPExcel_Cell $pCell The current cell (containing this formula) | |||||
* @return mixed The cells referenced by cellAddress | |||||
* | |||||
* @todo Support for the optional a1 parameter introduced in Excel 2010 | |||||
* | |||||
*/ | |||||
public static function INDIRECT($cellAddress = null, PHPExcel_Cell $pCell = null) | |||||
{ | |||||
$cellAddress = PHPExcel_Calculation_Functions::flattenSingleValue($cellAddress); | |||||
if (is_null($cellAddress) || $cellAddress === '') { | |||||
return PHPExcel_Calculation_Functions::REF(); | |||||
} | |||||
$cellAddress1 = $cellAddress; | |||||
$cellAddress2 = null; | |||||
if (strpos($cellAddress, ':') !== false) { | |||||
list($cellAddress1, $cellAddress2) = explode(':', $cellAddress); | |||||
} | |||||
if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $cellAddress1, $matches)) || | |||||
((!is_null($cellAddress2)) && (!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $cellAddress2, $matches)))) { | |||||
if (!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $cellAddress1, $matches)) { | |||||
return PHPExcel_Calculation_Functions::REF(); | |||||
} | |||||
if (strpos($cellAddress, '!') !== false) { | |||||
list($sheetName, $cellAddress) = explode('!', $cellAddress); | |||||
$sheetName = trim($sheetName, "'"); | |||||
$pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); | |||||
} else { | |||||
$pSheet = $pCell->getWorksheet(); | |||||
} | |||||
return PHPExcel_Calculation::getInstance()->extractNamedRange($cellAddress, $pSheet, false); | |||||
} | |||||
if (strpos($cellAddress, '!') !== false) { | |||||
list($sheetName, $cellAddress) = explode('!', $cellAddress); | |||||
$sheetName = trim($sheetName, "'"); | |||||
$pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); | |||||
} else { | |||||
$pSheet = $pCell->getWorksheet(); | |||||
} | |||||
return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, false); | |||||
} | |||||
/** | |||||
* OFFSET | |||||
* | |||||
* Returns a reference to a range that is a specified number of rows and columns from a cell or range of cells. | |||||
* The reference that is returned can be a single cell or a range of cells. You can specify the number of rows and | |||||
* the number of columns to be returned. | |||||
* | |||||
* Excel Function: | |||||
* =OFFSET(cellAddress, rows, cols, [height], [width]) | |||||
* | |||||
* @param cellAddress The reference from which you want to base the offset. Reference must refer to a cell or | |||||
* range of adjacent cells; otherwise, OFFSET returns the #VALUE! error value. | |||||
* @param rows The number of rows, up or down, that you want the upper-left cell to refer to. | |||||
* Using 5 as the rows argument specifies that the upper-left cell in the reference is | |||||
* five rows below reference. Rows can be positive (which means below the starting reference) | |||||
* or negative (which means above the starting reference). | |||||
* @param cols The number of columns, to the left or right, that you want the upper-left cell of the result | |||||
* to refer to. Using 5 as the cols argument specifies that the upper-left cell in the | |||||
* reference is five columns to the right of reference. Cols can be positive (which means | |||||
* to the right of the starting reference) or negative (which means to the left of the | |||||
* starting reference). | |||||
* @param height The height, in number of rows, that you want the returned reference to be. Height must be a positive number. | |||||
* @param width The width, in number of columns, that you want the returned reference to be. Width must be a positive number. | |||||
* @return string A reference to a cell or range of cells | |||||
*/ | |||||
public static function OFFSET($cellAddress = null, $rows = 0, $columns = 0, $height = null, $width = null) | |||||
{ | |||||
$rows = PHPExcel_Calculation_Functions::flattenSingleValue($rows); | |||||
$columns = PHPExcel_Calculation_Functions::flattenSingleValue($columns); | |||||
$height = PHPExcel_Calculation_Functions::flattenSingleValue($height); | |||||
$width = PHPExcel_Calculation_Functions::flattenSingleValue($width); | |||||
if ($cellAddress == null) { | |||||
return 0; | |||||
} | |||||
$args = func_get_args(); | |||||
$pCell = array_pop($args); | |||||
if (!is_object($pCell)) { | |||||
return PHPExcel_Calculation_Functions::REF(); | |||||
} | |||||
$sheetName = null; | |||||
if (strpos($cellAddress, "!")) { | |||||
list($sheetName, $cellAddress) = explode("!", $cellAddress); | |||||
$sheetName = trim($sheetName, "'"); | |||||
} | |||||
if (strpos($cellAddress, ":")) { | |||||
list($startCell, $endCell) = explode(":", $cellAddress); | |||||
} else { | |||||
$startCell = $endCell = $cellAddress; | |||||
} | |||||
list($startCellColumn, $startCellRow) = PHPExcel_Cell::coordinateFromString($startCell); | |||||
list($endCellColumn, $endCellRow) = PHPExcel_Cell::coordinateFromString($endCell); | |||||
$startCellRow += $rows; | |||||
$startCellColumn = PHPExcel_Cell::columnIndexFromString($startCellColumn) - 1; | |||||
$startCellColumn += $columns; | |||||
if (($startCellRow <= 0) || ($startCellColumn < 0)) { | |||||
return PHPExcel_Calculation_Functions::REF(); | |||||
} | |||||
$endCellColumn = PHPExcel_Cell::columnIndexFromString($endCellColumn) - 1; | |||||
if (($width != null) && (!is_object($width))) { | |||||
$endCellColumn = $startCellColumn + $width - 1; | |||||
} else { | |||||
$endCellColumn += $columns; | |||||
} | |||||
$startCellColumn = PHPExcel_Cell::stringFromColumnIndex($startCellColumn); | |||||
if (($height != null) && (!is_object($height))) { | |||||
$endCellRow = $startCellRow + $height - 1; | |||||
} else { | |||||
$endCellRow += $rows; | |||||
} | |||||
if (($endCellRow <= 0) || ($endCellColumn < 0)) { | |||||
return PHPExcel_Calculation_Functions::REF(); | |||||
} | |||||
$endCellColumn = PHPExcel_Cell::stringFromColumnIndex($endCellColumn); | |||||
$cellAddress = $startCellColumn.$startCellRow; | |||||
if (($startCellColumn != $endCellColumn) || ($startCellRow != $endCellRow)) { | |||||
$cellAddress .= ':'.$endCellColumn.$endCellRow; | |||||
} | |||||
if ($sheetName !== null) { | |||||
$pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); | |||||
} else { | |||||
$pSheet = $pCell->getWorksheet(); | |||||
} | |||||
return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, false); | |||||
} | |||||
/** | |||||
* CHOOSE | |||||
* | |||||
* Uses lookup_value to return a value from the list of value arguments. | |||||
* Use CHOOSE to select one of up to 254 values based on the lookup_value. | |||||
* | |||||
* Excel Function: | |||||
* =CHOOSE(index_num, value1, [value2], ...) | |||||
* | |||||
* @param index_num Specifies which value argument is selected. | |||||
* Index_num must be a number between 1 and 254, or a formula or reference to a cell containing a number | |||||
* between 1 and 254. | |||||
* @param value1... Value1 is required, subsequent values are optional. | |||||
* Between 1 to 254 value arguments from which CHOOSE selects a value or an action to perform based on | |||||
* index_num. The arguments can be numbers, cell references, defined names, formulas, functions, or | |||||
* text. | |||||
* @return mixed The selected value | |||||
*/ | |||||
public static function CHOOSE() | |||||
{ | |||||
$chooseArgs = func_get_args(); | |||||
$chosenEntry = PHPExcel_Calculation_Functions::flattenArray(array_shift($chooseArgs)); | |||||
$entryCount = count($chooseArgs) - 1; | |||||
if (is_array($chosenEntry)) { | |||||
$chosenEntry = array_shift($chosenEntry); | |||||
} | |||||
if ((is_numeric($chosenEntry)) && (!is_bool($chosenEntry))) { | |||||
--$chosenEntry; | |||||
} else { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
$chosenEntry = floor($chosenEntry); | |||||
if (($chosenEntry < 0) || ($chosenEntry > $entryCount)) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
if (is_array($chooseArgs[$chosenEntry])) { | |||||
return PHPExcel_Calculation_Functions::flattenArray($chooseArgs[$chosenEntry]); | |||||
} else { | |||||
return $chooseArgs[$chosenEntry]; | |||||
} | |||||
} | |||||
/** | |||||
* MATCH | |||||
* | |||||
* The MATCH function searches for a specified item in a range of cells | |||||
* | |||||
* Excel Function: | |||||
* =MATCH(lookup_value, lookup_array, [match_type]) | |||||
* | |||||
* @param lookup_value The value that you want to match in lookup_array | |||||
* @param lookup_array The range of cells being searched | |||||
* @param match_type The number -1, 0, or 1. -1 means above, 0 means exact match, 1 means below. If match_type is 1 or -1, the list has to be ordered. | |||||
* @return integer The relative position of the found item | |||||
*/ | |||||
public static function MATCH($lookup_value, $lookup_array, $match_type = 1) | |||||
{ | |||||
$lookup_array = PHPExcel_Calculation_Functions::flattenArray($lookup_array); | |||||
$lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); | |||||
$match_type = (is_null($match_type)) ? 1 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($match_type); | |||||
// MATCH is not case sensitive | |||||
$lookup_value = strtolower($lookup_value); | |||||
// lookup_value type has to be number, text, or logical values | |||||
if ((!is_numeric($lookup_value)) && (!is_string($lookup_value)) && (!is_bool($lookup_value))) { | |||||
return PHPExcel_Calculation_Functions::NA(); | |||||
} | |||||
// match_type is 0, 1 or -1 | |||||
if (($match_type !== 0) && ($match_type !== -1) && ($match_type !== 1)) { | |||||
return PHPExcel_Calculation_Functions::NA(); | |||||
} | |||||
// lookup_array should not be empty | |||||
$lookupArraySize = count($lookup_array); | |||||
if ($lookupArraySize <= 0) { | |||||
return PHPExcel_Calculation_Functions::NA(); | |||||
} | |||||
// lookup_array should contain only number, text, or logical values, or empty (null) cells | |||||
foreach ($lookup_array as $i => $lookupArrayValue) { | |||||
// check the type of the value | |||||
if ((!is_numeric($lookupArrayValue)) && (!is_string($lookupArrayValue)) && | |||||
(!is_bool($lookupArrayValue)) && (!is_null($lookupArrayValue))) { | |||||
return PHPExcel_Calculation_Functions::NA(); | |||||
} | |||||
// convert strings to lowercase for case-insensitive testing | |||||
if (is_string($lookupArrayValue)) { | |||||
$lookup_array[$i] = strtolower($lookupArrayValue); | |||||
} | |||||
if ((is_null($lookupArrayValue)) && (($match_type == 1) || ($match_type == -1))) { | |||||
$lookup_array = array_slice($lookup_array, 0, $i-1); | |||||
} | |||||
} | |||||
// if match_type is 1 or -1, the list has to be ordered | |||||
if ($match_type == 1) { | |||||
asort($lookup_array); | |||||
$keySet = array_keys($lookup_array); | |||||
} elseif ($match_type == -1) { | |||||
arsort($lookup_array); | |||||
$keySet = array_keys($lookup_array); | |||||
} | |||||
// ** | |||||
// find the match | |||||
// ** | |||||
foreach ($lookup_array as $i => $lookupArrayValue) { | |||||
if (($match_type == 0) && ($lookupArrayValue == $lookup_value)) { | |||||
// exact match | |||||
return ++$i; | |||||
} elseif (($match_type == -1) && ($lookupArrayValue <= $lookup_value)) { | |||||
$i = array_search($i, $keySet); | |||||
// if match_type is -1 <=> find the smallest value that is greater than or equal to lookup_value | |||||
if ($i < 1) { | |||||
// 1st cell was already smaller than the lookup_value | |||||
break; | |||||
} else { | |||||
// the previous cell was the match | |||||
return $keySet[$i-1]+1; | |||||
} | |||||
} elseif (($match_type == 1) && ($lookupArrayValue >= $lookup_value)) { | |||||
$i = array_search($i, $keySet); | |||||
// if match_type is 1 <=> find the largest value that is less than or equal to lookup_value | |||||
if ($i < 1) { | |||||
// 1st cell was already bigger than the lookup_value | |||||
break; | |||||
} else { | |||||
// the previous cell was the match | |||||
return $keySet[$i-1]+1; | |||||
} | |||||
} | |||||
} | |||||
// unsuccessful in finding a match, return #N/A error value | |||||
return PHPExcel_Calculation_Functions::NA(); | |||||
} | |||||
/** | |||||
* INDEX | |||||
* | |||||
* Uses an index to choose a value from a reference or array | |||||
* | |||||
* Excel Function: | |||||
* =INDEX(range_array, row_num, [column_num]) | |||||
* | |||||
* @param range_array A range of cells or an array constant | |||||
* @param row_num The row in array from which to return a value. If row_num is omitted, column_num is required. | |||||
* @param column_num The column in array from which to return a value. If column_num is omitted, row_num is required. | |||||
* @return mixed the value of a specified cell or array of cells | |||||
*/ | |||||
public static function INDEX($arrayValues, $rowNum = 0, $columnNum = 0) | |||||
{ | |||||
if (($rowNum < 0) || ($columnNum < 0)) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
if (!is_array($arrayValues)) { | |||||
return PHPExcel_Calculation_Functions::REF(); | |||||
} | |||||
$rowKeys = array_keys($arrayValues); | |||||
$columnKeys = @array_keys($arrayValues[$rowKeys[0]]); | |||||
if ($columnNum > count($columnKeys)) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} elseif ($columnNum == 0) { | |||||
if ($rowNum == 0) { | |||||
return $arrayValues; | |||||
} | |||||
$rowNum = $rowKeys[--$rowNum]; | |||||
$returnArray = array(); | |||||
foreach ($arrayValues as $arrayColumn) { | |||||
if (is_array($arrayColumn)) { | |||||
if (isset($arrayColumn[$rowNum])) { | |||||
$returnArray[] = $arrayColumn[$rowNum]; | |||||
} else { | |||||
return $arrayValues[$rowNum]; | |||||
} | |||||
} else { | |||||
return $arrayValues[$rowNum]; | |||||
} | |||||
} | |||||
return $returnArray; | |||||
} | |||||
$columnNum = $columnKeys[--$columnNum]; | |||||
if ($rowNum > count($rowKeys)) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} elseif ($rowNum == 0) { | |||||
return $arrayValues[$columnNum]; | |||||
} | |||||
$rowNum = $rowKeys[--$rowNum]; | |||||
return $arrayValues[$rowNum][$columnNum]; | |||||
} | |||||
/** | |||||
* TRANSPOSE | |||||
* | |||||
* @param array $matrixData A matrix of values | |||||
* @return array | |||||
* | |||||
* Unlike the Excel TRANSPOSE function, which will only work on a single row or column, this function will transpose a full matrix. | |||||
*/ | |||||
public static function TRANSPOSE($matrixData) | |||||
{ | |||||
$returnMatrix = array(); | |||||
if (!is_array($matrixData)) { | |||||
$matrixData = array(array($matrixData)); | |||||
} | |||||
$column = 0; | |||||
foreach ($matrixData as $matrixRow) { | |||||
$row = 0; | |||||
foreach ($matrixRow as $matrixCell) { | |||||
$returnMatrix[$row][$column] = $matrixCell; | |||||
++$row; | |||||
} | |||||
++$column; | |||||
} | |||||
return $returnMatrix; | |||||
} | |||||
private static function vlookupSort($a, $b) | |||||
{ | |||||
reset($a); | |||||
$firstColumn = key($a); | |||||
if (($aLower = strtolower($a[$firstColumn])) == ($bLower = strtolower($b[$firstColumn]))) { | |||||
return 0; | |||||
} | |||||
return ($aLower < $bLower) ? -1 : 1; | |||||
} | |||||
/** | |||||
* VLOOKUP | |||||
* The VLOOKUP function searches for value in the left-most column of lookup_array and returns the value in the same row based on the index_number. | |||||
* @param lookup_value The value that you want to match in lookup_array | |||||
* @param lookup_array The range of cells being searched | |||||
* @param index_number The column number in table_array from which the matching value must be returned. The first column is 1. | |||||
* @param not_exact_match Determines if you are looking for an exact match based on lookup_value. | |||||
* @return mixed The value of the found cell | |||||
*/ | |||||
public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match = true) | |||||
{ | |||||
$lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); | |||||
$index_number = PHPExcel_Calculation_Functions::flattenSingleValue($index_number); | |||||
$not_exact_match = PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match); | |||||
// index_number must be greater than or equal to 1 | |||||
if ($index_number < 1) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
// index_number must be less than or equal to the number of columns in lookup_array | |||||
if ((!is_array($lookup_array)) || (empty($lookup_array))) { | |||||
return PHPExcel_Calculation_Functions::REF(); | |||||
} else { | |||||
$f = array_keys($lookup_array); | |||||
$firstRow = array_pop($f); | |||||
if ((!is_array($lookup_array[$firstRow])) || ($index_number > count($lookup_array[$firstRow]))) { | |||||
return PHPExcel_Calculation_Functions::REF(); | |||||
} else { | |||||
$columnKeys = array_keys($lookup_array[$firstRow]); | |||||
$returnColumn = $columnKeys[--$index_number]; | |||||
$firstColumn = array_shift($columnKeys); | |||||
} | |||||
} | |||||
if (!$not_exact_match) { | |||||
uasort($lookup_array, array('self', 'vlookupSort')); | |||||
} | |||||
$rowNumber = $rowValue = false; | |||||
foreach ($lookup_array as $rowKey => $rowData) { | |||||
if ((is_numeric($lookup_value) && is_numeric($rowData[$firstColumn]) && ($rowData[$firstColumn] > $lookup_value)) || | |||||
(!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]) && (strtolower($rowData[$firstColumn]) > strtolower($lookup_value)))) { | |||||
break; | |||||
} | |||||
$rowNumber = $rowKey; | |||||
$rowValue = $rowData[$firstColumn]; | |||||
} | |||||
if ($rowNumber !== false) { | |||||
if ((!$not_exact_match) && ($rowValue != $lookup_value)) { | |||||
// if an exact match is required, we have what we need to return an appropriate response | |||||
return PHPExcel_Calculation_Functions::NA(); | |||||
} else { | |||||
// otherwise return the appropriate value | |||||
return $lookup_array[$rowNumber][$returnColumn]; | |||||
} | |||||
} | |||||
return PHPExcel_Calculation_Functions::NA(); | |||||
} | |||||
/** | |||||
* HLOOKUP | |||||
* The HLOOKUP function searches for value in the top-most row of lookup_array and returns the value in the same column based on the index_number. | |||||
* @param lookup_value The value that you want to match in lookup_array | |||||
* @param lookup_array The range of cells being searched | |||||
* @param index_number The row number in table_array from which the matching value must be returned. The first row is 1. | |||||
* @param not_exact_match Determines if you are looking for an exact match based on lookup_value. | |||||
* @return mixed The value of the found cell | |||||
*/ | |||||
public static function HLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match = true) | |||||
{ | |||||
$lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); | |||||
$index_number = PHPExcel_Calculation_Functions::flattenSingleValue($index_number); | |||||
$not_exact_match = PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match); | |||||
// index_number must be greater than or equal to 1 | |||||
if ($index_number < 1) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
// index_number must be less than or equal to the number of columns in lookup_array | |||||
if ((!is_array($lookup_array)) || (empty($lookup_array))) { | |||||
return PHPExcel_Calculation_Functions::REF(); | |||||
} else { | |||||
$f = array_keys($lookup_array); | |||||
$firstRow = array_pop($f); | |||||
if ((!is_array($lookup_array[$firstRow])) || ($index_number > count($lookup_array[$firstRow]))) { | |||||
return PHPExcel_Calculation_Functions::REF(); | |||||
} else { | |||||
$columnKeys = array_keys($lookup_array[$firstRow]); | |||||
$firstkey = $f[0] - 1; | |||||
$returnColumn = $firstkey + $index_number; | |||||
$firstColumn = array_shift($f); | |||||
} | |||||
} | |||||
if (!$not_exact_match) { | |||||
$firstRowH = asort($lookup_array[$firstColumn]); | |||||
} | |||||
$rowNumber = $rowValue = false; | |||||
foreach ($lookup_array[$firstColumn] as $rowKey => $rowData) { | |||||
if ((is_numeric($lookup_value) && is_numeric($rowData) && ($rowData > $lookup_value)) || | |||||
(!is_numeric($lookup_value) && !is_numeric($rowData) && (strtolower($rowData) > strtolower($lookup_value)))) { | |||||
break; | |||||
} | |||||
$rowNumber = $rowKey; | |||||
$rowValue = $rowData; | |||||
} | |||||
if ($rowNumber !== false) { | |||||
if ((!$not_exact_match) && ($rowValue != $lookup_value)) { | |||||
// if an exact match is required, we have what we need to return an appropriate response | |||||
return PHPExcel_Calculation_Functions::NA(); | |||||
} else { | |||||
// otherwise return the appropriate value | |||||
return $lookup_array[$returnColumn][$rowNumber]; | |||||
} | |||||
} | |||||
return PHPExcel_Calculation_Functions::NA(); | |||||
} | |||||
/** | |||||
* LOOKUP | |||||
* The LOOKUP function searches for value either from a one-row or one-column range or from an array. | |||||
* @param lookup_value The value that you want to match in lookup_array | |||||
* @param lookup_vector The range of cells being searched | |||||
* @param result_vector The column from which the matching value must be returned | |||||
* @return mixed The value of the found cell | |||||
*/ | |||||
public static function LOOKUP($lookup_value, $lookup_vector, $result_vector = null) | |||||
{ | |||||
$lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); | |||||
if (!is_array($lookup_vector)) { | |||||
return PHPExcel_Calculation_Functions::NA(); | |||||
} | |||||
$lookupRows = count($lookup_vector); | |||||
$l = array_keys($lookup_vector); | |||||
$l = array_shift($l); | |||||
$lookupColumns = count($lookup_vector[$l]); | |||||
if ((($lookupRows == 1) && ($lookupColumns > 1)) || (($lookupRows == 2) && ($lookupColumns != 2))) { | |||||
$lookup_vector = self::TRANSPOSE($lookup_vector); | |||||
$lookupRows = count($lookup_vector); | |||||
$l = array_keys($lookup_vector); | |||||
$lookupColumns = count($lookup_vector[array_shift($l)]); | |||||
} | |||||
if (is_null($result_vector)) { | |||||
$result_vector = $lookup_vector; | |||||
} | |||||
$resultRows = count($result_vector); | |||||
$l = array_keys($result_vector); | |||||
$l = array_shift($l); | |||||
$resultColumns = count($result_vector[$l]); | |||||
if ((($resultRows == 1) && ($resultColumns > 1)) || (($resultRows == 2) && ($resultColumns != 2))) { | |||||
$result_vector = self::TRANSPOSE($result_vector); | |||||
$resultRows = count($result_vector); | |||||
$r = array_keys($result_vector); | |||||
$resultColumns = count($result_vector[array_shift($r)]); | |||||
} | |||||
if ($lookupRows == 2) { | |||||
$result_vector = array_pop($lookup_vector); | |||||
$lookup_vector = array_shift($lookup_vector); | |||||
} | |||||
if ($lookupColumns != 2) { | |||||
foreach ($lookup_vector as &$value) { | |||||
if (is_array($value)) { | |||||
$k = array_keys($value); | |||||
$key1 = $key2 = array_shift($k); | |||||
$key2++; | |||||
$dataValue1 = $value[$key1]; | |||||
} else { | |||||
$key1 = 0; | |||||
$key2 = 1; | |||||
$dataValue1 = $value; | |||||
} | |||||
$dataValue2 = array_shift($result_vector); | |||||
if (is_array($dataValue2)) { | |||||
$dataValue2 = array_shift($dataValue2); | |||||
} | |||||
$value = array($key1 => $dataValue1, $key2 => $dataValue2); | |||||
} | |||||
unset($value); | |||||
} | |||||
return self::VLOOKUP($lookup_value, $lookup_vector, 2); | |||||
} | |||||
} |
@ -0,0 +1,651 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_Calculation_TextData | |||||
* | |||||
* 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_Calculation | |||||
* @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_Calculation_TextData | |||||
{ | |||||
private static $invalidChars; | |||||
private static function unicodeToOrd($c) | |||||
{ | |||||
if (ord($c{0}) >=0 && ord($c{0}) <= 127) { | |||||
return ord($c{0}); | |||||
} elseif (ord($c{0}) >= 192 && ord($c{0}) <= 223) { | |||||
return (ord($c{0})-192)*64 + (ord($c{1})-128); | |||||
} elseif (ord($c{0}) >= 224 && ord($c{0}) <= 239) { | |||||
return (ord($c{0})-224)*4096 + (ord($c{1})-128)*64 + (ord($c{2})-128); | |||||
} elseif (ord($c{0}) >= 240 && ord($c{0}) <= 247) { | |||||
return (ord($c{0})-240)*262144 + (ord($c{1})-128)*4096 + (ord($c{2})-128)*64 + (ord($c{3})-128); | |||||
} elseif (ord($c{0}) >= 248 && ord($c{0}) <= 251) { | |||||
return (ord($c{0})-248)*16777216 + (ord($c{1})-128)*262144 + (ord($c{2})-128)*4096 + (ord($c{3})-128)*64 + (ord($c{4})-128); | |||||
} elseif (ord($c{0}) >= 252 && ord($c{0}) <= 253) { | |||||
return (ord($c{0})-252)*1073741824 + (ord($c{1})-128)*16777216 + (ord($c{2})-128)*262144 + (ord($c{3})-128)*4096 + (ord($c{4})-128)*64 + (ord($c{5})-128); | |||||
} elseif (ord($c{0}) >= 254 && ord($c{0}) <= 255) { | |||||
// error | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
return 0; | |||||
} | |||||
/** | |||||
* CHARACTER | |||||
* | |||||
* @param string $character Value | |||||
* @return int | |||||
*/ | |||||
public static function CHARACTER($character) | |||||
{ | |||||
$character = PHPExcel_Calculation_Functions::flattenSingleValue($character); | |||||
if ((!is_numeric($character)) || ($character < 0)) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
if (function_exists('mb_convert_encoding')) { | |||||
return mb_convert_encoding('&#'.intval($character).';', 'UTF-8', 'HTML-ENTITIES'); | |||||
} else { | |||||
return chr(intval($character)); | |||||
} | |||||
} | |||||
/** | |||||
* TRIMNONPRINTABLE | |||||
* | |||||
* @param mixed $stringValue Value to check | |||||
* @return string | |||||
*/ | |||||
public static function TRIMNONPRINTABLE($stringValue = '') | |||||
{ | |||||
$stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); | |||||
if (is_bool($stringValue)) { | |||||
return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if (self::$invalidChars == null) { | |||||
self::$invalidChars = range(chr(0), chr(31)); | |||||
} | |||||
if (is_string($stringValue) || is_numeric($stringValue)) { | |||||
return str_replace(self::$invalidChars, '', trim($stringValue, "\x00..\x1F")); | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* TRIMSPACES | |||||
* | |||||
* @param mixed $stringValue Value to check | |||||
* @return string | |||||
*/ | |||||
public static function TRIMSPACES($stringValue = '') | |||||
{ | |||||
$stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); | |||||
if (is_bool($stringValue)) { | |||||
return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if (is_string($stringValue) || is_numeric($stringValue)) { | |||||
return trim(preg_replace('/ +/', ' ', trim($stringValue, ' ')), ' '); | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* ASCIICODE | |||||
* | |||||
* @param string $characters Value | |||||
* @return int | |||||
*/ | |||||
public static function ASCIICODE($characters) | |||||
{ | |||||
if (($characters === null) || ($characters === '')) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
$characters = PHPExcel_Calculation_Functions::flattenSingleValue($characters); | |||||
if (is_bool($characters)) { | |||||
if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { | |||||
$characters = (int) $characters; | |||||
} else { | |||||
$characters = ($characters) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
} | |||||
$character = $characters; | |||||
if ((function_exists('mb_strlen')) && (function_exists('mb_substr'))) { | |||||
if (mb_strlen($characters, 'UTF-8') > 1) { | |||||
$character = mb_substr($characters, 0, 1, 'UTF-8'); | |||||
} | |||||
return self::unicodeToOrd($character); | |||||
} else { | |||||
if (strlen($characters) > 0) { | |||||
$character = substr($characters, 0, 1); | |||||
} | |||||
return ord($character); | |||||
} | |||||
} | |||||
/** | |||||
* CONCATENATE | |||||
* | |||||
* @return string | |||||
*/ | |||||
public static function CONCATENATE() | |||||
{ | |||||
$returnValue = ''; | |||||
// Loop through arguments | |||||
$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); | |||||
foreach ($aArgs as $arg) { | |||||
if (is_bool($arg)) { | |||||
if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { | |||||
$arg = (int) $arg; | |||||
} else { | |||||
$arg = ($arg) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
} | |||||
$returnValue .= $arg; | |||||
} | |||||
return $returnValue; | |||||
} | |||||
/** | |||||
* DOLLAR | |||||
* | |||||
* This function converts a number to text using currency format, with the decimals rounded to the specified place. | |||||
* The format used is $#,##0.00_);($#,##0.00).. | |||||
* | |||||
* @param float $value The value to format | |||||
* @param int $decimals The number of digits to display to the right of the decimal point. | |||||
* If decimals is negative, number is rounded to the left of the decimal point. | |||||
* If you omit decimals, it is assumed to be 2 | |||||
* @return string | |||||
*/ | |||||
public static function DOLLAR($value = 0, $decimals = 2) | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
$decimals = is_null($decimals) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($decimals); | |||||
// Validate parameters | |||||
if (!is_numeric($value) || !is_numeric($decimals)) { | |||||
return PHPExcel_Calculation_Functions::NaN(); | |||||
} | |||||
$decimals = floor($decimals); | |||||
$mask = '$#,##0'; | |||||
if ($decimals > 0) { | |||||
$mask .= '.' . str_repeat('0', $decimals); | |||||
} else { | |||||
$round = pow(10, abs($decimals)); | |||||
if ($value < 0) { | |||||
$round = 0-$round; | |||||
} | |||||
$value = PHPExcel_Calculation_MathTrig::MROUND($value, $round); | |||||
} | |||||
return PHPExcel_Style_NumberFormat::toFormattedString($value, $mask); | |||||
} | |||||
/** | |||||
* SEARCHSENSITIVE | |||||
* | |||||
* @param string $needle The string to look for | |||||
* @param string $haystack The string in which to look | |||||
* @param int $offset Offset within $haystack | |||||
* @return string | |||||
*/ | |||||
public static function SEARCHSENSITIVE($needle, $haystack, $offset = 1) | |||||
{ | |||||
$needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); | |||||
$haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); | |||||
$offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); | |||||
if (!is_bool($needle)) { | |||||
if (is_bool($haystack)) { | |||||
$haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) { | |||||
if (PHPExcel_Shared_String::CountCharacters($needle) == 0) { | |||||
return $offset; | |||||
} | |||||
if (function_exists('mb_strpos')) { | |||||
$pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8'); | |||||
} else { | |||||
$pos = strpos($haystack, $needle, --$offset); | |||||
} | |||||
if ($pos !== false) { | |||||
return ++$pos; | |||||
} | |||||
} | |||||
} | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
/** | |||||
* SEARCHINSENSITIVE | |||||
* | |||||
* @param string $needle The string to look for | |||||
* @param string $haystack The string in which to look | |||||
* @param int $offset Offset within $haystack | |||||
* @return string | |||||
*/ | |||||
public static function SEARCHINSENSITIVE($needle, $haystack, $offset = 1) | |||||
{ | |||||
$needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); | |||||
$haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); | |||||
$offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); | |||||
if (!is_bool($needle)) { | |||||
if (is_bool($haystack)) { | |||||
$haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) { | |||||
if (PHPExcel_Shared_String::CountCharacters($needle) == 0) { | |||||
return $offset; | |||||
} | |||||
if (function_exists('mb_stripos')) { | |||||
$pos = mb_stripos($haystack, $needle, --$offset, 'UTF-8'); | |||||
} else { | |||||
$pos = stripos($haystack, $needle, --$offset); | |||||
} | |||||
if ($pos !== false) { | |||||
return ++$pos; | |||||
} | |||||
} | |||||
} | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
/** | |||||
* FIXEDFORMAT | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @param integer $decimals | |||||
* @param boolean $no_commas | |||||
* @return boolean | |||||
*/ | |||||
public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = false) | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
$decimals = PHPExcel_Calculation_Functions::flattenSingleValue($decimals); | |||||
$no_commas = PHPExcel_Calculation_Functions::flattenSingleValue($no_commas); | |||||
// Validate parameters | |||||
if (!is_numeric($value) || !is_numeric($decimals)) { | |||||
return PHPExcel_Calculation_Functions::NaN(); | |||||
} | |||||
$decimals = floor($decimals); | |||||
$valueResult = round($value, $decimals); | |||||
if ($decimals < 0) { | |||||
$decimals = 0; | |||||
} | |||||
if (!$no_commas) { | |||||
$valueResult = number_format($valueResult, $decimals); | |||||
} | |||||
return (string) $valueResult; | |||||
} | |||||
/** | |||||
* LEFT | |||||
* | |||||
* @param string $value Value | |||||
* @param int $chars Number of characters | |||||
* @return string | |||||
*/ | |||||
public static function LEFT($value = '', $chars = 1) | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
$chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); | |||||
if ($chars < 0) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
if (is_bool($value)) { | |||||
$value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if (function_exists('mb_substr')) { | |||||
return mb_substr($value, 0, $chars, 'UTF-8'); | |||||
} else { | |||||
return substr($value, 0, $chars); | |||||
} | |||||
} | |||||
/** | |||||
* MID | |||||
* | |||||
* @param string $value Value | |||||
* @param int $start Start character | |||||
* @param int $chars Number of characters | |||||
* @return string | |||||
*/ | |||||
public static function MID($value = '', $start = 1, $chars = null) | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
$start = PHPExcel_Calculation_Functions::flattenSingleValue($start); | |||||
$chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); | |||||
if (($start < 1) || ($chars < 0)) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
if (is_bool($value)) { | |||||
$value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if (function_exists('mb_substr')) { | |||||
return mb_substr($value, --$start, $chars, 'UTF-8'); | |||||
} else { | |||||
return substr($value, --$start, $chars); | |||||
} | |||||
} | |||||
/** | |||||
* RIGHT | |||||
* | |||||
* @param string $value Value | |||||
* @param int $chars Number of characters | |||||
* @return string | |||||
*/ | |||||
public static function RIGHT($value = '', $chars = 1) | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
$chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); | |||||
if ($chars < 0) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
if (is_bool($value)) { | |||||
$value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if ((function_exists('mb_substr')) && (function_exists('mb_strlen'))) { | |||||
return mb_substr($value, mb_strlen($value, 'UTF-8') - $chars, $chars, 'UTF-8'); | |||||
} else { | |||||
return substr($value, strlen($value) - $chars); | |||||
} | |||||
} | |||||
/** | |||||
* STRINGLENGTH | |||||
* | |||||
* @param string $value Value | |||||
* @return string | |||||
*/ | |||||
public static function STRINGLENGTH($value = '') | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
if (is_bool($value)) { | |||||
$value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if (function_exists('mb_strlen')) { | |||||
return mb_strlen($value, 'UTF-8'); | |||||
} else { | |||||
return strlen($value); | |||||
} | |||||
} | |||||
/** | |||||
* LOWERCASE | |||||
* | |||||
* Converts a string value to upper case. | |||||
* | |||||
* @param string $mixedCaseString | |||||
* @return string | |||||
*/ | |||||
public static function LOWERCASE($mixedCaseString) | |||||
{ | |||||
$mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); | |||||
if (is_bool($mixedCaseString)) { | |||||
$mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
return PHPExcel_Shared_String::StrToLower($mixedCaseString); | |||||
} | |||||
/** | |||||
* UPPERCASE | |||||
* | |||||
* Converts a string value to upper case. | |||||
* | |||||
* @param string $mixedCaseString | |||||
* @return string | |||||
*/ | |||||
public static function UPPERCASE($mixedCaseString) | |||||
{ | |||||
$mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); | |||||
if (is_bool($mixedCaseString)) { | |||||
$mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
return PHPExcel_Shared_String::StrToUpper($mixedCaseString); | |||||
} | |||||
/** | |||||
* PROPERCASE | |||||
* | |||||
* Converts a string value to upper case. | |||||
* | |||||
* @param string $mixedCaseString | |||||
* @return string | |||||
*/ | |||||
public static function PROPERCASE($mixedCaseString) | |||||
{ | |||||
$mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); | |||||
if (is_bool($mixedCaseString)) { | |||||
$mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
return PHPExcel_Shared_String::StrToTitle($mixedCaseString); | |||||
} | |||||
/** | |||||
* REPLACE | |||||
* | |||||
* @param string $oldText String to modify | |||||
* @param int $start Start character | |||||
* @param int $chars Number of characters | |||||
* @param string $newText String to replace in defined position | |||||
* @return string | |||||
*/ | |||||
public static function REPLACE($oldText = '', $start = 1, $chars = null, $newText) | |||||
{ | |||||
$oldText = PHPExcel_Calculation_Functions::flattenSingleValue($oldText); | |||||
$start = PHPExcel_Calculation_Functions::flattenSingleValue($start); | |||||
$chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); | |||||
$newText = PHPExcel_Calculation_Functions::flattenSingleValue($newText); | |||||
$left = self::LEFT($oldText, $start-1); | |||||
$right = self::RIGHT($oldText, self::STRINGLENGTH($oldText)-($start+$chars)+1); | |||||
return $left.$newText.$right; | |||||
} | |||||
/** | |||||
* SUBSTITUTE | |||||
* | |||||
* @param string $text Value | |||||
* @param string $fromText From Value | |||||
* @param string $toText To Value | |||||
* @param integer $instance Instance Number | |||||
* @return string | |||||
*/ | |||||
public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $instance = 0) | |||||
{ | |||||
$text = PHPExcel_Calculation_Functions::flattenSingleValue($text); | |||||
$fromText = PHPExcel_Calculation_Functions::flattenSingleValue($fromText); | |||||
$toText = PHPExcel_Calculation_Functions::flattenSingleValue($toText); | |||||
$instance = floor(PHPExcel_Calculation_Functions::flattenSingleValue($instance)); | |||||
if ($instance == 0) { | |||||
if (function_exists('mb_str_replace')) { | |||||
return mb_str_replace($fromText, $toText, $text); | |||||
} else { | |||||
return str_replace($fromText, $toText, $text); | |||||
} | |||||
} else { | |||||
$pos = -1; | |||||
while ($instance > 0) { | |||||
if (function_exists('mb_strpos')) { | |||||
$pos = mb_strpos($text, $fromText, $pos+1, 'UTF-8'); | |||||
} else { | |||||
$pos = strpos($text, $fromText, $pos+1); | |||||
} | |||||
if ($pos === false) { | |||||
break; | |||||
} | |||||
--$instance; | |||||
} | |||||
if ($pos !== false) { | |||||
if (function_exists('mb_strlen')) { | |||||
return self::REPLACE($text, ++$pos, mb_strlen($fromText, 'UTF-8'), $toText); | |||||
} else { | |||||
return self::REPLACE($text, ++$pos, strlen($fromText), $toText); | |||||
} | |||||
} | |||||
} | |||||
return $text; | |||||
} | |||||
/** | |||||
* RETURNSTRING | |||||
* | |||||
* @param mixed $testValue Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function RETURNSTRING($testValue = '') | |||||
{ | |||||
$testValue = PHPExcel_Calculation_Functions::flattenSingleValue($testValue); | |||||
if (is_string($testValue)) { | |||||
return $testValue; | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* TEXTFORMAT | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @param string $format Format mask to use | |||||
* @return boolean | |||||
*/ | |||||
public static function TEXTFORMAT($value, $format) | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
$format = PHPExcel_Calculation_Functions::flattenSingleValue($format); | |||||
if ((is_string($value)) && (!is_numeric($value)) && PHPExcel_Shared_Date::isDateTimeFormatCode($format)) { | |||||
$value = PHPExcel_Calculation_DateTime::DATEVALUE($value); | |||||
} | |||||
return (string) PHPExcel_Style_NumberFormat::toFormattedString($value, $format); | |||||
} | |||||
/** | |||||
* VALUE | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function VALUE($value = '') | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
if (!is_numeric($value)) { | |||||
$numberValue = str_replace( | |||||
PHPExcel_Shared_String::getThousandsSeparator(), | |||||
'', | |||||
trim($value, " \t\n\r\0\x0B" . PHPExcel_Shared_String::getCurrencyCode()) | |||||
); | |||||
if (is_numeric($numberValue)) { | |||||
return (float) $numberValue; | |||||
} | |||||
$dateSetting = PHPExcel_Calculation_Functions::getReturnDateType(); | |||||
PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); | |||||
if (strpos($value, ':') !== false) { | |||||
$timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($value); | |||||
if ($timeValue !== PHPExcel_Calculation_Functions::VALUE()) { | |||||
PHPExcel_Calculation_Functions::setReturnDateType($dateSetting); | |||||
return $timeValue; | |||||
} | |||||
} | |||||
$dateValue = PHPExcel_Calculation_DateTime::DATEVALUE($value); | |||||
if ($dateValue !== PHPExcel_Calculation_Functions::VALUE()) { | |||||
PHPExcel_Calculation_Functions::setReturnDateType($dateSetting); | |||||
return $dateValue; | |||||
} | |||||
PHPExcel_Calculation_Functions::setReturnDateType($dateSetting); | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
return (float) $value; | |||||
} | |||||
} |
@ -0,0 +1,651 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_Calculation_TextData | |||||
* | |||||
* 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_Calculation | |||||
* @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_Calculation_TextData | |||||
{ | |||||
private static $invalidChars; | |||||
private static function unicodeToOrd($c) | |||||
{ | |||||
if (ord($c{0}) >=0 && ord($c{0}) <= 127) { | |||||
return ord($c{0}); | |||||
} elseif (ord($c{0}) >= 192 && ord($c{0}) <= 223) { | |||||
return (ord($c{0})-192)*64 + (ord($c{1})-128); | |||||
} elseif (ord($c{0}) >= 224 && ord($c{0}) <= 239) { | |||||
return (ord($c{0})-224)*4096 + (ord($c{1})-128)*64 + (ord($c{2})-128); | |||||
} elseif (ord($c{0}) >= 240 && ord($c{0}) <= 247) { | |||||
return (ord($c{0})-240)*262144 + (ord($c{1})-128)*4096 + (ord($c{2})-128)*64 + (ord($c{3})-128); | |||||
} elseif (ord($c{0}) >= 248 && ord($c{0}) <= 251) { | |||||
return (ord($c{0})-248)*16777216 + (ord($c{1})-128)*262144 + (ord($c{2})-128)*4096 + (ord($c{3})-128)*64 + (ord($c{4})-128); | |||||
} elseif (ord($c{0}) >= 252 && ord($c{0}) <= 253) { | |||||
return (ord($c{0})-252)*1073741824 + (ord($c{1})-128)*16777216 + (ord($c{2})-128)*262144 + (ord($c{3})-128)*4096 + (ord($c{4})-128)*64 + (ord($c{5})-128); | |||||
} elseif (ord($c{0}) >= 254 && ord($c{0}) <= 255) { | |||||
// error | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
return 0; | |||||
} | |||||
/** | |||||
* CHARACTER | |||||
* | |||||
* @param string $character Value | |||||
* @return int | |||||
*/ | |||||
public static function CHARACTER($character) | |||||
{ | |||||
$character = PHPExcel_Calculation_Functions::flattenSingleValue($character); | |||||
if ((!is_numeric($character)) || ($character < 0)) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
if (function_exists('mb_convert_encoding')) { | |||||
return mb_convert_encoding('&#'.intval($character).';', 'UTF-8', 'HTML-ENTITIES'); | |||||
} else { | |||||
return chr(intval($character)); | |||||
} | |||||
} | |||||
/** | |||||
* TRIMNONPRINTABLE | |||||
* | |||||
* @param mixed $stringValue Value to check | |||||
* @return string | |||||
*/ | |||||
public static function TRIMNONPRINTABLE($stringValue = '') | |||||
{ | |||||
$stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); | |||||
if (is_bool($stringValue)) { | |||||
return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if (self::$invalidChars == null) { | |||||
self::$invalidChars = range(chr(0), chr(31)); | |||||
} | |||||
if (is_string($stringValue) || is_numeric($stringValue)) { | |||||
return str_replace(self::$invalidChars, '', trim($stringValue, "\x00..\x1F")); | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* TRIMSPACES | |||||
* | |||||
* @param mixed $stringValue Value to check | |||||
* @return string | |||||
*/ | |||||
public static function TRIMSPACES($stringValue = '') | |||||
{ | |||||
$stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); | |||||
if (is_bool($stringValue)) { | |||||
return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if (is_string($stringValue) || is_numeric($stringValue)) { | |||||
return trim(preg_replace('/ +/', ' ', trim($stringValue, ' ')), ' '); | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* ASCIICODE | |||||
* | |||||
* @param string $characters Value | |||||
* @return int | |||||
*/ | |||||
public static function ASCIICODE($characters) | |||||
{ | |||||
if (($characters === null) || ($characters === '')) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
$characters = PHPExcel_Calculation_Functions::flattenSingleValue($characters); | |||||
if (is_bool($characters)) { | |||||
if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { | |||||
$characters = (int) $characters; | |||||
} else { | |||||
$characters = ($characters) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
} | |||||
$character = $characters; | |||||
if ((function_exists('mb_strlen')) && (function_exists('mb_substr'))) { | |||||
if (mb_strlen($characters, 'UTF-8') > 1) { | |||||
$character = mb_substr($characters, 0, 1, 'UTF-8'); | |||||
} | |||||
return self::unicodeToOrd($character); | |||||
} else { | |||||
if (strlen($characters) > 0) { | |||||
$character = substr($characters, 0, 1); | |||||
} | |||||
return ord($character); | |||||
} | |||||
} | |||||
/** | |||||
* CONCATENATE | |||||
* | |||||
* @return string | |||||
*/ | |||||
public static function CONCATENATE() | |||||
{ | |||||
$returnValue = ''; | |||||
// Loop through arguments | |||||
$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); | |||||
foreach ($aArgs as $arg) { | |||||
if (is_bool($arg)) { | |||||
if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { | |||||
$arg = (int) $arg; | |||||
} else { | |||||
$arg = ($arg) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
} | |||||
$returnValue .= $arg; | |||||
} | |||||
return $returnValue; | |||||
} | |||||
/** | |||||
* DOLLAR | |||||
* | |||||
* This function converts a number to text using currency format, with the decimals rounded to the specified place. | |||||
* The format used is $#,##0.00_);($#,##0.00).. | |||||
* | |||||
* @param float $value The value to format | |||||
* @param int $decimals The number of digits to display to the right of the decimal point. | |||||
* If decimals is negative, number is rounded to the left of the decimal point. | |||||
* If you omit decimals, it is assumed to be 2 | |||||
* @return string | |||||
*/ | |||||
public static function DOLLAR($value = 0, $decimals = 2) | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
$decimals = is_null($decimals) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($decimals); | |||||
// Validate parameters | |||||
if (!is_numeric($value) || !is_numeric($decimals)) { | |||||
return PHPExcel_Calculation_Functions::NaN(); | |||||
} | |||||
$decimals = floor($decimals); | |||||
$mask = '$#,##0'; | |||||
if ($decimals > 0) { | |||||
$mask .= '.' . str_repeat('0', $decimals); | |||||
} else { | |||||
$round = pow(10, abs($decimals)); | |||||
if ($value < 0) { | |||||
$round = 0-$round; | |||||
} | |||||
$value = PHPExcel_Calculation_MathTrig::MROUND($value, $round); | |||||
} | |||||
return PHPExcel_Style_NumberFormat::toFormattedString($value, $mask); | |||||
} | |||||
/** | |||||
* SEARCHSENSITIVE | |||||
* | |||||
* @param string $needle The string to look for | |||||
* @param string $haystack The string in which to look | |||||
* @param int $offset Offset within $haystack | |||||
* @return string | |||||
*/ | |||||
public static function SEARCHSENSITIVE($needle, $haystack, $offset = 1) | |||||
{ | |||||
$needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); | |||||
$haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); | |||||
$offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); | |||||
if (!is_bool($needle)) { | |||||
if (is_bool($haystack)) { | |||||
$haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) { | |||||
if (PHPExcel_Shared_String::CountCharacters($needle) == 0) { | |||||
return $offset; | |||||
} | |||||
if (function_exists('mb_strpos')) { | |||||
$pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8'); | |||||
} else { | |||||
$pos = strpos($haystack, $needle, --$offset); | |||||
} | |||||
if ($pos !== false) { | |||||
return ++$pos; | |||||
} | |||||
} | |||||
} | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
/** | |||||
* SEARCHINSENSITIVE | |||||
* | |||||
* @param string $needle The string to look for | |||||
* @param string $haystack The string in which to look | |||||
* @param int $offset Offset within $haystack | |||||
* @return string | |||||
*/ | |||||
public static function SEARCHINSENSITIVE($needle, $haystack, $offset = 1) | |||||
{ | |||||
$needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); | |||||
$haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); | |||||
$offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); | |||||
if (!is_bool($needle)) { | |||||
if (is_bool($haystack)) { | |||||
$haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) { | |||||
if (PHPExcel_Shared_String::CountCharacters($needle) == 0) { | |||||
return $offset; | |||||
} | |||||
if (function_exists('mb_stripos')) { | |||||
$pos = mb_stripos($haystack, $needle, --$offset, 'UTF-8'); | |||||
} else { | |||||
$pos = stripos($haystack, $needle, --$offset); | |||||
} | |||||
if ($pos !== false) { | |||||
return ++$pos; | |||||
} | |||||
} | |||||
} | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
/** | |||||
* FIXEDFORMAT | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @param integer $decimals | |||||
* @param boolean $no_commas | |||||
* @return boolean | |||||
*/ | |||||
public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = false) | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
$decimals = PHPExcel_Calculation_Functions::flattenSingleValue($decimals); | |||||
$no_commas = PHPExcel_Calculation_Functions::flattenSingleValue($no_commas); | |||||
// Validate parameters | |||||
if (!is_numeric($value) || !is_numeric($decimals)) { | |||||
return PHPExcel_Calculation_Functions::NaN(); | |||||
} | |||||
$decimals = floor($decimals); | |||||
$valueResult = round($value, $decimals); | |||||
if ($decimals < 0) { | |||||
$decimals = 0; | |||||
} | |||||
if (!$no_commas) { | |||||
$valueResult = number_format($valueResult, $decimals); | |||||
} | |||||
return (string) $valueResult; | |||||
} | |||||
/** | |||||
* LEFT | |||||
* | |||||
* @param string $value Value | |||||
* @param int $chars Number of characters | |||||
* @return string | |||||
*/ | |||||
public static function LEFT($value = '', $chars = 1) | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
$chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); | |||||
if ($chars < 0) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
if (is_bool($value)) { | |||||
$value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if (function_exists('mb_substr')) { | |||||
return mb_substr($value, 0, $chars, 'UTF-8'); | |||||
} else { | |||||
return substr($value, 0, $chars); | |||||
} | |||||
} | |||||
/** | |||||
* MID | |||||
* | |||||
* @param string $value Value | |||||
* @param int $start Start character | |||||
* @param int $chars Number of characters | |||||
* @return string | |||||
*/ | |||||
public static function MID($value = '', $start = 1, $chars = null) | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
$start = PHPExcel_Calculation_Functions::flattenSingleValue($start); | |||||
$chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); | |||||
if (($start < 1) || ($chars < 0)) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
if (is_bool($value)) { | |||||
$value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if (function_exists('mb_substr')) { | |||||
return mb_substr($value, --$start, $chars, 'UTF-8'); | |||||
} else { | |||||
return substr($value, --$start, $chars); | |||||
} | |||||
} | |||||
/** | |||||
* RIGHT | |||||
* | |||||
* @param string $value Value | |||||
* @param int $chars Number of characters | |||||
* @return string | |||||
*/ | |||||
public static function RIGHT($value = '', $chars = 1) | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
$chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); | |||||
if ($chars < 0) { | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
if (is_bool($value)) { | |||||
$value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if ((function_exists('mb_substr')) && (function_exists('mb_strlen'))) { | |||||
return mb_substr($value, mb_strlen($value, 'UTF-8') - $chars, $chars, 'UTF-8'); | |||||
} else { | |||||
return substr($value, strlen($value) - $chars); | |||||
} | |||||
} | |||||
/** | |||||
* STRINGLENGTH | |||||
* | |||||
* @param string $value Value | |||||
* @return string | |||||
*/ | |||||
public static function STRINGLENGTH($value = '') | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
if (is_bool($value)) { | |||||
$value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
if (function_exists('mb_strlen')) { | |||||
return mb_strlen($value, 'UTF-8'); | |||||
} else { | |||||
return strlen($value); | |||||
} | |||||
} | |||||
/** | |||||
* LOWERCASE | |||||
* | |||||
* Converts a string value to upper case. | |||||
* | |||||
* @param string $mixedCaseString | |||||
* @return string | |||||
*/ | |||||
public static function LOWERCASE($mixedCaseString) | |||||
{ | |||||
$mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); | |||||
if (is_bool($mixedCaseString)) { | |||||
$mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
return PHPExcel_Shared_String::StrToLower($mixedCaseString); | |||||
} | |||||
/** | |||||
* UPPERCASE | |||||
* | |||||
* Converts a string value to upper case. | |||||
* | |||||
* @param string $mixedCaseString | |||||
* @return string | |||||
*/ | |||||
public static function UPPERCASE($mixedCaseString) | |||||
{ | |||||
$mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); | |||||
if (is_bool($mixedCaseString)) { | |||||
$mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
return PHPExcel_Shared_String::StrToUpper($mixedCaseString); | |||||
} | |||||
/** | |||||
* PROPERCASE | |||||
* | |||||
* Converts a string value to upper case. | |||||
* | |||||
* @param string $mixedCaseString | |||||
* @return string | |||||
*/ | |||||
public static function PROPERCASE($mixedCaseString) | |||||
{ | |||||
$mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); | |||||
if (is_bool($mixedCaseString)) { | |||||
$mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); | |||||
} | |||||
return PHPExcel_Shared_String::StrToTitle($mixedCaseString); | |||||
} | |||||
/** | |||||
* REPLACE | |||||
* | |||||
* @param string $oldText String to modify | |||||
* @param int $start Start character | |||||
* @param int $chars Number of characters | |||||
* @param string $newText String to replace in defined position | |||||
* @return string | |||||
*/ | |||||
public static function REPLACE($oldText = '', $start = 1, $chars = null, $newText) | |||||
{ | |||||
$oldText = PHPExcel_Calculation_Functions::flattenSingleValue($oldText); | |||||
$start = PHPExcel_Calculation_Functions::flattenSingleValue($start); | |||||
$chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); | |||||
$newText = PHPExcel_Calculation_Functions::flattenSingleValue($newText); | |||||
$left = self::LEFT($oldText, $start-1); | |||||
$right = self::RIGHT($oldText, self::STRINGLENGTH($oldText)-($start+$chars)+1); | |||||
return $left.$newText.$right; | |||||
} | |||||
/** | |||||
* SUBSTITUTE | |||||
* | |||||
* @param string $text Value | |||||
* @param string $fromText From Value | |||||
* @param string $toText To Value | |||||
* @param integer $instance Instance Number | |||||
* @return string | |||||
*/ | |||||
public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $instance = 0) | |||||
{ | |||||
$text = PHPExcel_Calculation_Functions::flattenSingleValue($text); | |||||
$fromText = PHPExcel_Calculation_Functions::flattenSingleValue($fromText); | |||||
$toText = PHPExcel_Calculation_Functions::flattenSingleValue($toText); | |||||
$instance = floor(PHPExcel_Calculation_Functions::flattenSingleValue($instance)); | |||||
if ($instance == 0) { | |||||
if (function_exists('mb_str_replace')) { | |||||
return mb_str_replace($fromText, $toText, $text); | |||||
} else { | |||||
return str_replace($fromText, $toText, $text); | |||||
} | |||||
} else { | |||||
$pos = -1; | |||||
while ($instance > 0) { | |||||
if (function_exists('mb_strpos')) { | |||||
$pos = mb_strpos($text, $fromText, $pos+1, 'UTF-8'); | |||||
} else { | |||||
$pos = strpos($text, $fromText, $pos+1); | |||||
} | |||||
if ($pos === false) { | |||||
break; | |||||
} | |||||
--$instance; | |||||
} | |||||
if ($pos !== false) { | |||||
if (function_exists('mb_strlen')) { | |||||
return self::REPLACE($text, ++$pos, mb_strlen($fromText, 'UTF-8'), $toText); | |||||
} else { | |||||
return self::REPLACE($text, ++$pos, strlen($fromText), $toText); | |||||
} | |||||
} | |||||
} | |||||
return $text; | |||||
} | |||||
/** | |||||
* RETURNSTRING | |||||
* | |||||
* @param mixed $testValue Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function RETURNSTRING($testValue = '') | |||||
{ | |||||
$testValue = PHPExcel_Calculation_Functions::flattenSingleValue($testValue); | |||||
if (is_string($testValue)) { | |||||
return $testValue; | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* TEXTFORMAT | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @param string $format Format mask to use | |||||
* @return boolean | |||||
*/ | |||||
public static function TEXTFORMAT($value, $format) | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
$format = PHPExcel_Calculation_Functions::flattenSingleValue($format); | |||||
if ((is_string($value)) && (!is_numeric($value)) && PHPExcel_Shared_Date::isDateTimeFormatCode($format)) { | |||||
$value = PHPExcel_Calculation_DateTime::DATEVALUE($value); | |||||
} | |||||
return (string) PHPExcel_Style_NumberFormat::toFormattedString($value, $format); | |||||
} | |||||
/** | |||||
* VALUE | |||||
* | |||||
* @param mixed $value Value to check | |||||
* @return boolean | |||||
*/ | |||||
public static function VALUE($value = '') | |||||
{ | |||||
$value = PHPExcel_Calculation_Functions::flattenSingleValue($value); | |||||
if (!is_numeric($value)) { | |||||
$numberValue = str_replace( | |||||
PHPExcel_Shared_String::getThousandsSeparator(), | |||||
'', | |||||
trim($value, " \t\n\r\0\x0B" . PHPExcel_Shared_String::getCurrencyCode()) | |||||
); | |||||
if (is_numeric($numberValue)) { | |||||
return (float) $numberValue; | |||||
} | |||||
$dateSetting = PHPExcel_Calculation_Functions::getReturnDateType(); | |||||
PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); | |||||
if (strpos($value, ':') !== false) { | |||||
$timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($value); | |||||
if ($timeValue !== PHPExcel_Calculation_Functions::VALUE()) { | |||||
PHPExcel_Calculation_Functions::setReturnDateType($dateSetting); | |||||
return $timeValue; | |||||
} | |||||
} | |||||
$dateValue = PHPExcel_Calculation_DateTime::DATEVALUE($value); | |||||
if ($dateValue !== PHPExcel_Calculation_Functions::VALUE()) { | |||||
PHPExcel_Calculation_Functions::setReturnDateType($dateSetting); | |||||
return $dateValue; | |||||
} | |||||
PHPExcel_Calculation_Functions::setReturnDateType($dateSetting); | |||||
return PHPExcel_Calculation_Functions::VALUE(); | |||||
} | |||||
return (float) $value; | |||||
} | |||||
} |
@ -0,0 +1,111 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Calculation_Token_Stack | |||||
* | |||||
* 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_Calculation | |||||
* @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_Calculation_Token_Stack | |||||
{ | |||||
/** | |||||
* The parser stack for formulae | |||||
* | |||||
* @var mixed[] | |||||
*/ | |||||
private $stack = array(); | |||||
/** | |||||
* Count of entries in the parser stack | |||||
* | |||||
* @var integer | |||||
*/ | |||||
private $count = 0; | |||||
/** | |||||
* Return the number of entries on the stack | |||||
* | |||||
* @return integer | |||||
*/ | |||||
public function count() | |||||
{ | |||||
return $this->count; | |||||
} | |||||
/** | |||||
* Push a new entry onto the stack | |||||
* | |||||
* @param mixed $type | |||||
* @param mixed $value | |||||
* @param mixed $reference | |||||
*/ | |||||
public function push($type, $value, $reference = null) | |||||
{ | |||||
$this->stack[$this->count++] = array( | |||||
'type' => $type, | |||||
'value' => $value, | |||||
'reference' => $reference | |||||
); | |||||
if ($type == 'Function') { | |||||
$localeFunction = PHPExcel_Calculation::localeFunc($value); | |||||
if ($localeFunction != $value) { | |||||
$this->stack[($this->count - 1)]['localeValue'] = $localeFunction; | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Pop the last entry from the stack | |||||
* | |||||
* @return mixed | |||||
*/ | |||||
public function pop() | |||||
{ | |||||
if ($this->count > 0) { | |||||
return $this->stack[--$this->count]; | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* Return an entry from the stack without removing it | |||||
* | |||||
* @param integer $n number indicating how far back in the stack we want to look | |||||
* @return mixed | |||||
*/ | |||||
public function last($n = 1) | |||||
{ | |||||
if ($this->count - $n < 0) { | |||||
return null; | |||||
} | |||||
return $this->stack[$this->count - $n]; | |||||
} | |||||
/** | |||||
* Clear the stack | |||||
*/ | |||||
public function clear() | |||||
{ | |||||
$this->stack = array(); | |||||
$this->count = 0; | |||||
} | |||||
} |
@ -0,0 +1,351 @@ | |||||
ABS | |||||
ACCRINT | |||||
ACCRINTM | |||||
ACOS | |||||
ACOSH | |||||
ADDRESS | |||||
AMORDEGRC | |||||
AMORLINC | |||||
AND | |||||
AREAS | |||||
ASC | |||||
ASIN | |||||
ASINH | |||||
ATAN | |||||
ATAN2 | |||||
ATANH | |||||
AVEDEV | |||||
AVERAGE | |||||
AVERAGEA | |||||
AVERAGEIF | |||||
AVERAGEIFS | |||||
BAHTTEXT | |||||
BESSELI | |||||
BESSELJ | |||||
BESSELK | |||||
BESSELY | |||||
BETADIST | |||||
BETAINV | |||||
BIN2DEC | |||||
BIN2HEX | |||||
BIN2OCT | |||||
BINOMDIST | |||||
CEILING | |||||
CELL | |||||
CHAR | |||||
CHIDIST | |||||
CHIINV | |||||
CHITEST | |||||
CHOOSE | |||||
CLEAN | |||||
CODE | |||||
COLUMN | |||||
COLUMNS | |||||
COMBIN | |||||
COMPLEX | |||||
CONCATENATE | |||||
CONFIDENCE | |||||
CONVERT | |||||
CORREL | |||||
COS | |||||
COSH | |||||
COUNT | |||||
COUNTA | |||||
COUNTBLANK | |||||
COUNTIF | |||||
COUNTIFS | |||||
COUPDAYBS | |||||
COUPDAYBS | |||||
COUPDAYSNC | |||||
COUPNCD | |||||
COUPNUM | |||||
COUPPCD | |||||
COVAR | |||||
CRITBINOM | |||||
CUBEKPIMEMBER | |||||
CUBEMEMBER | |||||
CUBEMEMBERPROPERTY | |||||
CUBERANKEDMEMBER | |||||
CUBESET | |||||
CUBESETCOUNT | |||||
CUBEVALUE | |||||
CUMIPMT | |||||
CUMPRINC | |||||
DATE | |||||
DATEDIF | |||||
DATEVALUE | |||||
DAVERAGE | |||||
DAY | |||||
DAYS360 | |||||
DB | |||||
DCOUNT | |||||
DCOUNTA | |||||
DDB | |||||
DEC2BIN | |||||
DEC2HEX | |||||
DEC2OCT | |||||
DEGREES | |||||
DELTA | |||||
DEVSQ | |||||
DGET | |||||
DISC | |||||
DMAX | |||||
DMIN | |||||
DOLLAR | |||||
DOLLARDE | |||||
DOLLARFR | |||||
DPRODUCT | |||||
DSTDEV | |||||
DSTDEVP | |||||
DSUM | |||||
DURATION | |||||
DVAR | |||||
DVARP | |||||
EDATE | |||||
EFFECT | |||||
EOMONTH | |||||
ERF | |||||
ERFC | |||||
ERROR.TYPE | |||||
EVEN | |||||
EXACT | |||||
EXP | |||||
EXPONDIST | |||||
FACT | |||||
FACTDOUBLE | |||||
FALSE | |||||
FDIST | |||||
FIND | |||||
FINDB | |||||
FINV | |||||
FISHER | |||||
FISHERINV | |||||
FIXED | |||||
FLOOR | |||||
FORECAST | |||||
FREQUENCY | |||||
FTEST | |||||
FV | |||||
FVSCHEDULE | |||||
GAMAMDIST | |||||
GAMMAINV | |||||
GAMMALN | |||||
GCD | |||||
GEOMEAN | |||||
GESTEP | |||||
GETPIVOTDATA | |||||
GROWTH | |||||
HARMEAN | |||||
HEX2BIN | |||||
HEX2OCT | |||||
HLOOKUP | |||||
HOUR | |||||
HYPERLINK | |||||
HYPGEOMDIST | |||||
IF | |||||
IFERROR | |||||
IMABS | |||||
IMAGINARY | |||||
IMARGUMENT | |||||
IMCONJUGATE | |||||
IMCOS | |||||
IMEXP | |||||
IMLN | |||||
IMLOG10 | |||||
IMLOG2 | |||||
IMPOWER | |||||
IMPRODUCT | |||||
IMREAL | |||||
IMSIN | |||||
IMSQRT | |||||
IMSUB | |||||
IMSUM | |||||
INDEX | |||||
INDIRECT | |||||
INFO | |||||
INT | |||||
INTERCEPT | |||||
INTRATE | |||||
IPMT | |||||
IRR | |||||
ISBLANK | |||||
ISERR | |||||
ISERROR | |||||
ISEVEN | |||||
ISLOGICAL | |||||
ISNA | |||||
ISNONTEXT | |||||
ISNUMBER | |||||
ISODD | |||||
ISPMT | |||||
ISREF | |||||
ISTEXT | |||||
JIS | |||||
KURT | |||||
LARGE | |||||
LCM | |||||
LEFT | |||||
LEFTB | |||||
LEN | |||||
LENB | |||||
LINEST | |||||
LN | |||||
LOG | |||||
LOG10 | |||||
LOGEST | |||||
LOGINV | |||||
LOGNORMDIST | |||||
LOOKUP | |||||
LOWER | |||||
MATCH | |||||
MAX | |||||
MAXA | |||||
MDETERM | |||||
MDURATION | |||||
MEDIAN | |||||
MID | |||||
MIDB | |||||
MIN | |||||
MINA | |||||
MINUTE | |||||
MINVERSE | |||||
MIRR | |||||
MMULT | |||||
MOD | |||||
MODE | |||||
MONTH | |||||
MROUND | |||||
MULTINOMIAL | |||||
N | |||||
NA | |||||
NEGBINOMDIST | |||||
NETWORKDAYS | |||||
NOMINAL | |||||
NORMDIST | |||||
NORMINV | |||||
NORMSDIST | |||||
NORMSINV | |||||
NOT | |||||
NOW | |||||
NPER | |||||
NPV | |||||
OCT2BIN | |||||
OCT2DEC | |||||
OCT2HEX | |||||
ODD | |||||
ODDFPRICE | |||||
ODDFYIELD | |||||
ODDLPRICE | |||||
ODDLYIELD | |||||
OFFSET | |||||
OR | |||||
PEARSON | |||||
PERCENTILE | |||||
PERCENTRANK | |||||
PERMUT | |||||
PHONETIC | |||||
PI | |||||
PMT | |||||
POISSON | |||||
POWER | |||||
PPMT | |||||
PRICE | |||||
PRICEDISC | |||||
PRICEMAT | |||||
PROB | |||||
PRODUCT | |||||
PROPER | |||||
PV | |||||
QUARTILE | |||||
QUOTIENT | |||||
RADIANS | |||||
RAND | |||||
RANDBETWEEN | |||||
RANK | |||||
RATE | |||||
RECEIVED | |||||
REPLACE | |||||
REPLACEB | |||||
REPT | |||||
RIGHT | |||||
RIGHTB | |||||
ROMAN | |||||
ROUND | |||||
ROUNDDOWN | |||||
ROUNDUP | |||||
ROW | |||||
ROWS | |||||
RSQ | |||||
RTD | |||||
SEARCH | |||||
SEARCHB | |||||
SECOND | |||||
SERIESSUM | |||||
SIGN | |||||
SIN | |||||
SINH | |||||
SKEW | |||||
SLN | |||||
SLOPE | |||||
SMALL | |||||
SQRT | |||||
SQRTPI | |||||
STANDARDIZE | |||||
STDEV | |||||
STDEVA | |||||
STDEVP | |||||
STDEVPA | |||||
STEYX | |||||
SUBSTITUTE | |||||
SUBTOTAL | |||||
SUM | |||||
SUMIF | |||||
SUMIFS | |||||
SUMPRODUCT | |||||
SUMSQ | |||||
SUMX2MY2 | |||||
SUMX2PY2 | |||||
SUMXMY2 | |||||
SYD | |||||
T | |||||
TAN | |||||
TANH | |||||
TBILLEQ | |||||
TBILLPRICE | |||||
TBILLYIELD | |||||
TDIST | |||||
TEXT | |||||
TIME | |||||
TIMEVALUE | |||||
TINV | |||||
TODAY | |||||
TRANSPOSE | |||||
TREND | |||||
TRIM | |||||
TRIMMEAN | |||||
TRUE | |||||
TRUNC | |||||
TTEST | |||||
TYPE | |||||
UPPER | |||||
USDOLLAR | |||||
VALUE | |||||
VAR | |||||
VARA | |||||
VARP | |||||
VARPA | |||||
VDB | |||||
VERSION | |||||
VLOOKUP | |||||
WEEKDAY | |||||
WEEKNUM | |||||
WEIBULL | |||||
WORKDAY | |||||
XIRR | |||||
XNPV | |||||
YEAR | |||||
YEARFRAC | |||||
YIELD | |||||
YIELDDISC | |||||
YIELDMAT | |||||
ZTEST |
@ -0,0 +1,187 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_Cell_AdvancedValueBinder | |||||
* | |||||
* 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_AdvancedValueBinder extends PHPExcel_Cell_DefaultValueBinder implements PHPExcel_Cell_IValueBinder | |||||
{ | |||||
/** | |||||
* Bind value to a cell | |||||
* | |||||
* @param PHPExcel_Cell $cell Cell to bind value to | |||||
* @param mixed $value Value to bind in cell | |||||
* @return boolean | |||||
*/ | |||||
public function bindValue(PHPExcel_Cell $cell, $value = null) | |||||
{ | |||||
// sanitize UTF-8 strings | |||||
if (is_string($value)) { | |||||
$value = PHPExcel_Shared_String::SanitizeUTF8($value); | |||||
} | |||||
// Find out data type | |||||
$dataType = parent::dataTypeForValue($value); | |||||
// Style logic - strings | |||||
if ($dataType === PHPExcel_Cell_DataType::TYPE_STRING && !$value instanceof PHPExcel_RichText) { | |||||
// Test for booleans using locale-setting | |||||
if ($value == PHPExcel_Calculation::getTRUE()) { | |||||
$cell->setValueExplicit(true, PHPExcel_Cell_DataType::TYPE_BOOL); | |||||
return true; | |||||
} elseif ($value == PHPExcel_Calculation::getFALSE()) { | |||||
$cell->setValueExplicit(false, PHPExcel_Cell_DataType::TYPE_BOOL); | |||||
return true; | |||||
} | |||||
// Check for number in scientific format | |||||
if (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NUMBER.'$/', $value)) { | |||||
$cell->setValueExplicit((float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
return true; | |||||
} | |||||
// Check for fraction | |||||
if (preg_match('/^([+-]?)\s*([0-9]+)\s?\/\s*([0-9]+)$/', $value, $matches)) { | |||||
// Convert value to number | |||||
$value = $matches[2] / $matches[3]; | |||||
if ($matches[1] == '-') { | |||||
$value = 0 - $value; | |||||
} | |||||
$cell->setValueExplicit((float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode('??/??'); | |||||
return true; | |||||
} elseif (preg_match('/^([+-]?)([0-9]*) +([0-9]*)\s?\/\s*([0-9]*)$/', $value, $matches)) { | |||||
// Convert value to number | |||||
$value = $matches[2] + ($matches[3] / $matches[4]); | |||||
if ($matches[1] == '-') { | |||||
$value = 0 - $value; | |||||
} | |||||
$cell->setValueExplicit((float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode('# ??/??'); | |||||
return true; | |||||
} | |||||
// Check for percentage | |||||
if (preg_match('/^\-?[0-9]*\.?[0-9]*\s?\%$/', $value)) { | |||||
// Convert value to number | |||||
$value = (float) str_replace('%', '', $value) / 100; | |||||
$cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00); | |||||
return true; | |||||
} | |||||
// Check for currency | |||||
$currencyCode = PHPExcel_Shared_String::getCurrencyCode(); | |||||
$decimalSeparator = PHPExcel_Shared_String::getDecimalSeparator(); | |||||
$thousandsSeparator = PHPExcel_Shared_String::getThousandsSeparator(); | |||||
if (preg_match('/^'.preg_quote($currencyCode).' *(\d{1,3}('.preg_quote($thousandsSeparator).'\d{3})*|(\d+))('.preg_quote($decimalSeparator).'\d{2})?$/', $value)) { | |||||
// Convert value to number | |||||
$value = (float) trim(str_replace(array($currencyCode, $thousandsSeparator, $decimalSeparator), array('', '', '.'), $value)); | |||||
$cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode( | |||||
str_replace('$', $currencyCode, PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE) | |||||
); | |||||
return true; | |||||
} elseif (preg_match('/^\$ *(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$/', $value)) { | |||||
// Convert value to number | |||||
$value = (float) trim(str_replace(array('$',','), '', $value)); | |||||
$cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE); | |||||
return true; | |||||
} | |||||
// Check for time without seconds e.g. '9:45', '09:45' | |||||
if (preg_match('/^(\d|[0-1]\d|2[0-3]):[0-5]\d$/', $value)) { | |||||
// Convert value to number | |||||
list($h, $m) = explode(':', $value); | |||||
$days = $h / 24 + $m / 1440; | |||||
$cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3); | |||||
return true; | |||||
} | |||||
// Check for time with seconds '9:45:59', '09:45:59' | |||||
if (preg_match('/^(\d|[0-1]\d|2[0-3]):[0-5]\d:[0-5]\d$/', $value)) { | |||||
// Convert value to number | |||||
list($h, $m, $s) = explode(':', $value); | |||||
$days = $h / 24 + $m / 1440 + $s / 86400; | |||||
// Convert value to number | |||||
$cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4); | |||||
return true; | |||||
} | |||||
// Check for datetime, e.g. '2008-12-31', '2008-12-31 15:59', '2008-12-31 15:59:10' | |||||
if (($d = PHPExcel_Shared_Date::stringToExcel($value)) !== false) { | |||||
// Convert value to number | |||||
$cell->setValueExplicit($d, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Determine style. Either there is a time part or not. Look for ':' | |||||
if (strpos($value, ':') !== false) { | |||||
$formatCode = 'yyyy-mm-dd h:mm'; | |||||
} else { | |||||
$formatCode = 'yyyy-mm-dd'; | |||||
} | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode($formatCode); | |||||
return true; | |||||
} | |||||
// Check for newline character "\n" | |||||
if (strpos($value, "\n") !== false) { | |||||
$value = PHPExcel_Shared_String::SanitizeUTF8($value); | |||||
$cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getAlignment()->setWrapText(true); | |||||
return true; | |||||
} | |||||
} | |||||
// Not bound yet? Use parent... | |||||
return parent::bindValue($cell, $value); | |||||
} | |||||
} |
@ -0,0 +1,187 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_Cell_AdvancedValueBinder | |||||
* | |||||
* 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_AdvancedValueBinder extends PHPExcel_Cell_DefaultValueBinder implements PHPExcel_Cell_IValueBinder | |||||
{ | |||||
/** | |||||
* Bind value to a cell | |||||
* | |||||
* @param PHPExcel_Cell $cell Cell to bind value to | |||||
* @param mixed $value Value to bind in cell | |||||
* @return boolean | |||||
*/ | |||||
public function bindValue(PHPExcel_Cell $cell, $value = null) | |||||
{ | |||||
// sanitize UTF-8 strings | |||||
if (is_string($value)) { | |||||
$value = PHPExcel_Shared_String::SanitizeUTF8($value); | |||||
} | |||||
// Find out data type | |||||
$dataType = parent::dataTypeForValue($value); | |||||
// Style logic - strings | |||||
if ($dataType === PHPExcel_Cell_DataType::TYPE_STRING && !$value instanceof PHPExcel_RichText) { | |||||
// Test for booleans using locale-setting | |||||
if ($value == PHPExcel_Calculation::getTRUE()) { | |||||
$cell->setValueExplicit(true, PHPExcel_Cell_DataType::TYPE_BOOL); | |||||
return true; | |||||
} elseif ($value == PHPExcel_Calculation::getFALSE()) { | |||||
$cell->setValueExplicit(false, PHPExcel_Cell_DataType::TYPE_BOOL); | |||||
return true; | |||||
} | |||||
// Check for number in scientific format | |||||
if (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NUMBER.'$/', $value)) { | |||||
$cell->setValueExplicit((float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
return true; | |||||
} | |||||
// Check for fraction | |||||
if (preg_match('/^([+-]?)\s*([0-9]+)\s?\/\s*([0-9]+)$/', $value, $matches)) { | |||||
// Convert value to number | |||||
$value = $matches[2] / $matches[3]; | |||||
if ($matches[1] == '-') { | |||||
$value = 0 - $value; | |||||
} | |||||
$cell->setValueExplicit((float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode('??/??'); | |||||
return true; | |||||
} elseif (preg_match('/^([+-]?)([0-9]*) +([0-9]*)\s?\/\s*([0-9]*)$/', $value, $matches)) { | |||||
// Convert value to number | |||||
$value = $matches[2] + ($matches[3] / $matches[4]); | |||||
if ($matches[1] == '-') { | |||||
$value = 0 - $value; | |||||
} | |||||
$cell->setValueExplicit((float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode('# ??/??'); | |||||
return true; | |||||
} | |||||
// Check for percentage | |||||
if (preg_match('/^\-?[0-9]*\.?[0-9]*\s?\%$/', $value)) { | |||||
// Convert value to number | |||||
$value = (float) str_replace('%', '', $value) / 100; | |||||
$cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00); | |||||
return true; | |||||
} | |||||
// Check for currency | |||||
$currencyCode = PHPExcel_Shared_String::getCurrencyCode(); | |||||
$decimalSeparator = PHPExcel_Shared_String::getDecimalSeparator(); | |||||
$thousandsSeparator = PHPExcel_Shared_String::getThousandsSeparator(); | |||||
if (preg_match('/^'.preg_quote($currencyCode).' *(\d{1,3}('.preg_quote($thousandsSeparator).'\d{3})*|(\d+))('.preg_quote($decimalSeparator).'\d{2})?$/', $value)) { | |||||
// Convert value to number | |||||
$value = (float) trim(str_replace(array($currencyCode, $thousandsSeparator, $decimalSeparator), array('', '', '.'), $value)); | |||||
$cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode( | |||||
str_replace('$', $currencyCode, PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE) | |||||
); | |||||
return true; | |||||
} elseif (preg_match('/^\$ *(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$/', $value)) { | |||||
// Convert value to number | |||||
$value = (float) trim(str_replace(array('$',','), '', $value)); | |||||
$cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE); | |||||
return true; | |||||
} | |||||
// Check for time without seconds e.g. '9:45', '09:45' | |||||
if (preg_match('/^(\d|[0-1]\d|2[0-3]):[0-5]\d$/', $value)) { | |||||
// Convert value to number | |||||
list($h, $m) = explode(':', $value); | |||||
$days = $h / 24 + $m / 1440; | |||||
$cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3); | |||||
return true; | |||||
} | |||||
// Check for time with seconds '9:45:59', '09:45:59' | |||||
if (preg_match('/^(\d|[0-1]\d|2[0-3]):[0-5]\d:[0-5]\d$/', $value)) { | |||||
// Convert value to number | |||||
list($h, $m, $s) = explode(':', $value); | |||||
$days = $h / 24 + $m / 1440 + $s / 86400; | |||||
// Convert value to number | |||||
$cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4); | |||||
return true; | |||||
} | |||||
// Check for datetime, e.g. '2008-12-31', '2008-12-31 15:59', '2008-12-31 15:59:10' | |||||
if (($d = PHPExcel_Shared_Date::stringToExcel($value)) !== false) { | |||||
// Convert value to number | |||||
$cell->setValueExplicit($d, PHPExcel_Cell_DataType::TYPE_NUMERIC); | |||||
// Determine style. Either there is a time part or not. Look for ':' | |||||
if (strpos($value, ':') !== false) { | |||||
$formatCode = 'yyyy-mm-dd h:mm'; | |||||
} else { | |||||
$formatCode = 'yyyy-mm-dd'; | |||||
} | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getNumberFormat()->setFormatCode($formatCode); | |||||
return true; | |||||
} | |||||
// Check for newline character "\n" | |||||
if (strpos($value, "\n") !== false) { | |||||
$value = PHPExcel_Shared_String::SanitizeUTF8($value); | |||||
$cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); | |||||
// Set style | |||||
$cell->getWorksheet()->getStyle($cell->getCoordinate()) | |||||
->getAlignment()->setWrapText(true); | |||||
return true; | |||||
} | |||||
} | |||||
// Not bound yet? Use parent... | |||||
return parent::bindValue($cell, $value); | |||||
} | |||||
} |
@ -0,0 +1,115 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Cell_DataType | |||||
* | |||||
* 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_DataType | |||||
{ | |||||
/* Data types */ | |||||
const TYPE_STRING2 = 'str'; | |||||
const TYPE_STRING = 's'; | |||||
const TYPE_FORMULA = 'f'; | |||||
const TYPE_NUMERIC = 'n'; | |||||
const TYPE_BOOL = 'b'; | |||||
const TYPE_NULL = 'null'; | |||||
const TYPE_INLINE = 'inlineStr'; | |||||
const TYPE_ERROR = 'e'; | |||||
/** | |||||
* List of error codes | |||||
* | |||||
* @var array | |||||
*/ | |||||
private static $errorCodes = array( | |||||
'#NULL!' => 0, | |||||
'#DIV/0!' => 1, | |||||
'#VALUE!' => 2, | |||||
'#REF!' => 3, | |||||
'#NAME?' => 4, | |||||
'#NUM!' => 5, | |||||
'#N/A' => 6 | |||||
); | |||||
/** | |||||
* Get list of error codes | |||||
* | |||||
* @return array | |||||
*/ | |||||
public static function getErrorCodes() | |||||
{ | |||||
return self::$errorCodes; | |||||
} | |||||
/** | |||||
* DataType for value | |||||
* | |||||
* @deprecated Replaced by PHPExcel_Cell_IValueBinder infrastructure, will be removed in version 1.8.0 | |||||
* @param mixed $pValue | |||||
* @return string | |||||
*/ | |||||
public static function dataTypeForValue($pValue = null) | |||||
{ | |||||
return PHPExcel_Cell_DefaultValueBinder::dataTypeForValue($pValue); | |||||
} | |||||
/** | |||||
* Check a string that it satisfies Excel requirements | |||||
* | |||||
* @param mixed Value to sanitize to an Excel string | |||||
* @return mixed Sanitized value | |||||
*/ | |||||
public static function checkString($pValue = null) | |||||
{ | |||||
if ($pValue instanceof PHPExcel_RichText) { | |||||
// TODO: Sanitize Rich-Text string (max. character count is 32,767) | |||||
return $pValue; | |||||
} | |||||
// string must never be longer than 32,767 characters, truncate if necessary | |||||
$pValue = PHPExcel_Shared_String::Substring($pValue, 0, 32767); | |||||
// we require that newline is represented as "\n" in core, not as "\r\n" or "\r" | |||||
$pValue = str_replace(array("\r\n", "\r"), "\n", $pValue); | |||||
return $pValue; | |||||
} | |||||
/** | |||||
* Check a value that it is a valid error code | |||||
* | |||||
* @param mixed Value to sanitize to an Excel error code | |||||
* @return string Sanitized value | |||||
*/ | |||||
public static function checkErrorCode($pValue = null) | |||||
{ | |||||
$pValue = (string) $pValue; | |||||
if (!array_key_exists($pValue, self::$errorCodes)) { | |||||
$pValue = '#NULL!'; | |||||
} | |||||
return $pValue; | |||||
} | |||||
} |
@ -0,0 +1,492 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Cell_DataValidation | |||||
* | |||||
* 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_DataValidation | |||||
{ | |||||
/* Data validation types */ | |||||
const TYPE_NONE = 'none'; | |||||
const TYPE_CUSTOM = 'custom'; | |||||
const TYPE_DATE = 'date'; | |||||
const TYPE_DECIMAL = 'decimal'; | |||||
const TYPE_LIST = 'list'; | |||||
const TYPE_TEXTLENGTH = 'textLength'; | |||||
const TYPE_TIME = 'time'; | |||||
const TYPE_WHOLE = 'whole'; | |||||
/* Data validation error styles */ | |||||
const STYLE_STOP = 'stop'; | |||||
const STYLE_WARNING = 'warning'; | |||||
const STYLE_INFORMATION = 'information'; | |||||
/* Data validation operators */ | |||||
const OPERATOR_BETWEEN = 'between'; | |||||
const OPERATOR_EQUAL = 'equal'; | |||||
const OPERATOR_GREATERTHAN = 'greaterThan'; | |||||
const OPERATOR_GREATERTHANOREQUAL = 'greaterThanOrEqual'; | |||||
const OPERATOR_LESSTHAN = 'lessThan'; | |||||
const OPERATOR_LESSTHANOREQUAL = 'lessThanOrEqual'; | |||||
const OPERATOR_NOTBETWEEN = 'notBetween'; | |||||
const OPERATOR_NOTEQUAL = 'notEqual'; | |||||
/** | |||||
* Formula 1 | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $formula1; | |||||
/** | |||||
* Formula 2 | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $formula2; | |||||
/** | |||||
* Type | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $type = PHPExcel_Cell_DataValidation::TYPE_NONE; | |||||
/** | |||||
* Error style | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; | |||||
/** | |||||
* Operator | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $operator; | |||||
/** | |||||
* Allow Blank | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $allowBlank; | |||||
/** | |||||
* Show DropDown | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $showDropDown; | |||||
/** | |||||
* Show InputMessage | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $showInputMessage; | |||||
/** | |||||
* Show ErrorMessage | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $showErrorMessage; | |||||
/** | |||||
* Error title | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $errorTitle; | |||||
/** | |||||
* Error | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $error; | |||||
/** | |||||
* Prompt title | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $promptTitle; | |||||
/** | |||||
* Prompt | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $prompt; | |||||
/** | |||||
* Create a new PHPExcel_Cell_DataValidation | |||||
*/ | |||||
public function __construct() | |||||
{ | |||||
// Initialise member variables | |||||
$this->formula1 = ''; | |||||
$this->formula2 = ''; | |||||
$this->type = PHPExcel_Cell_DataValidation::TYPE_NONE; | |||||
$this->errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; | |||||
$this->operator = ''; | |||||
$this->allowBlank = false; | |||||
$this->showDropDown = false; | |||||
$this->showInputMessage = false; | |||||
$this->showErrorMessage = false; | |||||
$this->errorTitle = ''; | |||||
$this->error = ''; | |||||
$this->promptTitle = ''; | |||||
$this->prompt = ''; | |||||
} | |||||
/** | |||||
* Get Formula 1 | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getFormula1() | |||||
{ | |||||
return $this->formula1; | |||||
} | |||||
/** | |||||
* Set Formula 1 | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_Cell_DataValidation | |||||
*/ | |||||
public function setFormula1($value = '') | |||||
{ | |||||
$this->formula1 = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Formula 2 | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getFormula2() | |||||
{ | |||||
return $this->formula2; | |||||
} | |||||
/** | |||||
* Set Formula 2 | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_Cell_DataValidation | |||||
*/ | |||||
public function setFormula2($value = '') | |||||
{ | |||||
$this->formula2 = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Type | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getType() | |||||
{ | |||||
return $this->type; | |||||
} | |||||
/** | |||||
* Set Type | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_Cell_DataValidation | |||||
*/ | |||||
public function setType($value = PHPExcel_Cell_DataValidation::TYPE_NONE) | |||||
{ | |||||
$this->type = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Error style | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getErrorStyle() | |||||
{ | |||||
return $this->errorStyle; | |||||
} | |||||
/** | |||||
* Set Error style | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_Cell_DataValidation | |||||
*/ | |||||
public function setErrorStyle($value = PHPExcel_Cell_DataValidation::STYLE_STOP) | |||||
{ | |||||
$this->errorStyle = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Operator | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getOperator() | |||||
{ | |||||
return $this->operator; | |||||
} | |||||
/** | |||||
* Set Operator | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_Cell_DataValidation | |||||
*/ | |||||
public function setOperator($value = '') | |||||
{ | |||||
$this->operator = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Allow Blank | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getAllowBlank() | |||||
{ | |||||
return $this->allowBlank; | |||||
} | |||||
/** | |||||
* Set Allow Blank | |||||
* | |||||
* @param boolean $value | |||||
* @return PHPExcel_Cell_DataValidation | |||||
*/ | |||||
public function setAllowBlank($value = false) | |||||
{ | |||||
$this->allowBlank = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Show DropDown | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getShowDropDown() | |||||
{ | |||||
return $this->showDropDown; | |||||
} | |||||
/** | |||||
* Set Show DropDown | |||||
* | |||||
* @param boolean $value | |||||
* @return PHPExcel_Cell_DataValidation | |||||
*/ | |||||
public function setShowDropDown($value = false) | |||||
{ | |||||
$this->showDropDown = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Show InputMessage | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getShowInputMessage() | |||||
{ | |||||
return $this->showInputMessage; | |||||
} | |||||
/** | |||||
* Set Show InputMessage | |||||
* | |||||
* @param boolean $value | |||||
* @return PHPExcel_Cell_DataValidation | |||||
*/ | |||||
public function setShowInputMessage($value = false) | |||||
{ | |||||
$this->showInputMessage = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Show ErrorMessage | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getShowErrorMessage() | |||||
{ | |||||
return $this->showErrorMessage; | |||||
} | |||||
/** | |||||
* Set Show ErrorMessage | |||||
* | |||||
* @param boolean $value | |||||
* @return PHPExcel_Cell_DataValidation | |||||
*/ | |||||
public function setShowErrorMessage($value = false) | |||||
{ | |||||
$this->showErrorMessage = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Error title | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getErrorTitle() | |||||
{ | |||||
return $this->errorTitle; | |||||
} | |||||
/** | |||||
* Set Error title | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_Cell_DataValidation | |||||
*/ | |||||
public function setErrorTitle($value = '') | |||||
{ | |||||
$this->errorTitle = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Error | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getError() | |||||
{ | |||||
return $this->error; | |||||
} | |||||
/** | |||||
* Set Error | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_Cell_DataValidation | |||||
*/ | |||||
public function setError($value = '') | |||||
{ | |||||
$this->error = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Prompt title | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getPromptTitle() | |||||
{ | |||||
return $this->promptTitle; | |||||
} | |||||
/** | |||||
* Set Prompt title | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_Cell_DataValidation | |||||
*/ | |||||
public function setPromptTitle($value = '') | |||||
{ | |||||
$this->promptTitle = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Prompt | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getPrompt() | |||||
{ | |||||
return $this->prompt; | |||||
} | |||||
/** | |||||
* Set Prompt | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_Cell_DataValidation | |||||
*/ | |||||
public function setPrompt($value = '') | |||||
{ | |||||
$this->prompt = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get hash code | |||||
* | |||||
* @return string Hash code | |||||
*/ | |||||
public function getHashCode() | |||||
{ | |||||
return md5( | |||||
$this->formula1 . | |||||
$this->formula2 . | |||||
$this->type = PHPExcel_Cell_DataValidation::TYPE_NONE . | |||||
$this->errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP . | |||||
$this->operator . | |||||
($this->allowBlank ? 't' : 'f') . | |||||
($this->showDropDown ? 't' : 'f') . | |||||
($this->showInputMessage ? 't' : 'f') . | |||||
($this->showErrorMessage ? 't' : 'f') . | |||||
$this->errorTitle . | |||||
$this->error . | |||||
$this->promptTitle . | |||||
$this->prompt . | |||||
__CLASS__ | |||||
); | |||||
} | |||||
/** | |||||
* Implement PHP __clone to create a deep clone, not just a shallow copy. | |||||
*/ | |||||
public function __clone() | |||||
{ | |||||
$vars = get_object_vars($this); | |||||
foreach ($vars as $key => $value) { | |||||
if (is_object($value)) { | |||||
$this->$key = clone $value; | |||||
} else { | |||||
$this->$key = $value; | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,102 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_Cell_DefaultValueBinder | |||||
* | |||||
* 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_DefaultValueBinder implements PHPExcel_Cell_IValueBinder | |||||
{ | |||||
/** | |||||
* Bind value to a cell | |||||
* | |||||
* @param PHPExcel_Cell $cell Cell to bind value to | |||||
* @param mixed $value Value to bind in cell | |||||
* @return boolean | |||||
*/ | |||||
public function bindValue(PHPExcel_Cell $cell, $value = null) | |||||
{ | |||||
// sanitize UTF-8 strings | |||||
if (is_string($value)) { | |||||
$value = PHPExcel_Shared_String::SanitizeUTF8($value); | |||||
} elseif (is_object($value)) { | |||||
// Handle any objects that might be injected | |||||
if ($value instanceof DateTime) { | |||||
$value = $value->format('Y-m-d H:i:s'); | |||||
} elseif (!($value instanceof PHPExcel_RichText)) { | |||||
$value = (string) $value; | |||||
} | |||||
} | |||||
// Set value explicit | |||||
$cell->setValueExplicit($value, self::dataTypeForValue($value)); | |||||
// Done! | |||||
return true; | |||||
} | |||||
/** | |||||
* DataType for value | |||||
* | |||||
* @param mixed $pValue | |||||
* @return string | |||||
*/ | |||||
public static function dataTypeForValue($pValue = null) | |||||
{ | |||||
// Match the value against a few data types | |||||
if ($pValue === null) { | |||||
return PHPExcel_Cell_DataType::TYPE_NULL; | |||||
} elseif ($pValue === '') { | |||||
return PHPExcel_Cell_DataType::TYPE_STRING; | |||||
} elseif ($pValue instanceof PHPExcel_RichText) { | |||||
return PHPExcel_Cell_DataType::TYPE_INLINE; | |||||
} elseif ($pValue[0] === '=' && strlen($pValue) > 1) { | |||||
return PHPExcel_Cell_DataType::TYPE_FORMULA; | |||||
} elseif (is_bool($pValue)) { | |||||
return PHPExcel_Cell_DataType::TYPE_BOOL; | |||||
} elseif (is_float($pValue) || is_int($pValue)) { | |||||
return PHPExcel_Cell_DataType::TYPE_NUMERIC; | |||||
} elseif (preg_match('/^[\+\-]?([0-9]+\\.?[0-9]*|[0-9]*\\.?[0-9]+)([Ee][\-\+]?[0-2]?\d{1,3})?$/', $pValue)) { | |||||
$tValue = ltrim($pValue, '+-'); | |||||
if (is_string($pValue) && $tValue[0] === '0' && strlen($tValue) > 1 && $tValue[1] !== '.') { | |||||
return PHPExcel_Cell_DataType::TYPE_STRING; | |||||
} elseif ((strpos($pValue, '.') === false) && ($pValue > PHP_INT_MAX)) { | |||||
return PHPExcel_Cell_DataType::TYPE_STRING; | |||||
} | |||||
return PHPExcel_Cell_DataType::TYPE_NUMERIC; | |||||
} elseif (is_string($pValue) && array_key_exists($pValue, PHPExcel_Cell_DataType::getErrorCodes())) { | |||||
return PHPExcel_Cell_DataType::TYPE_ERROR; | |||||
} | |||||
return PHPExcel_Cell_DataType::TYPE_STRING; | |||||
} | |||||
} |
@ -0,0 +1,102 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_Cell_DefaultValueBinder | |||||
* | |||||
* 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_DefaultValueBinder implements PHPExcel_Cell_IValueBinder | |||||
{ | |||||
/** | |||||
* Bind value to a cell | |||||
* | |||||
* @param PHPExcel_Cell $cell Cell to bind value to | |||||
* @param mixed $value Value to bind in cell | |||||
* @return boolean | |||||
*/ | |||||
public function bindValue(PHPExcel_Cell $cell, $value = null) | |||||
{ | |||||
// sanitize UTF-8 strings | |||||
if (is_string($value)) { | |||||
$value = PHPExcel_Shared_String::SanitizeUTF8($value); | |||||
} elseif (is_object($value)) { | |||||
// Handle any objects that might be injected | |||||
if ($value instanceof DateTime) { | |||||
$value = $value->format('Y-m-d H:i:s'); | |||||
} elseif (!($value instanceof PHPExcel_RichText)) { | |||||
$value = (string) $value; | |||||
} | |||||
} | |||||
// Set value explicit | |||||
$cell->setValueExplicit($value, self::dataTypeForValue($value)); | |||||
// Done! | |||||
return true; | |||||
} | |||||
/** | |||||
* DataType for value | |||||
* | |||||
* @param mixed $pValue | |||||
* @return string | |||||
*/ | |||||
public static function dataTypeForValue($pValue = null) | |||||
{ | |||||
// Match the value against a few data types | |||||
if ($pValue === null) { | |||||
return PHPExcel_Cell_DataType::TYPE_NULL; | |||||
} elseif ($pValue === '') { | |||||
return PHPExcel_Cell_DataType::TYPE_STRING; | |||||
} elseif ($pValue instanceof PHPExcel_RichText) { | |||||
return PHPExcel_Cell_DataType::TYPE_INLINE; | |||||
} elseif ($pValue{0} === '=' && strlen($pValue) > 1) { | |||||
return PHPExcel_Cell_DataType::TYPE_FORMULA; | |||||
} elseif (is_bool($pValue)) { | |||||
return PHPExcel_Cell_DataType::TYPE_BOOL; | |||||
} elseif (is_float($pValue) || is_int($pValue)) { | |||||
return PHPExcel_Cell_DataType::TYPE_NUMERIC; | |||||
} elseif (preg_match('/^[\+\-]?([0-9]+\\.?[0-9]*|[0-9]*\\.?[0-9]+)([Ee][\-\+]?[0-2]?\d{1,3})?$/', $pValue)) { | |||||
$tValue = ltrim($pValue, '+-'); | |||||
if (is_string($pValue) && $tValue{0} === '0' && strlen($tValue) > 1 && $tValue{1} !== '.') { | |||||
return PHPExcel_Cell_DataType::TYPE_STRING; | |||||
} elseif ((strpos($pValue, '.') === false) && ($pValue > PHP_INT_MAX)) { | |||||
return PHPExcel_Cell_DataType::TYPE_STRING; | |||||
} | |||||
return PHPExcel_Cell_DataType::TYPE_NUMERIC; | |||||
} elseif (is_string($pValue) && array_key_exists($pValue, PHPExcel_Cell_DataType::getErrorCodes())) { | |||||
return PHPExcel_Cell_DataType::TYPE_ERROR; | |||||
} | |||||
return PHPExcel_Cell_DataType::TYPE_STRING; | |||||
} | |||||
} |
@ -0,0 +1,124 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Cell_Hyperlink | |||||
* | |||||
* 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_Hyperlink | |||||
{ | |||||
/** | |||||
* URL to link the cell to | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $url; | |||||
/** | |||||
* Tooltip to display on the hyperlink | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $tooltip; | |||||
/** | |||||
* Create a new PHPExcel_Cell_Hyperlink | |||||
* | |||||
* @param string $pUrl Url to link the cell to | |||||
* @param string $pTooltip Tooltip to display on the hyperlink | |||||
*/ | |||||
public function __construct($pUrl = '', $pTooltip = '') | |||||
{ | |||||
// Initialise member variables | |||||
$this->url = $pUrl; | |||||
$this->tooltip = $pTooltip; | |||||
} | |||||
/** | |||||
* Get URL | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getUrl() | |||||
{ | |||||
return $this->url; | |||||
} | |||||
/** | |||||
* Set URL | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_Cell_Hyperlink | |||||
*/ | |||||
public function setUrl($value = '') | |||||
{ | |||||
$this->url = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get tooltip | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getTooltip() | |||||
{ | |||||
return $this->tooltip; | |||||
} | |||||
/** | |||||
* Set tooltip | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_Cell_Hyperlink | |||||
*/ | |||||
public function setTooltip($value = '') | |||||
{ | |||||
$this->tooltip = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Is this hyperlink internal? (to another worksheet) | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function isInternal() | |||||
{ | |||||
return strpos($this->url, 'sheet://') !== false; | |||||
} | |||||
/** | |||||
* Get hash code | |||||
* | |||||
* @return string Hash code | |||||
*/ | |||||
public function getHashCode() | |||||
{ | |||||
return md5( | |||||
$this->url . | |||||
$this->tooltip . | |||||
__CLASS__ | |||||
); | |||||
} | |||||
} |
@ -0,0 +1,47 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel | |||||
* | |||||
* 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## | |||||
*/ | |||||
/** | |||||
* PHPExcel_Cell_IValueBinder | |||||
* | |||||
* @category PHPExcel | |||||
* @package PHPExcel_Cell | |||||
* @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | |||||
*/ | |||||
interface PHPExcel_Cell_IValueBinder | |||||
{ | |||||
/** | |||||
* Bind value to a cell | |||||
* | |||||
* @param PHPExcel_Cell $cell Cell to bind value to | |||||
* @param mixed $value Value to bind in cell | |||||
* @return boolean | |||||
*/ | |||||
public function bindValue(PHPExcel_Cell $cell, $value = null); | |||||
} |
@ -0,0 +1,680 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Chart | |||||
* | |||||
* 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_Chart | |||||
* @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_Chart | |||||
{ | |||||
/** | |||||
* Chart Name | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $name = ''; | |||||
/** | |||||
* Worksheet | |||||
* | |||||
* @var PHPExcel_Worksheet | |||||
*/ | |||||
private $worksheet; | |||||
/** | |||||
* Chart Title | |||||
* | |||||
* @var PHPExcel_Chart_Title | |||||
*/ | |||||
private $title; | |||||
/** | |||||
* Chart Legend | |||||
* | |||||
* @var PHPExcel_Chart_Legend | |||||
*/ | |||||
private $legend; | |||||
/** | |||||
* X-Axis Label | |||||
* | |||||
* @var PHPExcel_Chart_Title | |||||
*/ | |||||
private $xAxisLabel; | |||||
/** | |||||
* Y-Axis Label | |||||
* | |||||
* @var PHPExcel_Chart_Title | |||||
*/ | |||||
private $yAxisLabel; | |||||
/** | |||||
* Chart Plot Area | |||||
* | |||||
* @var PHPExcel_Chart_PlotArea | |||||
*/ | |||||
private $plotArea; | |||||
/** | |||||
* Plot Visible Only | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $plotVisibleOnly = true; | |||||
/** | |||||
* Display Blanks as | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $displayBlanksAs = '0'; | |||||
/** | |||||
* Chart Asix Y as | |||||
* | |||||
* @var PHPExcel_Chart_Axis | |||||
*/ | |||||
private $yAxis; | |||||
/** | |||||
* Chart Asix X as | |||||
* | |||||
* @var PHPExcel_Chart_Axis | |||||
*/ | |||||
private $xAxis; | |||||
/** | |||||
* Chart Major Gridlines as | |||||
* | |||||
* @var PHPExcel_Chart_GridLines | |||||
*/ | |||||
private $majorGridlines; | |||||
/** | |||||
* Chart Minor Gridlines as | |||||
* | |||||
* @var PHPExcel_Chart_GridLines | |||||
*/ | |||||
private $minorGridlines; | |||||
/** | |||||
* Top-Left Cell Position | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $topLeftCellRef = 'A1'; | |||||
/** | |||||
* Top-Left X-Offset | |||||
* | |||||
* @var integer | |||||
*/ | |||||
private $topLeftXOffset = 0; | |||||
/** | |||||
* Top-Left Y-Offset | |||||
* | |||||
* @var integer | |||||
*/ | |||||
private $topLeftYOffset = 0; | |||||
/** | |||||
* Bottom-Right Cell Position | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $bottomRightCellRef = 'A1'; | |||||
/** | |||||
* Bottom-Right X-Offset | |||||
* | |||||
* @var integer | |||||
*/ | |||||
private $bottomRightXOffset = 10; | |||||
/** | |||||
* Bottom-Right Y-Offset | |||||
* | |||||
* @var integer | |||||
*/ | |||||
private $bottomRightYOffset = 10; | |||||
/** | |||||
* Create a new PHPExcel_Chart | |||||
*/ | |||||
public function __construct($name, PHPExcel_Chart_Title $title = null, PHPExcel_Chart_Legend $legend = null, PHPExcel_Chart_PlotArea $plotArea = null, $plotVisibleOnly = true, $displayBlanksAs = '0', PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null, PHPExcel_Chart_Axis $xAxis = null, PHPExcel_Chart_Axis $yAxis = null, PHPExcel_Chart_GridLines $majorGridlines = null, PHPExcel_Chart_GridLines $minorGridlines = null) | |||||
{ | |||||
$this->name = $name; | |||||
$this->title = $title; | |||||
$this->legend = $legend; | |||||
$this->xAxisLabel = $xAxisLabel; | |||||
$this->yAxisLabel = $yAxisLabel; | |||||
$this->plotArea = $plotArea; | |||||
$this->plotVisibleOnly = $plotVisibleOnly; | |||||
$this->displayBlanksAs = $displayBlanksAs; | |||||
$this->xAxis = $xAxis; | |||||
$this->yAxis = $yAxis; | |||||
$this->majorGridlines = $majorGridlines; | |||||
$this->minorGridlines = $minorGridlines; | |||||
} | |||||
/** | |||||
* Get Name | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getName() | |||||
{ | |||||
return $this->name; | |||||
} | |||||
/** | |||||
* Get Worksheet | |||||
* | |||||
* @return PHPExcel_Worksheet | |||||
*/ | |||||
public function getWorksheet() | |||||
{ | |||||
return $this->worksheet; | |||||
} | |||||
/** | |||||
* Set Worksheet | |||||
* | |||||
* @param PHPExcel_Worksheet $pValue | |||||
* @throws PHPExcel_Chart_Exception | |||||
* @return PHPExcel_Chart | |||||
*/ | |||||
public function setWorksheet(PHPExcel_Worksheet $pValue = null) | |||||
{ | |||||
$this->worksheet = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Title | |||||
* | |||||
* @return PHPExcel_Chart_Title | |||||
*/ | |||||
public function getTitle() | |||||
{ | |||||
return $this->title; | |||||
} | |||||
/** | |||||
* Set Title | |||||
* | |||||
* @param PHPExcel_Chart_Title $title | |||||
* @return PHPExcel_Chart | |||||
*/ | |||||
public function setTitle(PHPExcel_Chart_Title $title) | |||||
{ | |||||
$this->title = $title; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Legend | |||||
* | |||||
* @return PHPExcel_Chart_Legend | |||||
*/ | |||||
public function getLegend() | |||||
{ | |||||
return $this->legend; | |||||
} | |||||
/** | |||||
* Set Legend | |||||
* | |||||
* @param PHPExcel_Chart_Legend $legend | |||||
* @return PHPExcel_Chart | |||||
*/ | |||||
public function setLegend(PHPExcel_Chart_Legend $legend) | |||||
{ | |||||
$this->legend = $legend; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get X-Axis Label | |||||
* | |||||
* @return PHPExcel_Chart_Title | |||||
*/ | |||||
public function getXAxisLabel() | |||||
{ | |||||
return $this->xAxisLabel; | |||||
} | |||||
/** | |||||
* Set X-Axis Label | |||||
* | |||||
* @param PHPExcel_Chart_Title $label | |||||
* @return PHPExcel_Chart | |||||
*/ | |||||
public function setXAxisLabel(PHPExcel_Chart_Title $label) | |||||
{ | |||||
$this->xAxisLabel = $label; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Y-Axis Label | |||||
* | |||||
* @return PHPExcel_Chart_Title | |||||
*/ | |||||
public function getYAxisLabel() | |||||
{ | |||||
return $this->yAxisLabel; | |||||
} | |||||
/** | |||||
* Set Y-Axis Label | |||||
* | |||||
* @param PHPExcel_Chart_Title $label | |||||
* @return PHPExcel_Chart | |||||
*/ | |||||
public function setYAxisLabel(PHPExcel_Chart_Title $label) | |||||
{ | |||||
$this->yAxisLabel = $label; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Plot Area | |||||
* | |||||
* @return PHPExcel_Chart_PlotArea | |||||
*/ | |||||
public function getPlotArea() | |||||
{ | |||||
return $this->plotArea; | |||||
} | |||||
/** | |||||
* Get Plot Visible Only | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getPlotVisibleOnly() | |||||
{ | |||||
return $this->plotVisibleOnly; | |||||
} | |||||
/** | |||||
* Set Plot Visible Only | |||||
* | |||||
* @param boolean $plotVisibleOnly | |||||
* @return PHPExcel_Chart | |||||
*/ | |||||
public function setPlotVisibleOnly($plotVisibleOnly = true) | |||||
{ | |||||
$this->plotVisibleOnly = $plotVisibleOnly; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Display Blanks as | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getDisplayBlanksAs() | |||||
{ | |||||
return $this->displayBlanksAs; | |||||
} | |||||
/** | |||||
* Set Display Blanks as | |||||
* | |||||
* @param string $displayBlanksAs | |||||
* @return PHPExcel_Chart | |||||
*/ | |||||
public function setDisplayBlanksAs($displayBlanksAs = '0') | |||||
{ | |||||
$this->displayBlanksAs = $displayBlanksAs; | |||||
} | |||||
/** | |||||
* Get yAxis | |||||
* | |||||
* @return PHPExcel_Chart_Axis | |||||
*/ | |||||
public function getChartAxisY() | |||||
{ | |||||
if ($this->yAxis !== null) { | |||||
return $this->yAxis; | |||||
} | |||||
return new PHPExcel_Chart_Axis(); | |||||
} | |||||
/** | |||||
* Get xAxis | |||||
* | |||||
* @return PHPExcel_Chart_Axis | |||||
*/ | |||||
public function getChartAxisX() | |||||
{ | |||||
if ($this->xAxis !== null) { | |||||
return $this->xAxis; | |||||
} | |||||
return new PHPExcel_Chart_Axis(); | |||||
} | |||||
/** | |||||
* Get Major Gridlines | |||||
* | |||||
* @return PHPExcel_Chart_GridLines | |||||
*/ | |||||
public function getMajorGridlines() | |||||
{ | |||||
if ($this->majorGridlines !== null) { | |||||
return $this->majorGridlines; | |||||
} | |||||
return new PHPExcel_Chart_GridLines(); | |||||
} | |||||
/** | |||||
* Get Minor Gridlines | |||||
* | |||||
* @return PHPExcel_Chart_GridLines | |||||
*/ | |||||
public function getMinorGridlines() | |||||
{ | |||||
if ($this->minorGridlines !== null) { | |||||
return $this->minorGridlines; | |||||
} | |||||
return new PHPExcel_Chart_GridLines(); | |||||
} | |||||
/** | |||||
* Set the Top Left position for the chart | |||||
* | |||||
* @param string $cell | |||||
* @param integer $xOffset | |||||
* @param integer $yOffset | |||||
* @return PHPExcel_Chart | |||||
*/ | |||||
public function setTopLeftPosition($cell, $xOffset = null, $yOffset = null) | |||||
{ | |||||
$this->topLeftCellRef = $cell; | |||||
if (!is_null($xOffset)) { | |||||
$this->setTopLeftXOffset($xOffset); | |||||
} | |||||
if (!is_null($yOffset)) { | |||||
$this->setTopLeftYOffset($yOffset); | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get the top left position of the chart | |||||
* | |||||
* @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell | |||||
*/ | |||||
public function getTopLeftPosition() | |||||
{ | |||||
return array( | |||||
'cell' => $this->topLeftCellRef, | |||||
'xOffset' => $this->topLeftXOffset, | |||||
'yOffset' => $this->topLeftYOffset | |||||
); | |||||
} | |||||
/** | |||||
* Get the cell address where the top left of the chart is fixed | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getTopLeftCell() | |||||
{ | |||||
return $this->topLeftCellRef; | |||||
} | |||||
/** | |||||
* Set the Top Left cell position for the chart | |||||
* | |||||
* @param string $cell | |||||
* @return PHPExcel_Chart | |||||
*/ | |||||
public function setTopLeftCell($cell) | |||||
{ | |||||
$this->topLeftCellRef = $cell; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set the offset position within the Top Left cell for the chart | |||||
* | |||||
* @param integer $xOffset | |||||
* @param integer $yOffset | |||||
* @return PHPExcel_Chart | |||||
*/ | |||||
public function setTopLeftOffset($xOffset = null, $yOffset = null) | |||||
{ | |||||
if (!is_null($xOffset)) { | |||||
$this->setTopLeftXOffset($xOffset); | |||||
} | |||||
if (!is_null($yOffset)) { | |||||
$this->setTopLeftYOffset($yOffset); | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get the offset position within the Top Left cell for the chart | |||||
* | |||||
* @return integer[] | |||||
*/ | |||||
public function getTopLeftOffset() | |||||
{ | |||||
return array( | |||||
'X' => $this->topLeftXOffset, | |||||
'Y' => $this->topLeftYOffset | |||||
); | |||||
} | |||||
public function setTopLeftXOffset($xOffset) | |||||
{ | |||||
$this->topLeftXOffset = $xOffset; | |||||
return $this; | |||||
} | |||||
public function getTopLeftXOffset() | |||||
{ | |||||
return $this->topLeftXOffset; | |||||
} | |||||
public function setTopLeftYOffset($yOffset) | |||||
{ | |||||
$this->topLeftYOffset = $yOffset; | |||||
return $this; | |||||
} | |||||
public function getTopLeftYOffset() | |||||
{ | |||||
return $this->topLeftYOffset; | |||||
} | |||||
/** | |||||
* Set the Bottom Right position of the chart | |||||
* | |||||
* @param string $cell | |||||
* @param integer $xOffset | |||||
* @param integer $yOffset | |||||
* @return PHPExcel_Chart | |||||
*/ | |||||
public function setBottomRightPosition($cell, $xOffset = null, $yOffset = null) | |||||
{ | |||||
$this->bottomRightCellRef = $cell; | |||||
if (!is_null($xOffset)) { | |||||
$this->setBottomRightXOffset($xOffset); | |||||
} | |||||
if (!is_null($yOffset)) { | |||||
$this->setBottomRightYOffset($yOffset); | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get the bottom right position of the chart | |||||
* | |||||
* @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell | |||||
*/ | |||||
public function getBottomRightPosition() | |||||
{ | |||||
return array( | |||||
'cell' => $this->bottomRightCellRef, | |||||
'xOffset' => $this->bottomRightXOffset, | |||||
'yOffset' => $this->bottomRightYOffset | |||||
); | |||||
} | |||||
public function setBottomRightCell($cell) | |||||
{ | |||||
$this->bottomRightCellRef = $cell; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get the cell address where the bottom right of the chart is fixed | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getBottomRightCell() | |||||
{ | |||||
return $this->bottomRightCellRef; | |||||
} | |||||
/** | |||||
* Set the offset position within the Bottom Right cell for the chart | |||||
* | |||||
* @param integer $xOffset | |||||
* @param integer $yOffset | |||||
* @return PHPExcel_Chart | |||||
*/ | |||||
public function setBottomRightOffset($xOffset = null, $yOffset = null) | |||||
{ | |||||
if (!is_null($xOffset)) { | |||||
$this->setBottomRightXOffset($xOffset); | |||||
} | |||||
if (!is_null($yOffset)) { | |||||
$this->setBottomRightYOffset($yOffset); | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get the offset position within the Bottom Right cell for the chart | |||||
* | |||||
* @return integer[] | |||||
*/ | |||||
public function getBottomRightOffset() | |||||
{ | |||||
return array( | |||||
'X' => $this->bottomRightXOffset, | |||||
'Y' => $this->bottomRightYOffset | |||||
); | |||||
} | |||||
public function setBottomRightXOffset($xOffset) | |||||
{ | |||||
$this->bottomRightXOffset = $xOffset; | |||||
return $this; | |||||
} | |||||
public function getBottomRightXOffset() | |||||
{ | |||||
return $this->bottomRightXOffset; | |||||
} | |||||
public function setBottomRightYOffset($yOffset) | |||||
{ | |||||
$this->bottomRightYOffset = $yOffset; | |||||
return $this; | |||||
} | |||||
public function getBottomRightYOffset() | |||||
{ | |||||
return $this->bottomRightYOffset; | |||||
} | |||||
public function refresh() | |||||
{ | |||||
if ($this->worksheet !== null) { | |||||
$this->plotArea->refresh($this->worksheet); | |||||
} | |||||
} | |||||
public function render($outputDestination = null) | |||||
{ | |||||
$libraryName = PHPExcel_Settings::getChartRendererName(); | |||||
if (is_null($libraryName)) { | |||||
return false; | |||||
} | |||||
// Ensure that data series values are up-to-date before we render | |||||
$this->refresh(); | |||||
$libraryPath = PHPExcel_Settings::getChartRendererPath(); | |||||
$includePath = str_replace('\\', '/', get_include_path()); | |||||
$rendererPath = str_replace('\\', '/', $libraryPath); | |||||
if (strpos($rendererPath, $includePath) === false) { | |||||
set_include_path(get_include_path() . PATH_SEPARATOR . $libraryPath); | |||||
} | |||||
$rendererName = 'PHPExcel_Chart_Renderer_'.$libraryName; | |||||
$renderer = new $rendererName($this); | |||||
if ($outputDestination == 'php://output') { | |||||
$outputDestination = null; | |||||
} | |||||
return $renderer->render($outputDestination); | |||||
} | |||||
} |
@ -0,0 +1,561 @@ | |||||
<?php | |||||
/** | |||||
* Created by PhpStorm. | |||||
* User: Wiktor Trzonkowski | |||||
* Date: 6/17/14 | |||||
* Time: 12:11 PM | |||||
*/ | |||||
class PHPExcel_Chart_Axis extends PHPExcel_Chart_Properties | |||||
{ | |||||
/** | |||||
* Axis Number | |||||
* | |||||
* @var array of mixed | |||||
*/ | |||||
private $axisNumber = array( | |||||
'format' => self::FORMAT_CODE_GENERAL, | |||||
'source_linked' => 1 | |||||
); | |||||
/** | |||||
* Axis Options | |||||
* | |||||
* @var array of mixed | |||||
*/ | |||||
private $axisOptions = array( | |||||
'minimum' => null, | |||||
'maximum' => null, | |||||
'major_unit' => null, | |||||
'minor_unit' => null, | |||||
'orientation' => self::ORIENTATION_NORMAL, | |||||
'minor_tick_mark' => self::TICK_MARK_NONE, | |||||
'major_tick_mark' => self::TICK_MARK_NONE, | |||||
'axis_labels' => self::AXIS_LABELS_NEXT_TO, | |||||
'horizontal_crosses' => self::HORIZONTAL_CROSSES_AUTOZERO, | |||||
'horizontal_crosses_value' => null | |||||
); | |||||
/** | |||||
* Fill Properties | |||||
* | |||||
* @var array of mixed | |||||
*/ | |||||
private $fillProperties = array( | |||||
'type' => self::EXCEL_COLOR_TYPE_ARGB, | |||||
'value' => null, | |||||
'alpha' => 0 | |||||
); | |||||
/** | |||||
* Line Properties | |||||
* | |||||
* @var array of mixed | |||||
*/ | |||||
private $lineProperties = array( | |||||
'type' => self::EXCEL_COLOR_TYPE_ARGB, | |||||
'value' => null, | |||||
'alpha' => 0 | |||||
); | |||||
/** | |||||
* Line Style Properties | |||||
* | |||||
* @var array of mixed | |||||
*/ | |||||
private $lineStyleProperties = array( | |||||
'width' => '9525', | |||||
'compound' => self::LINE_STYLE_COMPOUND_SIMPLE, | |||||
'dash' => self::LINE_STYLE_DASH_SOLID, | |||||
'cap' => self::LINE_STYLE_CAP_FLAT, | |||||
'join' => self::LINE_STYLE_JOIN_BEVEL, | |||||
'arrow' => array( | |||||
'head' => array( | |||||
'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW, | |||||
'size' => self::LINE_STYLE_ARROW_SIZE_5 | |||||
), | |||||
'end' => array( | |||||
'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW, | |||||
'size' => self::LINE_STYLE_ARROW_SIZE_8 | |||||
), | |||||
) | |||||
); | |||||
/** | |||||
* Shadow Properties | |||||
* | |||||
* @var array of mixed | |||||
*/ | |||||
private $shadowProperties = array( | |||||
'presets' => self::SHADOW_PRESETS_NOSHADOW, | |||||
'effect' => null, | |||||
'color' => array( | |||||
'type' => self::EXCEL_COLOR_TYPE_STANDARD, | |||||
'value' => 'black', | |||||
'alpha' => 40, | |||||
), | |||||
'size' => array( | |||||
'sx' => null, | |||||
'sy' => null, | |||||
'kx' => null | |||||
), | |||||
'blur' => null, | |||||
'direction' => null, | |||||
'distance' => null, | |||||
'algn' => null, | |||||
'rotWithShape' => null | |||||
); | |||||
/** | |||||
* Glow Properties | |||||
* | |||||
* @var array of mixed | |||||
*/ | |||||
private $glowProperties = array( | |||||
'size' => null, | |||||
'color' => array( | |||||
'type' => self::EXCEL_COLOR_TYPE_STANDARD, | |||||
'value' => 'black', | |||||
'alpha' => 40 | |||||
) | |||||
); | |||||
/** | |||||
* Soft Edge Properties | |||||
* | |||||
* @var array of mixed | |||||
*/ | |||||
private $softEdges = array( | |||||
'size' => null | |||||
); | |||||
/** | |||||
* Get Series Data Type | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function setAxisNumberProperties($format_code) | |||||
{ | |||||
$this->axisNumber['format'] = (string) $format_code; | |||||
$this->axisNumber['source_linked'] = 0; | |||||
} | |||||
/** | |||||
* Get Axis Number Format Data Type | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getAxisNumberFormat() | |||||
{ | |||||
return $this->axisNumber['format']; | |||||
} | |||||
/** | |||||
* Get Axis Number Source Linked | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getAxisNumberSourceLinked() | |||||
{ | |||||
return (string) $this->axisNumber['source_linked']; | |||||
} | |||||
/** | |||||
* Set Axis Options Properties | |||||
* | |||||
* @param string $axis_labels | |||||
* @param string $horizontal_crosses_value | |||||
* @param string $horizontal_crosses | |||||
* @param string $axis_orientation | |||||
* @param string $major_tmt | |||||
* @param string $minor_tmt | |||||
* @param string $minimum | |||||
* @param string $maximum | |||||
* @param string $major_unit | |||||
* @param string $minor_unit | |||||
* | |||||
*/ | |||||
public function setAxisOptionsProperties($axis_labels, $horizontal_crosses_value = null, $horizontal_crosses = null, $axis_orientation = null, $major_tmt = null, $minor_tmt = null, $minimum = null, $maximum = null, $major_unit = null, $minor_unit = null) | |||||
{ | |||||
$this->axisOptions['axis_labels'] = (string) $axis_labels; | |||||
($horizontal_crosses_value !== null) ? $this->axisOptions['horizontal_crosses_value'] = (string) $horizontal_crosses_value : null; | |||||
($horizontal_crosses !== null) ? $this->axisOptions['horizontal_crosses'] = (string) $horizontal_crosses : null; | |||||
($axis_orientation !== null) ? $this->axisOptions['orientation'] = (string) $axis_orientation : null; | |||||
($major_tmt !== null) ? $this->axisOptions['major_tick_mark'] = (string) $major_tmt : null; | |||||
($minor_tmt !== null) ? $this->axisOptions['minor_tick_mark'] = (string) $minor_tmt : null; | |||||
($minor_tmt !== null) ? $this->axisOptions['minor_tick_mark'] = (string) $minor_tmt : null; | |||||
($minimum !== null) ? $this->axisOptions['minimum'] = (string) $minimum : null; | |||||
($maximum !== null) ? $this->axisOptions['maximum'] = (string) $maximum : null; | |||||
($major_unit !== null) ? $this->axisOptions['major_unit'] = (string) $major_unit : null; | |||||
($minor_unit !== null) ? $this->axisOptions['minor_unit'] = (string) $minor_unit : null; | |||||
} | |||||
/** | |||||
* Get Axis Options Property | |||||
* | |||||
* @param string $property | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getAxisOptionsProperty($property) | |||||
{ | |||||
return $this->axisOptions[$property]; | |||||
} | |||||
/** | |||||
* Set Axis Orientation Property | |||||
* | |||||
* @param string $orientation | |||||
* | |||||
*/ | |||||
public function setAxisOrientation($orientation) | |||||
{ | |||||
$this->orientation = (string) $orientation; | |||||
} | |||||
/** | |||||
* Set Fill Property | |||||
* | |||||
* @param string $color | |||||
* @param int $alpha | |||||
* @param string $type | |||||
* | |||||
*/ | |||||
public function setFillParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) | |||||
{ | |||||
$this->fillProperties = $this->setColorProperties($color, $alpha, $type); | |||||
} | |||||
/** | |||||
* Set Line Property | |||||
* | |||||
* @param string $color | |||||
* @param int $alpha | |||||
* @param string $type | |||||
* | |||||
*/ | |||||
public function setLineParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) | |||||
{ | |||||
$this->lineProperties = $this->setColorProperties($color, $alpha, $type); | |||||
} | |||||
/** | |||||
* Get Fill Property | |||||
* | |||||
* @param string $property | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getFillProperty($property) | |||||
{ | |||||
return $this->fillProperties[$property]; | |||||
} | |||||
/** | |||||
* Get Line Property | |||||
* | |||||
* @param string $property | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getLineProperty($property) | |||||
{ | |||||
return $this->lineProperties[$property]; | |||||
} | |||||
/** | |||||
* Set Line Style Properties | |||||
* | |||||
* @param float $line_width | |||||
* @param string $compound_type | |||||
* @param string $dash_type | |||||
* @param string $cap_type | |||||
* @param string $join_type | |||||
* @param string $head_arrow_type | |||||
* @param string $head_arrow_size | |||||
* @param string $end_arrow_type | |||||
* @param string $end_arrow_size | |||||
* | |||||
*/ | |||||
public function setLineStyleProperties($line_width = null, $compound_type = null, $dash_type = null, $cap_type = null, $join_type = null, $head_arrow_type = null, $head_arrow_size = null, $end_arrow_type = null, $end_arrow_size = null) | |||||
{ | |||||
(!is_null($line_width)) ? $this->lineStyleProperties['width'] = $this->getExcelPointsWidth((float) $line_width) : null; | |||||
(!is_null($compound_type)) ? $this->lineStyleProperties['compound'] = (string) $compound_type : null; | |||||
(!is_null($dash_type)) ? $this->lineStyleProperties['dash'] = (string) $dash_type : null; | |||||
(!is_null($cap_type)) ? $this->lineStyleProperties['cap'] = (string) $cap_type : null; | |||||
(!is_null($join_type)) ? $this->lineStyleProperties['join'] = (string) $join_type : null; | |||||
(!is_null($head_arrow_type)) ? $this->lineStyleProperties['arrow']['head']['type'] = (string) $head_arrow_type : null; | |||||
(!is_null($head_arrow_size)) ? $this->lineStyleProperties['arrow']['head']['size'] = (string) $head_arrow_size : null; | |||||
(!is_null($end_arrow_type)) ? $this->lineStyleProperties['arrow']['end']['type'] = (string) $end_arrow_type : null; | |||||
(!is_null($end_arrow_size)) ? $this->lineStyleProperties['arrow']['end']['size'] = (string) $end_arrow_size : null; | |||||
} | |||||
/** | |||||
* Get Line Style Property | |||||
* | |||||
* @param array|string $elements | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getLineStyleProperty($elements) | |||||
{ | |||||
return $this->getArrayElementsValue($this->lineStyleProperties, $elements); | |||||
} | |||||
/** | |||||
* Get Line Style Arrow Excel Width | |||||
* | |||||
* @param string $arrow | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getLineStyleArrowWidth($arrow) | |||||
{ | |||||
return $this->getLineStyleArrowSize($this->lineStyleProperties['arrow'][$arrow]['size'], 'w'); | |||||
} | |||||
/** | |||||
* Get Line Style Arrow Excel Length | |||||
* | |||||
* @param string $arrow | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getLineStyleArrowLength($arrow) | |||||
{ | |||||
return $this->getLineStyleArrowSize($this->lineStyleProperties['arrow'][$arrow]['size'], 'len'); | |||||
} | |||||
/** | |||||
* Set Shadow Properties | |||||
* | |||||
* @param int $shadow_presets | |||||
* @param string $sh_color_value | |||||
* @param string $sh_color_type | |||||
* @param string $sh_color_alpha | |||||
* @param float $sh_blur | |||||
* @param int $sh_angle | |||||
* @param float $sh_distance | |||||
* | |||||
*/ | |||||
public function setShadowProperties($sh_presets, $sh_color_value = null, $sh_color_type = null, $sh_color_alpha = null, $sh_blur = null, $sh_angle = null, $sh_distance = null) | |||||
{ | |||||
$this->setShadowPresetsProperties((int) $sh_presets) | |||||
->setShadowColor( | |||||
is_null($sh_color_value) ? $this->shadowProperties['color']['value'] : $sh_color_value, | |||||
is_null($sh_color_alpha) ? (int) $this->shadowProperties['color']['alpha'] : $sh_color_alpha, | |||||
is_null($sh_color_type) ? $this->shadowProperties['color']['type'] : $sh_color_type | |||||
) | |||||
->setShadowBlur($sh_blur) | |||||
->setShadowAngle($sh_angle) | |||||
->setShadowDistance($sh_distance); | |||||
} | |||||
/** | |||||
* Set Shadow Color | |||||
* | |||||
* @param int $shadow_presets | |||||
* | |||||
* @return PHPExcel_Chart_Axis | |||||
*/ | |||||
private function setShadowPresetsProperties($shadow_presets) | |||||
{ | |||||
$this->shadowProperties['presets'] = $shadow_presets; | |||||
$this->setShadowProperiesMapValues($this->getShadowPresetsMap($shadow_presets)); | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set Shadow Properties from Maped Values | |||||
* | |||||
* @param array $properties_map | |||||
* @param * $reference | |||||
* | |||||
* @return PHPExcel_Chart_Axis | |||||
*/ | |||||
private function setShadowProperiesMapValues(array $properties_map, &$reference = null) | |||||
{ | |||||
$base_reference = $reference; | |||||
foreach ($properties_map as $property_key => $property_val) { | |||||
if (is_array($property_val)) { | |||||
if ($reference === null) { | |||||
$reference = & $this->shadowProperties[$property_key]; | |||||
} else { | |||||
$reference = & $reference[$property_key]; | |||||
} | |||||
$this->setShadowProperiesMapValues($property_val, $reference); | |||||
} else { | |||||
if ($base_reference === null) { | |||||
$this->shadowProperties[$property_key] = $property_val; | |||||
} else { | |||||
$reference[$property_key] = $property_val; | |||||
} | |||||
} | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set Shadow Color | |||||
* | |||||
* @param string $color | |||||
* @param int $alpha | |||||
* @param string $type | |||||
* | |||||
* @return PHPExcel_Chart_Axis | |||||
*/ | |||||
private function setShadowColor($color, $alpha, $type) | |||||
{ | |||||
$this->shadowProperties['color'] = $this->setColorProperties($color, $alpha, $type); | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set Shadow Blur | |||||
* | |||||
* @param float $blur | |||||
* | |||||
* @return PHPExcel_Chart_Axis | |||||
*/ | |||||
private function setShadowBlur($blur) | |||||
{ | |||||
if ($blur !== null) { | |||||
$this->shadowProperties['blur'] = (string) $this->getExcelPointsWidth($blur); | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set Shadow Angle | |||||
* | |||||
* @param int $angle | |||||
* | |||||
* @return PHPExcel_Chart_Axis | |||||
*/ | |||||
private function setShadowAngle($angle) | |||||
{ | |||||
if ($angle !== null) { | |||||
$this->shadowProperties['direction'] = (string) $this->getExcelPointsAngle($angle); | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set Shadow Distance | |||||
* | |||||
* @param float $distance | |||||
* | |||||
* @return PHPExcel_Chart_Axis | |||||
*/ | |||||
private function setShadowDistance($distance) | |||||
{ | |||||
if ($distance !== null) { | |||||
$this->shadowProperties['distance'] = (string) $this->getExcelPointsWidth($distance); | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Glow Property | |||||
* | |||||
* @param float $size | |||||
* @param string $color_value | |||||
* @param int $color_alpha | |||||
* @param string $color_type | |||||
*/ | |||||
public function getShadowProperty($elements) | |||||
{ | |||||
return $this->getArrayElementsValue($this->shadowProperties, $elements); | |||||
} | |||||
/** | |||||
* Set Glow Properties | |||||
* | |||||
* @param float $size | |||||
* @param string $color_value | |||||
* @param int $color_alpha | |||||
* @param string $color_type | |||||
*/ | |||||
public function setGlowProperties($size, $color_value = null, $color_alpha = null, $color_type = null) | |||||
{ | |||||
$this->setGlowSize($size) | |||||
->setGlowColor( | |||||
is_null($color_value) ? $this->glowProperties['color']['value'] : $color_value, | |||||
is_null($color_alpha) ? (int) $this->glowProperties['color']['alpha'] : $color_alpha, | |||||
is_null($color_type) ? $this->glowProperties['color']['type'] : $color_type | |||||
); | |||||
} | |||||
/** | |||||
* Get Glow Property | |||||
* | |||||
* @param array|string $property | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getGlowProperty($property) | |||||
{ | |||||
return $this->getArrayElementsValue($this->glowProperties, $property); | |||||
} | |||||
/** | |||||
* Set Glow Color | |||||
* | |||||
* @param float $size | |||||
* | |||||
* @return PHPExcel_Chart_Axis | |||||
*/ | |||||
private function setGlowSize($size) | |||||
{ | |||||
if (!is_null($size)) { | |||||
$this->glowProperties['size'] = $this->getExcelPointsWidth($size); | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set Glow Color | |||||
* | |||||
* @param string $color | |||||
* @param int $alpha | |||||
* @param string $type | |||||
* | |||||
* @return PHPExcel_Chart_Axis | |||||
*/ | |||||
private function setGlowColor($color, $alpha, $type) | |||||
{ | |||||
$this->glowProperties['color'] = $this->setColorProperties($color, $alpha, $type); | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set Soft Edges Size | |||||
* | |||||
* @param float $size | |||||
*/ | |||||
public function setSoftEdges($size) | |||||
{ | |||||
if (!is_null($size)) { | |||||
$softEdges['size'] = (string) $this->getExcelPointsWidth($size); | |||||
} | |||||
} | |||||
/** | |||||
* Get Soft Edges Size | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getSoftEdgesSize() | |||||
{ | |||||
return $this->softEdges['size']; | |||||
} | |||||
} |
@ -0,0 +1,390 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel | |||||
* | |||||
* 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_Chart | |||||
* @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## | |||||
*/ | |||||
/** | |||||
* PHPExcel_Chart_DataSeries | |||||
* | |||||
* @category PHPExcel | |||||
* @package PHPExcel_Chart | |||||
* @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | |||||
*/ | |||||
class PHPExcel_Chart_DataSeries | |||||
{ | |||||
const TYPE_BARCHART = 'barChart'; | |||||
const TYPE_BARCHART_3D = 'bar3DChart'; | |||||
const TYPE_LINECHART = 'lineChart'; | |||||
const TYPE_LINECHART_3D = 'line3DChart'; | |||||
const TYPE_AREACHART = 'areaChart'; | |||||
const TYPE_AREACHART_3D = 'area3DChart'; | |||||
const TYPE_PIECHART = 'pieChart'; | |||||
const TYPE_PIECHART_3D = 'pie3DChart'; | |||||
const TYPE_DOUGHTNUTCHART = 'doughnutChart'; | |||||
const TYPE_DONUTCHART = self::TYPE_DOUGHTNUTCHART; // Synonym | |||||
const TYPE_SCATTERCHART = 'scatterChart'; | |||||
const TYPE_SURFACECHART = 'surfaceChart'; | |||||
const TYPE_SURFACECHART_3D = 'surface3DChart'; | |||||
const TYPE_RADARCHART = 'radarChart'; | |||||
const TYPE_BUBBLECHART = 'bubbleChart'; | |||||
const TYPE_STOCKCHART = 'stockChart'; | |||||
const TYPE_CANDLECHART = self::TYPE_STOCKCHART; // Synonym | |||||
const GROUPING_CLUSTERED = 'clustered'; | |||||
const GROUPING_STACKED = 'stacked'; | |||||
const GROUPING_PERCENT_STACKED = 'percentStacked'; | |||||
const GROUPING_STANDARD = 'standard'; | |||||
const DIRECTION_BAR = 'bar'; | |||||
const DIRECTION_HORIZONTAL = self::DIRECTION_BAR; | |||||
const DIRECTION_COL = 'col'; | |||||
const DIRECTION_COLUMN = self::DIRECTION_COL; | |||||
const DIRECTION_VERTICAL = self::DIRECTION_COL; | |||||
const STYLE_LINEMARKER = 'lineMarker'; | |||||
const STYLE_SMOOTHMARKER = 'smoothMarker'; | |||||
const STYLE_MARKER = 'marker'; | |||||
const STYLE_FILLED = 'filled'; | |||||
/** | |||||
* Series Plot Type | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $plotType; | |||||
/** | |||||
* Plot Grouping Type | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $plotGrouping; | |||||
/** | |||||
* Plot Direction | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $plotDirection; | |||||
/** | |||||
* Plot Style | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $plotStyle; | |||||
/** | |||||
* Order of plots in Series | |||||
* | |||||
* @var array of integer | |||||
*/ | |||||
private $plotOrder = array(); | |||||
/** | |||||
* Plot Label | |||||
* | |||||
* @var array of PHPExcel_Chart_DataSeriesValues | |||||
*/ | |||||
private $plotLabel = array(); | |||||
/** | |||||
* Plot Category | |||||
* | |||||
* @var array of PHPExcel_Chart_DataSeriesValues | |||||
*/ | |||||
private $plotCategory = array(); | |||||
/** | |||||
* Smooth Line | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $smoothLine; | |||||
/** | |||||
* Plot Values | |||||
* | |||||
* @var array of PHPExcel_Chart_DataSeriesValues | |||||
*/ | |||||
private $plotValues = array(); | |||||
/** | |||||
* Create a new PHPExcel_Chart_DataSeries | |||||
*/ | |||||
public function __construct($plotType = null, $plotGrouping = null, $plotOrder = array(), $plotLabel = array(), $plotCategory = array(), $plotValues = array(), $plotDirection = null, $smoothLine = null, $plotStyle = null) | |||||
{ | |||||
$this->plotType = $plotType; | |||||
$this->plotGrouping = $plotGrouping; | |||||
$this->plotOrder = $plotOrder; | |||||
$keys = array_keys($plotValues); | |||||
$this->plotValues = $plotValues; | |||||
if ((count($plotLabel) == 0) || (is_null($plotLabel[$keys[0]]))) { | |||||
$plotLabel[$keys[0]] = new PHPExcel_Chart_DataSeriesValues(); | |||||
} | |||||
$this->plotLabel = $plotLabel; | |||||
if ((count($plotCategory) == 0) || (is_null($plotCategory[$keys[0]]))) { | |||||
$plotCategory[$keys[0]] = new PHPExcel_Chart_DataSeriesValues(); | |||||
} | |||||
$this->plotCategory = $plotCategory; | |||||
$this->smoothLine = $smoothLine; | |||||
$this->plotStyle = $plotStyle; | |||||
if (is_null($plotDirection)) { | |||||
$plotDirection = self::DIRECTION_COL; | |||||
} | |||||
$this->plotDirection = $plotDirection; | |||||
} | |||||
/** | |||||
* Get Plot Type | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getPlotType() | |||||
{ | |||||
return $this->plotType; | |||||
} | |||||
/** | |||||
* Set Plot Type | |||||
* | |||||
* @param string $plotType | |||||
* @return PHPExcel_Chart_DataSeries | |||||
*/ | |||||
public function setPlotType($plotType = '') | |||||
{ | |||||
$this->plotType = $plotType; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Plot Grouping Type | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getPlotGrouping() | |||||
{ | |||||
return $this->plotGrouping; | |||||
} | |||||
/** | |||||
* Set Plot Grouping Type | |||||
* | |||||
* @param string $groupingType | |||||
* @return PHPExcel_Chart_DataSeries | |||||
*/ | |||||
public function setPlotGrouping($groupingType = null) | |||||
{ | |||||
$this->plotGrouping = $groupingType; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Plot Direction | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getPlotDirection() | |||||
{ | |||||
return $this->plotDirection; | |||||
} | |||||
/** | |||||
* Set Plot Direction | |||||
* | |||||
* @param string $plotDirection | |||||
* @return PHPExcel_Chart_DataSeries | |||||
*/ | |||||
public function setPlotDirection($plotDirection = null) | |||||
{ | |||||
$this->plotDirection = $plotDirection; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Plot Order | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getPlotOrder() | |||||
{ | |||||
return $this->plotOrder; | |||||
} | |||||
/** | |||||
* Get Plot Labels | |||||
* | |||||
* @return array of PHPExcel_Chart_DataSeriesValues | |||||
*/ | |||||
public function getPlotLabels() | |||||
{ | |||||
return $this->plotLabel; | |||||
} | |||||
/** | |||||
* Get Plot Label by Index | |||||
* | |||||
* @return PHPExcel_Chart_DataSeriesValues | |||||
*/ | |||||
public function getPlotLabelByIndex($index) | |||||
{ | |||||
$keys = array_keys($this->plotLabel); | |||||
if (in_array($index, $keys)) { | |||||
return $this->plotLabel[$index]; | |||||
} elseif (isset($keys[$index])) { | |||||
return $this->plotLabel[$keys[$index]]; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* Get Plot Categories | |||||
* | |||||
* @return array of PHPExcel_Chart_DataSeriesValues | |||||
*/ | |||||
public function getPlotCategories() | |||||
{ | |||||
return $this->plotCategory; | |||||
} | |||||
/** | |||||
* Get Plot Category by Index | |||||
* | |||||
* @return PHPExcel_Chart_DataSeriesValues | |||||
*/ | |||||
public function getPlotCategoryByIndex($index) | |||||
{ | |||||
$keys = array_keys($this->plotCategory); | |||||
if (in_array($index, $keys)) { | |||||
return $this->plotCategory[$index]; | |||||
} elseif (isset($keys[$index])) { | |||||
return $this->plotCategory[$keys[$index]]; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* Get Plot Style | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getPlotStyle() | |||||
{ | |||||
return $this->plotStyle; | |||||
} | |||||
/** | |||||
* Set Plot Style | |||||
* | |||||
* @param string $plotStyle | |||||
* @return PHPExcel_Chart_DataSeries | |||||
*/ | |||||
public function setPlotStyle($plotStyle = null) | |||||
{ | |||||
$this->plotStyle = $plotStyle; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Plot Values | |||||
* | |||||
* @return array of PHPExcel_Chart_DataSeriesValues | |||||
*/ | |||||
public function getPlotValues() | |||||
{ | |||||
return $this->plotValues; | |||||
} | |||||
/** | |||||
* Get Plot Values by Index | |||||
* | |||||
* @return PHPExcel_Chart_DataSeriesValues | |||||
*/ | |||||
public function getPlotValuesByIndex($index) | |||||
{ | |||||
$keys = array_keys($this->plotValues); | |||||
if (in_array($index, $keys)) { | |||||
return $this->plotValues[$index]; | |||||
} elseif (isset($keys[$index])) { | |||||
return $this->plotValues[$keys[$index]]; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* Get Number of Plot Series | |||||
* | |||||
* @return integer | |||||
*/ | |||||
public function getPlotSeriesCount() | |||||
{ | |||||
return count($this->plotValues); | |||||
} | |||||
/** | |||||
* Get Smooth Line | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getSmoothLine() | |||||
{ | |||||
return $this->smoothLine; | |||||
} | |||||
/** | |||||
* Set Smooth Line | |||||
* | |||||
* @param boolean $smoothLine | |||||
* @return PHPExcel_Chart_DataSeries | |||||
*/ | |||||
public function setSmoothLine($smoothLine = true) | |||||
{ | |||||
$this->smoothLine = $smoothLine; | |||||
return $this; | |||||
} | |||||
public function refresh(PHPExcel_Worksheet $worksheet) | |||||
{ | |||||
foreach ($this->plotValues as $plotValues) { | |||||
if ($plotValues !== null) { | |||||
$plotValues->refresh($worksheet, true); | |||||
} | |||||
} | |||||
foreach ($this->plotLabel as $plotValues) { | |||||
if ($plotValues !== null) { | |||||
$plotValues->refresh($worksheet, true); | |||||
} | |||||
} | |||||
foreach ($this->plotCategory as $plotValues) { | |||||
if ($plotValues !== null) { | |||||
$plotValues->refresh($worksheet, false); | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,333 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Chart_DataSeriesValues | |||||
* | |||||
* 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_Chart | |||||
* @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_Chart_DataSeriesValues | |||||
{ | |||||
const DATASERIES_TYPE_STRING = 'String'; | |||||
const DATASERIES_TYPE_NUMBER = 'Number'; | |||||
private static $dataTypeValues = array( | |||||
self::DATASERIES_TYPE_STRING, | |||||
self::DATASERIES_TYPE_NUMBER, | |||||
); | |||||
/** | |||||
* Series Data Type | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $dataType; | |||||
/** | |||||
* Series Data Source | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $dataSource; | |||||
/** | |||||
* Format Code | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $formatCode; | |||||
/** | |||||
* Series Point Marker | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $pointMarker; | |||||
/** | |||||
* Point Count (The number of datapoints in the dataseries) | |||||
* | |||||
* @var integer | |||||
*/ | |||||
private $pointCount = 0; | |||||
/** | |||||
* Data Values | |||||
* | |||||
* @var array of mixed | |||||
*/ | |||||
private $dataValues = array(); | |||||
/** | |||||
* Create a new PHPExcel_Chart_DataSeriesValues object | |||||
*/ | |||||
public function __construct($dataType = self::DATASERIES_TYPE_NUMBER, $dataSource = null, $formatCode = null, $pointCount = 0, $dataValues = array(), $marker = null) | |||||
{ | |||||
$this->setDataType($dataType); | |||||
$this->dataSource = $dataSource; | |||||
$this->formatCode = $formatCode; | |||||
$this->pointCount = $pointCount; | |||||
$this->dataValues = $dataValues; | |||||
$this->pointMarker = $marker; | |||||
} | |||||
/** | |||||
* Get Series Data Type | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getDataType() | |||||
{ | |||||
return $this->dataType; | |||||
} | |||||
/** | |||||
* Set Series Data Type | |||||
* | |||||
* @param string $dataType Datatype of this data series | |||||
* Typical values are: | |||||
* PHPExcel_Chart_DataSeriesValues::DATASERIES_TYPE_STRING | |||||
* Normally used for axis point values | |||||
* PHPExcel_Chart_DataSeriesValues::DATASERIES_TYPE_NUMBER | |||||
* Normally used for chart data values | |||||
* @return PHPExcel_Chart_DataSeriesValues | |||||
*/ | |||||
public function setDataType($dataType = self::DATASERIES_TYPE_NUMBER) | |||||
{ | |||||
if (!in_array($dataType, self::$dataTypeValues)) { | |||||
throw new PHPExcel_Chart_Exception('Invalid datatype for chart data series values'); | |||||
} | |||||
$this->dataType = $dataType; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Series Data Source (formula) | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getDataSource() | |||||
{ | |||||
return $this->dataSource; | |||||
} | |||||
/** | |||||
* Set Series Data Source (formula) | |||||
* | |||||
* @param string $dataSource | |||||
* @return PHPExcel_Chart_DataSeriesValues | |||||
*/ | |||||
public function setDataSource($dataSource = null, $refreshDataValues = true) | |||||
{ | |||||
$this->dataSource = $dataSource; | |||||
if ($refreshDataValues) { | |||||
// TO DO | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Point Marker | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getPointMarker() | |||||
{ | |||||
return $this->pointMarker; | |||||
} | |||||
/** | |||||
* Set Point Marker | |||||
* | |||||
* @param string $marker | |||||
* @return PHPExcel_Chart_DataSeriesValues | |||||
*/ | |||||
public function setPointMarker($marker = null) | |||||
{ | |||||
$this->pointMarker = $marker; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Series Format Code | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getFormatCode() | |||||
{ | |||||
return $this->formatCode; | |||||
} | |||||
/** | |||||
* Set Series Format Code | |||||
* | |||||
* @param string $formatCode | |||||
* @return PHPExcel_Chart_DataSeriesValues | |||||
*/ | |||||
public function setFormatCode($formatCode = null) | |||||
{ | |||||
$this->formatCode = $formatCode; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Series Point Count | |||||
* | |||||
* @return integer | |||||
*/ | |||||
public function getPointCount() | |||||
{ | |||||
return $this->pointCount; | |||||
} | |||||
/** | |||||
* Identify if the Data Series is a multi-level or a simple series | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function isMultiLevelSeries() | |||||
{ | |||||
if (count($this->dataValues) > 0) { | |||||
return is_array($this->dataValues[0]); | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* Return the level count of a multi-level Data Series | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function multiLevelCount() | |||||
{ | |||||
$levelCount = 0; | |||||
foreach ($this->dataValues as $dataValueSet) { | |||||
$levelCount = max($levelCount, count($dataValueSet)); | |||||
} | |||||
return $levelCount; | |||||
} | |||||
/** | |||||
* Get Series Data Values | |||||
* | |||||
* @return array of mixed | |||||
*/ | |||||
public function getDataValues() | |||||
{ | |||||
return $this->dataValues; | |||||
} | |||||
/** | |||||
* Get the first Series Data value | |||||
* | |||||
* @return mixed | |||||
*/ | |||||
public function getDataValue() | |||||
{ | |||||
$count = count($this->dataValues); | |||||
if ($count == 0) { | |||||
return null; | |||||
} elseif ($count == 1) { | |||||
return $this->dataValues[0]; | |||||
} | |||||
return $this->dataValues; | |||||
} | |||||
/** | |||||
* Set Series Data Values | |||||
* | |||||
* @param array $dataValues | |||||
* @param boolean $refreshDataSource | |||||
* TRUE - refresh the value of dataSource based on the values of $dataValues | |||||
* FALSE - don't change the value of dataSource | |||||
* @return PHPExcel_Chart_DataSeriesValues | |||||
*/ | |||||
public function setDataValues($dataValues = array(), $refreshDataSource = true) | |||||
{ | |||||
$this->dataValues = PHPExcel_Calculation_Functions::flattenArray($dataValues); | |||||
$this->pointCount = count($dataValues); | |||||
if ($refreshDataSource) { | |||||
// TO DO | |||||
} | |||||
return $this; | |||||
} | |||||
private function stripNulls($var) | |||||
{ | |||||
return $var !== null; | |||||
} | |||||
public function refresh(PHPExcel_Worksheet $worksheet, $flatten = true) | |||||
{ | |||||
if ($this->dataSource !== null) { | |||||
$calcEngine = PHPExcel_Calculation::getInstance($worksheet->getParent()); | |||||
$newDataValues = PHPExcel_Calculation::unwrapResult( | |||||
$calcEngine->_calculateFormulaValue( | |||||
'='.$this->dataSource, | |||||
null, | |||||
$worksheet->getCell('A1') | |||||
) | |||||
); | |||||
if ($flatten) { | |||||
$this->dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); | |||||
foreach ($this->dataValues as &$dataValue) { | |||||
if ((!empty($dataValue)) && ($dataValue[0] == '#')) { | |||||
$dataValue = 0.0; | |||||
} | |||||
} | |||||
unset($dataValue); | |||||
} else { | |||||
$cellRange = explode('!', $this->dataSource); | |||||
if (count($cellRange) > 1) { | |||||
list(, $cellRange) = $cellRange; | |||||
} | |||||
$dimensions = PHPExcel_Cell::rangeDimension(str_replace('$', '', $cellRange)); | |||||
if (($dimensions[0] == 1) || ($dimensions[1] == 1)) { | |||||
$this->dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); | |||||
} else { | |||||
$newArray = array_values(array_shift($newDataValues)); | |||||
foreach ($newArray as $i => $newDataSet) { | |||||
$newArray[$i] = array($newDataSet); | |||||
} | |||||
foreach ($newDataValues as $newDataSet) { | |||||
$i = 0; | |||||
foreach ($newDataSet as $newDataVal) { | |||||
array_unshift($newArray[$i++], $newDataVal); | |||||
} | |||||
} | |||||
$this->dataValues = $newArray; | |||||
} | |||||
} | |||||
$this->pointCount = count($this->dataValues); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,46 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Chart_Exception | |||||
* | |||||
* 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_Chart | |||||
* @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_Chart_Exception extends PHPExcel_Exception | |||||
{ | |||||
/** | |||||
* Error handler callback | |||||
* | |||||
* @param mixed $code | |||||
* @param mixed $string | |||||
* @param mixed $file | |||||
* @param mixed $line | |||||
* @param mixed $context | |||||
*/ | |||||
public static function errorHandlerCallback($code, $string, $file, $line, $context) | |||||
{ | |||||
$e = new self($string, $code); | |||||
$e->line = $line; | |||||
$e->file = $file; | |||||
throw $e; | |||||
} | |||||
} |
@ -0,0 +1,472 @@ | |||||
<?php | |||||
/** | |||||
* Created by PhpStorm. | |||||
* User: Wiktor Trzonkowski | |||||
* Date: 7/2/14 | |||||
* Time: 2:36 PM | |||||
*/ | |||||
class PHPExcel_Chart_GridLines extends PHPExcel_Chart_Properties | |||||
{ | |||||
/** | |||||
* Properties of Class: | |||||
* Object State (State for Minor Tick Mark) @var bool | |||||
* Line Properties @var array of mixed | |||||
* Shadow Properties @var array of mixed | |||||
* Glow Properties @var array of mixed | |||||
* Soft Properties @var array of mixed | |||||
* | |||||
*/ | |||||
private $objectState = false; | |||||
private $lineProperties = array( | |||||
'color' => array( | |||||
'type' => self::EXCEL_COLOR_TYPE_STANDARD, | |||||
'value' => null, | |||||
'alpha' => 0 | |||||
), | |||||
'style' => array( | |||||
'width' => '9525', | |||||
'compound' => self::LINE_STYLE_COMPOUND_SIMPLE, | |||||
'dash' => self::LINE_STYLE_DASH_SOLID, | |||||
'cap' => self::LINE_STYLE_CAP_FLAT, | |||||
'join' => self::LINE_STYLE_JOIN_BEVEL, | |||||
'arrow' => array( | |||||
'head' => array( | |||||
'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW, | |||||
'size' => self::LINE_STYLE_ARROW_SIZE_5 | |||||
), | |||||
'end' => array( | |||||
'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW, | |||||
'size' => self::LINE_STYLE_ARROW_SIZE_8 | |||||
), | |||||
) | |||||
) | |||||
); | |||||
private $shadowProperties = array( | |||||
'presets' => self::SHADOW_PRESETS_NOSHADOW, | |||||
'effect' => null, | |||||
'color' => array( | |||||
'type' => self::EXCEL_COLOR_TYPE_STANDARD, | |||||
'value' => 'black', | |||||
'alpha' => 85, | |||||
), | |||||
'size' => array( | |||||
'sx' => null, | |||||
'sy' => null, | |||||
'kx' => null | |||||
), | |||||
'blur' => null, | |||||
'direction' => null, | |||||
'distance' => null, | |||||
'algn' => null, | |||||
'rotWithShape' => null | |||||
); | |||||
private $glowProperties = array( | |||||
'size' => null, | |||||
'color' => array( | |||||
'type' => self::EXCEL_COLOR_TYPE_STANDARD, | |||||
'value' => 'black', | |||||
'alpha' => 40 | |||||
) | |||||
); | |||||
private $softEdges = array( | |||||
'size' => null | |||||
); | |||||
/** | |||||
* Get Object State | |||||
* | |||||
* @return bool | |||||
*/ | |||||
public function getObjectState() | |||||
{ | |||||
return $this->objectState; | |||||
} | |||||
/** | |||||
* Change Object State to True | |||||
* | |||||
* @return PHPExcel_Chart_GridLines | |||||
*/ | |||||
private function activateObject() | |||||
{ | |||||
$this->objectState = true; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set Line Color Properties | |||||
* | |||||
* @param string $value | |||||
* @param int $alpha | |||||
* @param string $type | |||||
*/ | |||||
public function setLineColorProperties($value, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_STANDARD) | |||||
{ | |||||
$this->activateObject() | |||||
->lineProperties['color'] = $this->setColorProperties( | |||||
$value, | |||||
$alpha, | |||||
$type | |||||
); | |||||
} | |||||
/** | |||||
* Set Line Color Properties | |||||
* | |||||
* @param float $line_width | |||||
* @param string $compound_type | |||||
* @param string $dash_type | |||||
* @param string $cap_type | |||||
* @param string $join_type | |||||
* @param string $head_arrow_type | |||||
* @param string $head_arrow_size | |||||
* @param string $end_arrow_type | |||||
* @param string $end_arrow_size | |||||
*/ | |||||
public function setLineStyleProperties($line_width = null, $compound_type = null, $dash_type = null, $cap_type = null, $join_type = null, $head_arrow_type = null, $head_arrow_size = null, $end_arrow_type = null, $end_arrow_size = null) | |||||
{ | |||||
$this->activateObject(); | |||||
(!is_null($line_width)) | |||||
? $this->lineProperties['style']['width'] = $this->getExcelPointsWidth((float) $line_width) | |||||
: null; | |||||
(!is_null($compound_type)) | |||||
? $this->lineProperties['style']['compound'] = (string) $compound_type | |||||
: null; | |||||
(!is_null($dash_type)) | |||||
? $this->lineProperties['style']['dash'] = (string) $dash_type | |||||
: null; | |||||
(!is_null($cap_type)) | |||||
? $this->lineProperties['style']['cap'] = (string) $cap_type | |||||
: null; | |||||
(!is_null($join_type)) | |||||
? $this->lineProperties['style']['join'] = (string) $join_type | |||||
: null; | |||||
(!is_null($head_arrow_type)) | |||||
? $this->lineProperties['style']['arrow']['head']['type'] = (string) $head_arrow_type | |||||
: null; | |||||
(!is_null($head_arrow_size)) | |||||
? $this->lineProperties['style']['arrow']['head']['size'] = (string) $head_arrow_size | |||||
: null; | |||||
(!is_null($end_arrow_type)) | |||||
? $this->lineProperties['style']['arrow']['end']['type'] = (string) $end_arrow_type | |||||
: null; | |||||
(!is_null($end_arrow_size)) | |||||
? $this->lineProperties['style']['arrow']['end']['size'] = (string) $end_arrow_size | |||||
: null; | |||||
} | |||||
/** | |||||
* Get Line Color Property | |||||
* | |||||
* @param string $parameter | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getLineColorProperty($parameter) | |||||
{ | |||||
return $this->lineProperties['color'][$parameter]; | |||||
} | |||||
/** | |||||
* Get Line Style Property | |||||
* | |||||
* @param array|string $elements | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getLineStyleProperty($elements) | |||||
{ | |||||
return $this->getArrayElementsValue($this->lineProperties['style'], $elements); | |||||
} | |||||
/** | |||||
* Set Glow Properties | |||||
* | |||||
* @param float $size | |||||
* @param string $color_value | |||||
* @param int $color_alpha | |||||
* @param string $color_type | |||||
* | |||||
*/ | |||||
public function setGlowProperties($size, $color_value = null, $color_alpha = null, $color_type = null) | |||||
{ | |||||
$this | |||||
->activateObject() | |||||
->setGlowSize($size) | |||||
->setGlowColor($color_value, $color_alpha, $color_type); | |||||
} | |||||
/** | |||||
* Get Glow Color Property | |||||
* | |||||
* @param string $property | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getGlowColor($property) | |||||
{ | |||||
return $this->glowProperties['color'][$property]; | |||||
} | |||||
/** | |||||
* Get Glow Size | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getGlowSize() | |||||
{ | |||||
return $this->glowProperties['size']; | |||||
} | |||||
/** | |||||
* Set Glow Size | |||||
* | |||||
* @param float $size | |||||
* | |||||
* @return PHPExcel_Chart_GridLines | |||||
*/ | |||||
private function setGlowSize($size) | |||||
{ | |||||
$this->glowProperties['size'] = $this->getExcelPointsWidth((float) $size); | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set Glow Color | |||||
* | |||||
* @param string $color | |||||
* @param int $alpha | |||||
* @param string $type | |||||
* | |||||
* @return PHPExcel_Chart_GridLines | |||||
*/ | |||||
private function setGlowColor($color, $alpha, $type) | |||||
{ | |||||
if (!is_null($color)) { | |||||
$this->glowProperties['color']['value'] = (string) $color; | |||||
} | |||||
if (!is_null($alpha)) { | |||||
$this->glowProperties['color']['alpha'] = $this->getTrueAlpha((int) $alpha); | |||||
} | |||||
if (!is_null($type)) { | |||||
$this->glowProperties['color']['type'] = (string) $type; | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Line Style Arrow Parameters | |||||
* | |||||
* @param string $arrow_selector | |||||
* @param string $property_selector | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getLineStyleArrowParameters($arrow_selector, $property_selector) | |||||
{ | |||||
return $this->getLineStyleArrowSize($this->lineProperties['style']['arrow'][$arrow_selector]['size'], $property_selector); | |||||
} | |||||
/** | |||||
* Set Shadow Properties | |||||
* | |||||
* @param int $sh_presets | |||||
* @param string $sh_color_value | |||||
* @param string $sh_color_type | |||||
* @param int $sh_color_alpha | |||||
* @param string $sh_blur | |||||
* @param int $sh_angle | |||||
* @param float $sh_distance | |||||
* | |||||
*/ | |||||
public function setShadowProperties($sh_presets, $sh_color_value = null, $sh_color_type = null, $sh_color_alpha = null, $sh_blur = null, $sh_angle = null, $sh_distance = null) | |||||
{ | |||||
$this->activateObject() | |||||
->setShadowPresetsProperties((int) $sh_presets) | |||||
->setShadowColor( | |||||
is_null($sh_color_value) ? $this->shadowProperties['color']['value'] : $sh_color_value, | |||||
is_null($sh_color_alpha) ? (int) $this->shadowProperties['color']['alpha'] : $this->getTrueAlpha($sh_color_alpha), | |||||
is_null($sh_color_type) ? $this->shadowProperties['color']['type'] : $sh_color_type | |||||
) | |||||
->setShadowBlur($sh_blur) | |||||
->setShadowAngle($sh_angle) | |||||
->setShadowDistance($sh_distance); | |||||
} | |||||
/** | |||||
* Set Shadow Presets Properties | |||||
* | |||||
* @param int $shadow_presets | |||||
* | |||||
* @return PHPExcel_Chart_GridLines | |||||
*/ | |||||
private function setShadowPresetsProperties($shadow_presets) | |||||
{ | |||||
$this->shadowProperties['presets'] = $shadow_presets; | |||||
$this->setShadowProperiesMapValues($this->getShadowPresetsMap($shadow_presets)); | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set Shadow Properties Values | |||||
* | |||||
* @param array $properties_map | |||||
* @param * $reference | |||||
* | |||||
* @return PHPExcel_Chart_GridLines | |||||
*/ | |||||
private function setShadowProperiesMapValues(array $properties_map, &$reference = null) | |||||
{ | |||||
$base_reference = $reference; | |||||
foreach ($properties_map as $property_key => $property_val) { | |||||
if (is_array($property_val)) { | |||||
if ($reference === null) { | |||||
$reference = & $this->shadowProperties[$property_key]; | |||||
} else { | |||||
$reference = & $reference[$property_key]; | |||||
} | |||||
$this->setShadowProperiesMapValues($property_val, $reference); | |||||
} else { | |||||
if ($base_reference === null) { | |||||
$this->shadowProperties[$property_key] = $property_val; | |||||
} else { | |||||
$reference[$property_key] = $property_val; | |||||
} | |||||
} | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set Shadow Color | |||||
* | |||||
* @param string $color | |||||
* @param int $alpha | |||||
* @param string $type | |||||
* @return PHPExcel_Chart_GridLines | |||||
*/ | |||||
private function setShadowColor($color, $alpha, $type) | |||||
{ | |||||
if (!is_null($color)) { | |||||
$this->shadowProperties['color']['value'] = (string) $color; | |||||
} | |||||
if (!is_null($alpha)) { | |||||
$this->shadowProperties['color']['alpha'] = $this->getTrueAlpha((int) $alpha); | |||||
} | |||||
if (!is_null($type)) { | |||||
$this->shadowProperties['color']['type'] = (string) $type; | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set Shadow Blur | |||||
* | |||||
* @param float $blur | |||||
* | |||||
* @return PHPExcel_Chart_GridLines | |||||
*/ | |||||
private function setShadowBlur($blur) | |||||
{ | |||||
if ($blur !== null) { | |||||
$this->shadowProperties['blur'] = (string) $this->getExcelPointsWidth($blur); | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set Shadow Angle | |||||
* | |||||
* @param int $angle | |||||
* @return PHPExcel_Chart_GridLines | |||||
*/ | |||||
private function setShadowAngle($angle) | |||||
{ | |||||
if ($angle !== null) { | |||||
$this->shadowProperties['direction'] = (string) $this->getExcelPointsAngle($angle); | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set Shadow Distance | |||||
* | |||||
* @param float $distance | |||||
* @return PHPExcel_Chart_GridLines | |||||
*/ | |||||
private function setShadowDistance($distance) | |||||
{ | |||||
if ($distance !== null) { | |||||
$this->shadowProperties['distance'] = (string) $this->getExcelPointsWidth($distance); | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Shadow Property | |||||
* | |||||
* @param string $elements | |||||
* @param array $elements | |||||
* @return string | |||||
*/ | |||||
public function getShadowProperty($elements) | |||||
{ | |||||
return $this->getArrayElementsValue($this->shadowProperties, $elements); | |||||
} | |||||
/** | |||||
* Set Soft Edges Size | |||||
* | |||||
* @param float $size | |||||
*/ | |||||
public function setSoftEdgesSize($size) | |||||
{ | |||||
if (!is_null($size)) { | |||||
$this->activateObject(); | |||||
$softEdges['size'] = (string) $this->getExcelPointsWidth($size); | |||||
} | |||||
} | |||||
/** | |||||
* Get Soft Edges Size | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getSoftEdgesSize() | |||||
{ | |||||
return $this->softEdges['size']; | |||||
} | |||||
} |
@ -0,0 +1,486 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel | |||||
* | |||||
* 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_Chart | |||||
* @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## | |||||
*/ | |||||
/** | |||||
* PHPExcel_Chart_Layout | |||||
* | |||||
* @category PHPExcel | |||||
* @package PHPExcel_Chart | |||||
* @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | |||||
*/ | |||||
class PHPExcel_Chart_Layout | |||||
{ | |||||
/** | |||||
* layoutTarget | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $layoutTarget; | |||||
/** | |||||
* X Mode | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $xMode; | |||||
/** | |||||
* Y Mode | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $yMode; | |||||
/** | |||||
* X-Position | |||||
* | |||||
* @var float | |||||
*/ | |||||
private $xPos; | |||||
/** | |||||
* Y-Position | |||||
* | |||||
* @var float | |||||
*/ | |||||
private $yPos; | |||||
/** | |||||
* width | |||||
* | |||||
* @var float | |||||
*/ | |||||
private $width; | |||||
/** | |||||
* height | |||||
* | |||||
* @var float | |||||
*/ | |||||
private $height; | |||||
/** | |||||
* show legend key | |||||
* Specifies that legend keys should be shown in data labels | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $showLegendKey; | |||||
/** | |||||
* show value | |||||
* Specifies that the value should be shown in a data label. | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $showVal; | |||||
/** | |||||
* show category name | |||||
* Specifies that the category name should be shown in the data label. | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $showCatName; | |||||
/** | |||||
* show data series name | |||||
* Specifies that the series name should be shown in the data label. | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $showSerName; | |||||
/** | |||||
* show percentage | |||||
* Specifies that the percentage should be shown in the data label. | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $showPercent; | |||||
/** | |||||
* show bubble size | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $showBubbleSize; | |||||
/** | |||||
* show leader lines | |||||
* Specifies that leader lines should be shown for the data label. | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $showLeaderLines; | |||||
/** | |||||
* Create a new PHPExcel_Chart_Layout | |||||
*/ | |||||
public function __construct($layout = array()) | |||||
{ | |||||
if (isset($layout['layoutTarget'])) { | |||||
$this->layoutTarget = $layout['layoutTarget']; | |||||
} | |||||
if (isset($layout['xMode'])) { | |||||
$this->xMode = $layout['xMode']; | |||||
} | |||||
if (isset($layout['yMode'])) { | |||||
$this->yMode = $layout['yMode']; | |||||
} | |||||
if (isset($layout['x'])) { | |||||
$this->xPos = (float) $layout['x']; | |||||
} | |||||
if (isset($layout['y'])) { | |||||
$this->yPos = (float) $layout['y']; | |||||
} | |||||
if (isset($layout['w'])) { | |||||
$this->width = (float) $layout['w']; | |||||
} | |||||
if (isset($layout['h'])) { | |||||
$this->height = (float) $layout['h']; | |||||
} | |||||
} | |||||
/** | |||||
* Get Layout Target | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getLayoutTarget() | |||||
{ | |||||
return $this->layoutTarget; | |||||
} | |||||
/** | |||||
* Set Layout Target | |||||
* | |||||
* @param Layout Target $value | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function setLayoutTarget($value) | |||||
{ | |||||
$this->layoutTarget = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get X-Mode | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getXMode() | |||||
{ | |||||
return $this->xMode; | |||||
} | |||||
/** | |||||
* Set X-Mode | |||||
* | |||||
* @param X-Mode $value | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function setXMode($value) | |||||
{ | |||||
$this->xMode = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Y-Mode | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getYMode() | |||||
{ | |||||
return $this->yMode; | |||||
} | |||||
/** | |||||
* Set Y-Mode | |||||
* | |||||
* @param Y-Mode $value | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function setYMode($value) | |||||
{ | |||||
$this->yMode = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get X-Position | |||||
* | |||||
* @return number | |||||
*/ | |||||
public function getXPosition() | |||||
{ | |||||
return $this->xPos; | |||||
} | |||||
/** | |||||
* Set X-Position | |||||
* | |||||
* @param X-Position $value | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function setXPosition($value) | |||||
{ | |||||
$this->xPos = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Y-Position | |||||
* | |||||
* @return number | |||||
*/ | |||||
public function getYPosition() | |||||
{ | |||||
return $this->yPos; | |||||
} | |||||
/** | |||||
* Set Y-Position | |||||
* | |||||
* @param Y-Position $value | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function setYPosition($value) | |||||
{ | |||||
$this->yPos = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Width | |||||
* | |||||
* @return number | |||||
*/ | |||||
public function getWidth() | |||||
{ | |||||
return $this->width; | |||||
} | |||||
/** | |||||
* Set Width | |||||
* | |||||
* @param Width $value | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function setWidth($value) | |||||
{ | |||||
$this->width = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Height | |||||
* | |||||
* @return number | |||||
*/ | |||||
public function getHeight() | |||||
{ | |||||
return $this->height; | |||||
} | |||||
/** | |||||
* Set Height | |||||
* | |||||
* @param Height $value | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function setHeight($value) | |||||
{ | |||||
$this->height = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get show legend key | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getShowLegendKey() | |||||
{ | |||||
return $this->showLegendKey; | |||||
} | |||||
/** | |||||
* Set show legend key | |||||
* Specifies that legend keys should be shown in data labels. | |||||
* | |||||
* @param boolean $value Show legend key | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function setShowLegendKey($value) | |||||
{ | |||||
$this->showLegendKey = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get show value | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getShowVal() | |||||
{ | |||||
return $this->showVal; | |||||
} | |||||
/** | |||||
* Set show val | |||||
* Specifies that the value should be shown in data labels. | |||||
* | |||||
* @param boolean $value Show val | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function setShowVal($value) | |||||
{ | |||||
$this->showVal = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get show category name | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getShowCatName() | |||||
{ | |||||
return $this->showCatName; | |||||
} | |||||
/** | |||||
* Set show cat name | |||||
* Specifies that the category name should be shown in data labels. | |||||
* | |||||
* @param boolean $value Show cat name | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function setShowCatName($value) | |||||
{ | |||||
$this->showCatName = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get show data series name | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getShowSerName() | |||||
{ | |||||
return $this->showSerName; | |||||
} | |||||
/** | |||||
* Set show ser name | |||||
* Specifies that the series name should be shown in data labels. | |||||
* | |||||
* @param boolean $value Show series name | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function setShowSerName($value) | |||||
{ | |||||
$this->showSerName = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get show percentage | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getShowPercent() | |||||
{ | |||||
return $this->showPercent; | |||||
} | |||||
/** | |||||
* Set show percentage | |||||
* Specifies that the percentage should be shown in data labels. | |||||
* | |||||
* @param boolean $value Show percentage | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function setShowPercent($value) | |||||
{ | |||||
$this->showPercent = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get show bubble size | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getShowBubbleSize() | |||||
{ | |||||
return $this->showBubbleSize; | |||||
} | |||||
/** | |||||
* Set show bubble size | |||||
* Specifies that the bubble size should be shown in data labels. | |||||
* | |||||
* @param boolean $value Show bubble size | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function setShowBubbleSize($value) | |||||
{ | |||||
$this->showBubbleSize = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get show leader lines | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getShowLeaderLines() | |||||
{ | |||||
return $this->showLeaderLines; | |||||
} | |||||
/** | |||||
* Set show leader lines | |||||
* Specifies that leader lines should be shown in data labels. | |||||
* | |||||
* @param boolean $value Show leader lines | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function setShowLeaderLines($value) | |||||
{ | |||||
$this->showLeaderLines = $value; | |||||
return $this; | |||||
} | |||||
} |
@ -0,0 +1,170 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Chart_Legend | |||||
* | |||||
* 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_Chart | |||||
* @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_Chart_Legend | |||||
{ | |||||
/** Legend positions */ | |||||
const xlLegendPositionBottom = -4107; // Below the chart. | |||||
const xlLegendPositionCorner = 2; // In the upper right-hand corner of the chart border. | |||||
const xlLegendPositionCustom = -4161; // A custom position. | |||||
const xlLegendPositionLeft = -4131; // Left of the chart. | |||||
const xlLegendPositionRight = -4152; // Right of the chart. | |||||
const xlLegendPositionTop = -4160; // Above the chart. | |||||
const POSITION_RIGHT = 'r'; | |||||
const POSITION_LEFT = 'l'; | |||||
const POSITION_BOTTOM = 'b'; | |||||
const POSITION_TOP = 't'; | |||||
const POSITION_TOPRIGHT = 'tr'; | |||||
private static $positionXLref = array( | |||||
self::xlLegendPositionBottom => self::POSITION_BOTTOM, | |||||
self::xlLegendPositionCorner => self::POSITION_TOPRIGHT, | |||||
self::xlLegendPositionCustom => '??', | |||||
self::xlLegendPositionLeft => self::POSITION_LEFT, | |||||
self::xlLegendPositionRight => self::POSITION_RIGHT, | |||||
self::xlLegendPositionTop => self::POSITION_TOP | |||||
); | |||||
/** | |||||
* Legend position | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $position = self::POSITION_RIGHT; | |||||
/** | |||||
* Allow overlay of other elements? | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $overlay = true; | |||||
/** | |||||
* Legend Layout | |||||
* | |||||
* @var PHPExcel_Chart_Layout | |||||
*/ | |||||
private $layout = null; | |||||
/** | |||||
* Create a new PHPExcel_Chart_Legend | |||||
*/ | |||||
public function __construct($position = self::POSITION_RIGHT, PHPExcel_Chart_Layout $layout = null, $overlay = false) | |||||
{ | |||||
$this->setPosition($position); | |||||
$this->layout = $layout; | |||||
$this->setOverlay($overlay); | |||||
} | |||||
/** | |||||
* Get legend position as an excel string value | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getPosition() | |||||
{ | |||||
return $this->position; | |||||
} | |||||
/** | |||||
* Get legend position using an excel string value | |||||
* | |||||
* @param string $position | |||||
*/ | |||||
public function setPosition($position = self::POSITION_RIGHT) | |||||
{ | |||||
if (!in_array($position, self::$positionXLref)) { | |||||
return false; | |||||
} | |||||
$this->position = $position; | |||||
return true; | |||||
} | |||||
/** | |||||
* Get legend position as an Excel internal numeric value | |||||
* | |||||
* @return number | |||||
*/ | |||||
public function getPositionXL() | |||||
{ | |||||
return array_search($this->position, self::$positionXLref); | |||||
} | |||||
/** | |||||
* Set legend position using an Excel internal numeric value | |||||
* | |||||
* @param number $positionXL | |||||
*/ | |||||
public function setPositionXL($positionXL = self::xlLegendPositionRight) | |||||
{ | |||||
if (!array_key_exists($positionXL, self::$positionXLref)) { | |||||
return false; | |||||
} | |||||
$this->position = self::$positionXLref[$positionXL]; | |||||
return true; | |||||
} | |||||
/** | |||||
* Get allow overlay of other elements? | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getOverlay() | |||||
{ | |||||
return $this->overlay; | |||||
} | |||||
/** | |||||
* Set allow overlay of other elements? | |||||
* | |||||
* @param boolean $overlay | |||||
* @return boolean | |||||
*/ | |||||
public function setOverlay($overlay = false) | |||||
{ | |||||
if (!is_bool($overlay)) { | |||||
return false; | |||||
} | |||||
$this->overlay = $overlay; | |||||
return true; | |||||
} | |||||
/** | |||||
* Get Layout | |||||
* | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function getLayout() | |||||
{ | |||||
return $this->layout; | |||||
} | |||||
} |
@ -0,0 +1,126 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Chart_PlotArea | |||||
* | |||||
* 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_Chart | |||||
* @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_Chart_PlotArea | |||||
{ | |||||
/** | |||||
* PlotArea Layout | |||||
* | |||||
* @var PHPExcel_Chart_Layout | |||||
*/ | |||||
private $layout = null; | |||||
/** | |||||
* Plot Series | |||||
* | |||||
* @var array of PHPExcel_Chart_DataSeries | |||||
*/ | |||||
private $plotSeries = array(); | |||||
/** | |||||
* Create a new PHPExcel_Chart_PlotArea | |||||
*/ | |||||
public function __construct(PHPExcel_Chart_Layout $layout = null, $plotSeries = array()) | |||||
{ | |||||
$this->layout = $layout; | |||||
$this->plotSeries = $plotSeries; | |||||
} | |||||
/** | |||||
* Get Layout | |||||
* | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function getLayout() | |||||
{ | |||||
return $this->layout; | |||||
} | |||||
/** | |||||
* Get Number of Plot Groups | |||||
* | |||||
* @return array of PHPExcel_Chart_DataSeries | |||||
*/ | |||||
public function getPlotGroupCount() | |||||
{ | |||||
return count($this->plotSeries); | |||||
} | |||||
/** | |||||
* Get Number of Plot Series | |||||
* | |||||
* @return integer | |||||
*/ | |||||
public function getPlotSeriesCount() | |||||
{ | |||||
$seriesCount = 0; | |||||
foreach ($this->plotSeries as $plot) { | |||||
$seriesCount += $plot->getPlotSeriesCount(); | |||||
} | |||||
return $seriesCount; | |||||
} | |||||
/** | |||||
* Get Plot Series | |||||
* | |||||
* @return array of PHPExcel_Chart_DataSeries | |||||
*/ | |||||
public function getPlotGroup() | |||||
{ | |||||
return $this->plotSeries; | |||||
} | |||||
/** | |||||
* Get Plot Series by Index | |||||
* | |||||
* @return PHPExcel_Chart_DataSeries | |||||
*/ | |||||
public function getPlotGroupByIndex($index) | |||||
{ | |||||
return $this->plotSeries[$index]; | |||||
} | |||||
/** | |||||
* Set Plot Series | |||||
* | |||||
* @param [PHPExcel_Chart_DataSeries] | |||||
* @return PHPExcel_Chart_PlotArea | |||||
*/ | |||||
public function setPlotSeries($plotSeries = array()) | |||||
{ | |||||
$this->plotSeries = $plotSeries; | |||||
return $this; | |||||
} | |||||
public function refresh(PHPExcel_Worksheet $worksheet) | |||||
{ | |||||
foreach ($this->plotSeries as $plotSeries) { | |||||
$plotSeries->refresh($worksheet); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,363 @@ | |||||
<?php | |||||
/** | |||||
* Created by PhpStorm. | |||||
* User: nhw2h8s | |||||
* Date: 7/2/14 | |||||
* Time: 5:45 PM | |||||
*/ | |||||
abstract class PHPExcel_Chart_Properties | |||||
{ | |||||
const | |||||
EXCEL_COLOR_TYPE_STANDARD = 'prstClr', | |||||
EXCEL_COLOR_TYPE_SCHEME = 'schemeClr', | |||||
EXCEL_COLOR_TYPE_ARGB = 'srgbClr'; | |||||
const | |||||
AXIS_LABELS_LOW = 'low', | |||||
AXIS_LABELS_HIGH = 'high', | |||||
AXIS_LABELS_NEXT_TO = 'nextTo', | |||||
AXIS_LABELS_NONE = 'none'; | |||||
const | |||||
TICK_MARK_NONE = 'none', | |||||
TICK_MARK_INSIDE = 'in', | |||||
TICK_MARK_OUTSIDE = 'out', | |||||
TICK_MARK_CROSS = 'cross'; | |||||
const | |||||
HORIZONTAL_CROSSES_AUTOZERO = 'autoZero', | |||||
HORIZONTAL_CROSSES_MAXIMUM = 'max'; | |||||
const | |||||
FORMAT_CODE_GENERAL = 'General', | |||||
FORMAT_CODE_NUMBER = '#,##0.00', | |||||
FORMAT_CODE_CURRENCY = '$#,##0.00', | |||||
FORMAT_CODE_ACCOUNTING = '_($* #,##0.00_);_($* (#,##0.00);_($* "-"??_);_(@_)', | |||||
FORMAT_CODE_DATE = 'm/d/yyyy', | |||||
FORMAT_CODE_TIME = '[$-F400]h:mm:ss AM/PM', | |||||
FORMAT_CODE_PERCENTAGE = '0.00%', | |||||
FORMAT_CODE_FRACTION = '# ?/?', | |||||
FORMAT_CODE_SCIENTIFIC = '0.00E+00', | |||||
FORMAT_CODE_TEXT = '@', | |||||
FORMAT_CODE_SPECIAL = '00000'; | |||||
const | |||||
ORIENTATION_NORMAL = 'minMax', | |||||
ORIENTATION_REVERSED = 'maxMin'; | |||||
const | |||||
LINE_STYLE_COMPOUND_SIMPLE = 'sng', | |||||
LINE_STYLE_COMPOUND_DOUBLE = 'dbl', | |||||
LINE_STYLE_COMPOUND_THICKTHIN = 'thickThin', | |||||
LINE_STYLE_COMPOUND_THINTHICK = 'thinThick', | |||||
LINE_STYLE_COMPOUND_TRIPLE = 'tri', | |||||
LINE_STYLE_DASH_SOLID = 'solid', | |||||
LINE_STYLE_DASH_ROUND_DOT = 'sysDot', | |||||
LINE_STYLE_DASH_SQUERE_DOT = 'sysDash', | |||||
LINE_STYPE_DASH_DASH = 'dash', | |||||
LINE_STYLE_DASH_DASH_DOT = 'dashDot', | |||||
LINE_STYLE_DASH_LONG_DASH = 'lgDash', | |||||
LINE_STYLE_DASH_LONG_DASH_DOT = 'lgDashDot', | |||||
LINE_STYLE_DASH_LONG_DASH_DOT_DOT = 'lgDashDotDot', | |||||
LINE_STYLE_CAP_SQUARE = 'sq', | |||||
LINE_STYLE_CAP_ROUND = 'rnd', | |||||
LINE_STYLE_CAP_FLAT = 'flat', | |||||
LINE_STYLE_JOIN_ROUND = 'bevel', | |||||
LINE_STYLE_JOIN_MITER = 'miter', | |||||
LINE_STYLE_JOIN_BEVEL = 'bevel', | |||||
LINE_STYLE_ARROW_TYPE_NOARROW = null, | |||||
LINE_STYLE_ARROW_TYPE_ARROW = 'triangle', | |||||
LINE_STYLE_ARROW_TYPE_OPEN = 'arrow', | |||||
LINE_STYLE_ARROW_TYPE_STEALTH = 'stealth', | |||||
LINE_STYLE_ARROW_TYPE_DIAMOND = 'diamond', | |||||
LINE_STYLE_ARROW_TYPE_OVAL = 'oval', | |||||
LINE_STYLE_ARROW_SIZE_1 = 1, | |||||
LINE_STYLE_ARROW_SIZE_2 = 2, | |||||
LINE_STYLE_ARROW_SIZE_3 = 3, | |||||
LINE_STYLE_ARROW_SIZE_4 = 4, | |||||
LINE_STYLE_ARROW_SIZE_5 = 5, | |||||
LINE_STYLE_ARROW_SIZE_6 = 6, | |||||
LINE_STYLE_ARROW_SIZE_7 = 7, | |||||
LINE_STYLE_ARROW_SIZE_8 = 8, | |||||
LINE_STYLE_ARROW_SIZE_9 = 9; | |||||
const | |||||
SHADOW_PRESETS_NOSHADOW = null, | |||||
SHADOW_PRESETS_OUTER_BOTTTOM_RIGHT = 1, | |||||
SHADOW_PRESETS_OUTER_BOTTOM = 2, | |||||
SHADOW_PRESETS_OUTER_BOTTOM_LEFT = 3, | |||||
SHADOW_PRESETS_OUTER_RIGHT = 4, | |||||
SHADOW_PRESETS_OUTER_CENTER = 5, | |||||
SHADOW_PRESETS_OUTER_LEFT = 6, | |||||
SHADOW_PRESETS_OUTER_TOP_RIGHT = 7, | |||||
SHADOW_PRESETS_OUTER_TOP = 8, | |||||
SHADOW_PRESETS_OUTER_TOP_LEFT = 9, | |||||
SHADOW_PRESETS_INNER_BOTTTOM_RIGHT = 10, | |||||
SHADOW_PRESETS_INNER_BOTTOM = 11, | |||||
SHADOW_PRESETS_INNER_BOTTOM_LEFT = 12, | |||||
SHADOW_PRESETS_INNER_RIGHT = 13, | |||||
SHADOW_PRESETS_INNER_CENTER = 14, | |||||
SHADOW_PRESETS_INNER_LEFT = 15, | |||||
SHADOW_PRESETS_INNER_TOP_RIGHT = 16, | |||||
SHADOW_PRESETS_INNER_TOP = 17, | |||||
SHADOW_PRESETS_INNER_TOP_LEFT = 18, | |||||
SHADOW_PRESETS_PERSPECTIVE_BELOW = 19, | |||||
SHADOW_PRESETS_PERSPECTIVE_UPPER_RIGHT = 20, | |||||
SHADOW_PRESETS_PERSPECTIVE_UPPER_LEFT = 21, | |||||
SHADOW_PRESETS_PERSPECTIVE_LOWER_RIGHT = 22, | |||||
SHADOW_PRESETS_PERSPECTIVE_LOWER_LEFT = 23; | |||||
protected function getExcelPointsWidth($width) | |||||
{ | |||||
return $width * 12700; | |||||
} | |||||
protected function getExcelPointsAngle($angle) | |||||
{ | |||||
return $angle * 60000; | |||||
} | |||||
protected function getTrueAlpha($alpha) | |||||
{ | |||||
return (string) 100 - $alpha . '000'; | |||||
} | |||||
protected function setColorProperties($color, $alpha, $type) | |||||
{ | |||||
return array( | |||||
'type' => (string) $type, | |||||
'value' => (string) $color, | |||||
'alpha' => (string) $this->getTrueAlpha($alpha) | |||||
); | |||||
} | |||||
protected function getLineStyleArrowSize($array_selector, $array_kay_selector) | |||||
{ | |||||
$sizes = array( | |||||
1 => array('w' => 'sm', 'len' => 'sm'), | |||||
2 => array('w' => 'sm', 'len' => 'med'), | |||||
3 => array('w' => 'sm', 'len' => 'lg'), | |||||
4 => array('w' => 'med', 'len' => 'sm'), | |||||
5 => array('w' => 'med', 'len' => 'med'), | |||||
6 => array('w' => 'med', 'len' => 'lg'), | |||||
7 => array('w' => 'lg', 'len' => 'sm'), | |||||
8 => array('w' => 'lg', 'len' => 'med'), | |||||
9 => array('w' => 'lg', 'len' => 'lg') | |||||
); | |||||
return $sizes[$array_selector][$array_kay_selector]; | |||||
} | |||||
protected function getShadowPresetsMap($shadow_presets_option) | |||||
{ | |||||
$presets_options = array( | |||||
//OUTER | |||||
1 => array( | |||||
'effect' => 'outerShdw', | |||||
'blur' => '50800', | |||||
'distance' => '38100', | |||||
'direction' => '2700000', | |||||
'algn' => 'tl', | |||||
'rotWithShape' => '0' | |||||
), | |||||
2 => array( | |||||
'effect' => 'outerShdw', | |||||
'blur' => '50800', | |||||
'distance' => '38100', | |||||
'direction' => '5400000', | |||||
'algn' => 't', | |||||
'rotWithShape' => '0' | |||||
), | |||||
3 => array( | |||||
'effect' => 'outerShdw', | |||||
'blur' => '50800', | |||||
'distance' => '38100', | |||||
'direction' => '8100000', | |||||
'algn' => 'tr', | |||||
'rotWithShape' => '0' | |||||
), | |||||
4 => array( | |||||
'effect' => 'outerShdw', | |||||
'blur' => '50800', | |||||
'distance' => '38100', | |||||
'algn' => 'l', | |||||
'rotWithShape' => '0' | |||||
), | |||||
5 => array( | |||||
'effect' => 'outerShdw', | |||||
'size' => array( | |||||
'sx' => '102000', | |||||
'sy' => '102000' | |||||
) | |||||
, | |||||
'blur' => '63500', | |||||
'distance' => '38100', | |||||
'algn' => 'ctr', | |||||
'rotWithShape' => '0' | |||||
), | |||||
6 => array( | |||||
'effect' => 'outerShdw', | |||||
'blur' => '50800', | |||||
'distance' => '38100', | |||||
'direction' => '10800000', | |||||
'algn' => 'r', | |||||
'rotWithShape' => '0' | |||||
), | |||||
7 => array( | |||||
'effect' => 'outerShdw', | |||||
'blur' => '50800', | |||||
'distance' => '38100', | |||||
'direction' => '18900000', | |||||
'algn' => 'bl', | |||||
'rotWithShape' => '0' | |||||
), | |||||
8 => array( | |||||
'effect' => 'outerShdw', | |||||
'blur' => '50800', | |||||
'distance' => '38100', | |||||
'direction' => '16200000', | |||||
'rotWithShape' => '0' | |||||
), | |||||
9 => array( | |||||
'effect' => 'outerShdw', | |||||
'blur' => '50800', | |||||
'distance' => '38100', | |||||
'direction' => '13500000', | |||||
'algn' => 'br', | |||||
'rotWithShape' => '0' | |||||
), | |||||
//INNER | |||||
10 => array( | |||||
'effect' => 'innerShdw', | |||||
'blur' => '63500', | |||||
'distance' => '50800', | |||||
'direction' => '2700000', | |||||
), | |||||
11 => array( | |||||
'effect' => 'innerShdw', | |||||
'blur' => '63500', | |||||
'distance' => '50800', | |||||
'direction' => '5400000', | |||||
), | |||||
12 => array( | |||||
'effect' => 'innerShdw', | |||||
'blur' => '63500', | |||||
'distance' => '50800', | |||||
'direction' => '8100000', | |||||
), | |||||
13 => array( | |||||
'effect' => 'innerShdw', | |||||
'blur' => '63500', | |||||
'distance' => '50800', | |||||
), | |||||
14 => array( | |||||
'effect' => 'innerShdw', | |||||
'blur' => '114300', | |||||
), | |||||
15 => array( | |||||
'effect' => 'innerShdw', | |||||
'blur' => '63500', | |||||
'distance' => '50800', | |||||
'direction' => '10800000', | |||||
), | |||||
16 => array( | |||||
'effect' => 'innerShdw', | |||||
'blur' => '63500', | |||||
'distance' => '50800', | |||||
'direction' => '18900000', | |||||
), | |||||
17 => array( | |||||
'effect' => 'innerShdw', | |||||
'blur' => '63500', | |||||
'distance' => '50800', | |||||
'direction' => '16200000', | |||||
), | |||||
18 => array( | |||||
'effect' => 'innerShdw', | |||||
'blur' => '63500', | |||||
'distance' => '50800', | |||||
'direction' => '13500000', | |||||
), | |||||
//perspective | |||||
19 => array( | |||||
'effect' => 'outerShdw', | |||||
'blur' => '152400', | |||||
'distance' => '317500', | |||||
'size' => array( | |||||
'sx' => '90000', | |||||
'sy' => '-19000', | |||||
), | |||||
'direction' => '5400000', | |||||
'rotWithShape' => '0', | |||||
), | |||||
20 => array( | |||||
'effect' => 'outerShdw', | |||||
'blur' => '76200', | |||||
'direction' => '18900000', | |||||
'size' => array( | |||||
'sy' => '23000', | |||||
'kx' => '-1200000', | |||||
), | |||||
'algn' => 'bl', | |||||
'rotWithShape' => '0', | |||||
), | |||||
21 => array( | |||||
'effect' => 'outerShdw', | |||||
'blur' => '76200', | |||||
'direction' => '13500000', | |||||
'size' => array( | |||||
'sy' => '23000', | |||||
'kx' => '1200000', | |||||
), | |||||
'algn' => 'br', | |||||
'rotWithShape' => '0', | |||||
), | |||||
22 => array( | |||||
'effect' => 'outerShdw', | |||||
'blur' => '76200', | |||||
'distance' => '12700', | |||||
'direction' => '2700000', | |||||
'size' => array( | |||||
'sy' => '-23000', | |||||
'kx' => '-800400', | |||||
), | |||||
'algn' => 'bl', | |||||
'rotWithShape' => '0', | |||||
), | |||||
23 => array( | |||||
'effect' => 'outerShdw', | |||||
'blur' => '76200', | |||||
'distance' => '12700', | |||||
'direction' => '8100000', | |||||
'size' => array( | |||||
'sy' => '-23000', | |||||
'kx' => '800400', | |||||
), | |||||
'algn' => 'br', | |||||
'rotWithShape' => '0', | |||||
), | |||||
); | |||||
return $presets_options[$shadow_presets_option]; | |||||
} | |||||
protected function getArrayElementsValue($properties, $elements) | |||||
{ | |||||
$reference = & $properties; | |||||
if (!is_array($elements)) { | |||||
return $reference[$elements]; | |||||
} else { | |||||
foreach ($elements as $keys) { | |||||
$reference = & $reference[$keys]; | |||||
} | |||||
return $reference; | |||||
} | |||||
return $this; | |||||
} | |||||
} |
@ -0,0 +1,20 @@ | |||||
ChartDirector | |||||
http://www.advsofteng.com/cdphp.html | |||||
GraPHPite | |||||
http://graphpite.sourceforge.net/ | |||||
JpGraph | |||||
http://www.aditus.nu/jpgraph/ | |||||
LibChart | |||||
http://naku.dohcrew.com/libchart/pages/introduction/ | |||||
pChart | |||||
http://pchart.sourceforge.net/ | |||||
TeeChart | |||||
http://www.steema.com/products/teechart/overview.html | |||||
PHPGraphLib | |||||
http://www.ebrueggeman.com/phpgraphlib |
@ -0,0 +1,883 @@ | |||||
<?php | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'/jpgraph.php'); | |||||
/** | |||||
* PHPExcel_Chart_Renderer_jpgraph | |||||
* | |||||
* 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_Chart_Renderer | |||||
* @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_Chart_Renderer_jpgraph | |||||
{ | |||||
private static $width = 640; | |||||
private static $height = 480; | |||||
private static $colourSet = array( | |||||
'mediumpurple1', 'palegreen3', 'gold1', 'cadetblue1', | |||||
'darkmagenta', 'coral', 'dodgerblue3', 'eggplant', | |||||
'mediumblue', 'magenta', 'sandybrown', 'cyan', | |||||
'firebrick1', 'forestgreen', 'deeppink4', 'darkolivegreen', | |||||
'goldenrod2' | |||||
); | |||||
private static $markSet = array( | |||||
'diamond' => MARK_DIAMOND, | |||||
'square' => MARK_SQUARE, | |||||
'triangle' => MARK_UTRIANGLE, | |||||
'x' => MARK_X, | |||||
'star' => MARK_STAR, | |||||
'dot' => MARK_FILLEDCIRCLE, | |||||
'dash' => MARK_DTRIANGLE, | |||||
'circle' => MARK_CIRCLE, | |||||
'plus' => MARK_CROSS | |||||
); | |||||
private $chart; | |||||
private $graph; | |||||
private static $plotColour = 0; | |||||
private static $plotMark = 0; | |||||
private function formatPointMarker($seriesPlot, $markerID) | |||||
{ | |||||
$plotMarkKeys = array_keys(self::$markSet); | |||||
if (is_null($markerID)) { | |||||
// Use default plot marker (next marker in the series) | |||||
self::$plotMark %= count(self::$markSet); | |||||
$seriesPlot->mark->SetType(self::$markSet[$plotMarkKeys[self::$plotMark++]]); | |||||
} elseif ($markerID !== 'none') { | |||||
// Use specified plot marker (if it exists) | |||||
if (isset(self::$markSet[$markerID])) { | |||||
$seriesPlot->mark->SetType(self::$markSet[$markerID]); | |||||
} else { | |||||
// If the specified plot marker doesn't exist, use default plot marker (next marker in the series) | |||||
self::$plotMark %= count(self::$markSet); | |||||
$seriesPlot->mark->SetType(self::$markSet[$plotMarkKeys[self::$plotMark++]]); | |||||
} | |||||
} else { | |||||
// Hide plot marker | |||||
$seriesPlot->mark->Hide(); | |||||
} | |||||
$seriesPlot->mark->SetColor(self::$colourSet[self::$plotColour]); | |||||
$seriesPlot->mark->SetFillColor(self::$colourSet[self::$plotColour]); | |||||
$seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); | |||||
return $seriesPlot; | |||||
} | |||||
private function formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation = '') | |||||
{ | |||||
$datasetLabelFormatCode = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getFormatCode(); | |||||
if (!is_null($datasetLabelFormatCode)) { | |||||
// Retrieve any label formatting code | |||||
$datasetLabelFormatCode = stripslashes($datasetLabelFormatCode); | |||||
} | |||||
$testCurrentIndex = 0; | |||||
foreach ($datasetLabels as $i => $datasetLabel) { | |||||
if (is_array($datasetLabel)) { | |||||
if ($rotation == 'bar') { | |||||
$datasetLabels[$i] = implode(" ", $datasetLabel); | |||||
} else { | |||||
$datasetLabel = array_reverse($datasetLabel); | |||||
$datasetLabels[$i] = implode("\n", $datasetLabel); | |||||
} | |||||
} else { | |||||
// Format labels according to any formatting code | |||||
if (!is_null($datasetLabelFormatCode)) { | |||||
$datasetLabels[$i] = PHPExcel_Style_NumberFormat::toFormattedString($datasetLabel, $datasetLabelFormatCode); | |||||
} | |||||
} | |||||
++$testCurrentIndex; | |||||
} | |||||
return $datasetLabels; | |||||
} | |||||
private function percentageSumCalculation($groupID, $seriesCount) | |||||
{ | |||||
// Adjust our values to a percentage value across all series in the group | |||||
for ($i = 0; $i < $seriesCount; ++$i) { | |||||
if ($i == 0) { | |||||
$sumValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); | |||||
} else { | |||||
$nextValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); | |||||
foreach ($nextValues as $k => $value) { | |||||
if (isset($sumValues[$k])) { | |||||
$sumValues[$k] += $value; | |||||
} else { | |||||
$sumValues[$k] = $value; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return $sumValues; | |||||
} | |||||
private function percentageAdjustValues($dataValues, $sumValues) | |||||
{ | |||||
foreach ($dataValues as $k => $dataValue) { | |||||
$dataValues[$k] = $dataValue / $sumValues[$k] * 100; | |||||
} | |||||
return $dataValues; | |||||
} | |||||
private function getCaption($captionElement) | |||||
{ | |||||
// Read any caption | |||||
$caption = (!is_null($captionElement)) ? $captionElement->getCaption() : null; | |||||
// Test if we have a title caption to display | |||||
if (!is_null($caption)) { | |||||
// If we do, it could be a plain string or an array | |||||
if (is_array($caption)) { | |||||
// Implode an array to a plain string | |||||
$caption = implode('', $caption); | |||||
} | |||||
} | |||||
return $caption; | |||||
} | |||||
private function renderTitle() | |||||
{ | |||||
$title = $this->getCaption($this->chart->getTitle()); | |||||
if (!is_null($title)) { | |||||
$this->graph->title->Set($title); | |||||
} | |||||
} | |||||
private function renderLegend() | |||||
{ | |||||
$legend = $this->chart->getLegend(); | |||||
if (!is_null($legend)) { | |||||
$legendPosition = $legend->getPosition(); | |||||
$legendOverlay = $legend->getOverlay(); | |||||
switch ($legendPosition) { | |||||
case 'r': | |||||
$this->graph->legend->SetPos(0.01, 0.5, 'right', 'center'); // right | |||||
$this->graph->legend->SetColumns(1); | |||||
break; | |||||
case 'l': | |||||
$this->graph->legend->SetPos(0.01, 0.5, 'left', 'center'); // left | |||||
$this->graph->legend->SetColumns(1); | |||||
break; | |||||
case 't': | |||||
$this->graph->legend->SetPos(0.5, 0.01, 'center', 'top'); // top | |||||
break; | |||||
case 'b': | |||||
$this->graph->legend->SetPos(0.5, 0.99, 'center', 'bottom'); // bottom | |||||
break; | |||||
default: | |||||
$this->graph->legend->SetPos(0.01, 0.01, 'right', 'top'); // top-right | |||||
$this->graph->legend->SetColumns(1); | |||||
break; | |||||
} | |||||
} else { | |||||
$this->graph->legend->Hide(); | |||||
} | |||||
} | |||||
private function renderCartesianPlotArea($type = 'textlin') | |||||
{ | |||||
$this->graph = new Graph(self::$width, self::$height); | |||||
$this->graph->SetScale($type); | |||||
$this->renderTitle(); | |||||
// Rotate for bar rather than column chart | |||||
$rotation = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotDirection(); | |||||
$reverse = ($rotation == 'bar') ? true : false; | |||||
$xAxisLabel = $this->chart->getXAxisLabel(); | |||||
if (!is_null($xAxisLabel)) { | |||||
$title = $this->getCaption($xAxisLabel); | |||||
if (!is_null($title)) { | |||||
$this->graph->xaxis->SetTitle($title, 'center'); | |||||
$this->graph->xaxis->title->SetMargin(35); | |||||
if ($reverse) { | |||||
$this->graph->xaxis->title->SetAngle(90); | |||||
$this->graph->xaxis->title->SetMargin(90); | |||||
} | |||||
} | |||||
} | |||||
$yAxisLabel = $this->chart->getYAxisLabel(); | |||||
if (!is_null($yAxisLabel)) { | |||||
$title = $this->getCaption($yAxisLabel); | |||||
if (!is_null($title)) { | |||||
$this->graph->yaxis->SetTitle($title, 'center'); | |||||
if ($reverse) { | |||||
$this->graph->yaxis->title->SetAngle(0); | |||||
$this->graph->yaxis->title->SetMargin(-55); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
private function renderPiePlotArea($doughnut = false) | |||||
{ | |||||
$this->graph = new PieGraph(self::$width, self::$height); | |||||
$this->renderTitle(); | |||||
} | |||||
private function renderRadarPlotArea() | |||||
{ | |||||
$this->graph = new RadarGraph(self::$width, self::$height); | |||||
$this->graph->SetScale('lin'); | |||||
$this->renderTitle(); | |||||
} | |||||
private function renderPlotLine($groupID, $filled = false, $combination = false, $dimensions = '2d') | |||||
{ | |||||
$grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); | |||||
$labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); | |||||
if ($labelCount > 0) { | |||||
$datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); | |||||
$datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); | |||||
$this->graph->xaxis->SetTickLabels($datasetLabels); | |||||
} | |||||
$seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); | |||||
$seriesPlots = array(); | |||||
if ($grouping == 'percentStacked') { | |||||
$sumValues = $this->percentageSumCalculation($groupID, $seriesCount); | |||||
} | |||||
// Loop through each data series in turn | |||||
for ($i = 0; $i < $seriesCount; ++$i) { | |||||
$dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); | |||||
$marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); | |||||
if ($grouping == 'percentStacked') { | |||||
$dataValues = $this->percentageAdjustValues($dataValues, $sumValues); | |||||
} | |||||
// Fill in any missing values in the $dataValues array | |||||
$testCurrentIndex = 0; | |||||
foreach ($dataValues as $k => $dataValue) { | |||||
while ($k != $testCurrentIndex) { | |||||
$dataValues[$testCurrentIndex] = null; | |||||
++$testCurrentIndex; | |||||
} | |||||
++$testCurrentIndex; | |||||
} | |||||
$seriesPlot = new LinePlot($dataValues); | |||||
if ($combination) { | |||||
$seriesPlot->SetBarCenter(); | |||||
} | |||||
if ($filled) { | |||||
$seriesPlot->SetFilled(true); | |||||
$seriesPlot->SetColor('black'); | |||||
$seriesPlot->SetFillColor(self::$colourSet[self::$plotColour++]); | |||||
} else { | |||||
// Set the appropriate plot marker | |||||
$this->formatPointMarker($seriesPlot, $marker); | |||||
} | |||||
$dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); | |||||
$seriesPlot->SetLegend($dataLabel); | |||||
$seriesPlots[] = $seriesPlot; | |||||
} | |||||
if ($grouping == 'standard') { | |||||
$groupPlot = $seriesPlots; | |||||
} else { | |||||
$groupPlot = new AccLinePlot($seriesPlots); | |||||
} | |||||
$this->graph->Add($groupPlot); | |||||
} | |||||
private function renderPlotBar($groupID, $dimensions = '2d') | |||||
{ | |||||
$rotation = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotDirection(); | |||||
// Rotate for bar rather than column chart | |||||
if (($groupID == 0) && ($rotation == 'bar')) { | |||||
$this->graph->Set90AndMargin(); | |||||
} | |||||
$grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); | |||||
$labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); | |||||
if ($labelCount > 0) { | |||||
$datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); | |||||
$datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation); | |||||
// Rotate for bar rather than column chart | |||||
if ($rotation == 'bar') { | |||||
$datasetLabels = array_reverse($datasetLabels); | |||||
$this->graph->yaxis->SetPos('max'); | |||||
$this->graph->yaxis->SetLabelAlign('center', 'top'); | |||||
$this->graph->yaxis->SetLabelSide(SIDE_RIGHT); | |||||
} | |||||
$this->graph->xaxis->SetTickLabels($datasetLabels); | |||||
} | |||||
$seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); | |||||
$seriesPlots = array(); | |||||
if ($grouping == 'percentStacked') { | |||||
$sumValues = $this->percentageSumCalculation($groupID, $seriesCount); | |||||
} | |||||
// Loop through each data series in turn | |||||
for ($j = 0; $j < $seriesCount; ++$j) { | |||||
$dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); | |||||
if ($grouping == 'percentStacked') { | |||||
$dataValues = $this->percentageAdjustValues($dataValues, $sumValues); | |||||
} | |||||
// Fill in any missing values in the $dataValues array | |||||
$testCurrentIndex = 0; | |||||
foreach ($dataValues as $k => $dataValue) { | |||||
while ($k != $testCurrentIndex) { | |||||
$dataValues[$testCurrentIndex] = null; | |||||
++$testCurrentIndex; | |||||
} | |||||
++$testCurrentIndex; | |||||
} | |||||
// Reverse the $dataValues order for bar rather than column chart | |||||
if ($rotation == 'bar') { | |||||
$dataValues = array_reverse($dataValues); | |||||
} | |||||
$seriesPlot = new BarPlot($dataValues); | |||||
$seriesPlot->SetColor('black'); | |||||
$seriesPlot->SetFillColor(self::$colourSet[self::$plotColour++]); | |||||
if ($dimensions == '3d') { | |||||
$seriesPlot->SetShadow(); | |||||
} | |||||
if (!$this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)) { | |||||
$dataLabel = ''; | |||||
} else { | |||||
$dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)->getDataValue(); | |||||
} | |||||
$seriesPlot->SetLegend($dataLabel); | |||||
$seriesPlots[] = $seriesPlot; | |||||
} | |||||
// Reverse the plot order for bar rather than column chart | |||||
if (($rotation == 'bar') && (!($grouping == 'percentStacked'))) { | |||||
$seriesPlots = array_reverse($seriesPlots); | |||||
} | |||||
if ($grouping == 'clustered') { | |||||
$groupPlot = new GroupBarPlot($seriesPlots); | |||||
} elseif ($grouping == 'standard') { | |||||
$groupPlot = new GroupBarPlot($seriesPlots); | |||||
} else { | |||||
$groupPlot = new AccBarPlot($seriesPlots); | |||||
if ($dimensions == '3d') { | |||||
$groupPlot->SetShadow(); | |||||
} | |||||
} | |||||
$this->graph->Add($groupPlot); | |||||
} | |||||
private function renderPlotScatter($groupID, $bubble) | |||||
{ | |||||
$grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); | |||||
$scatterStyle = $bubbleSize = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); | |||||
$seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); | |||||
$seriesPlots = array(); | |||||
// Loop through each data series in turn | |||||
for ($i = 0; $i < $seriesCount; ++$i) { | |||||
$dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); | |||||
$dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); | |||||
foreach ($dataValuesY as $k => $dataValueY) { | |||||
$dataValuesY[$k] = $k; | |||||
} | |||||
$seriesPlot = new ScatterPlot($dataValuesX, $dataValuesY); | |||||
if ($scatterStyle == 'lineMarker') { | |||||
$seriesPlot->SetLinkPoints(); | |||||
$seriesPlot->link->SetColor(self::$colourSet[self::$plotColour]); | |||||
} elseif ($scatterStyle == 'smoothMarker') { | |||||
$spline = new Spline($dataValuesY, $dataValuesX); | |||||
list($splineDataY, $splineDataX) = $spline->Get(count($dataValuesX) * self::$width / 20); | |||||
$lplot = new LinePlot($splineDataX, $splineDataY); | |||||
$lplot->SetColor(self::$colourSet[self::$plotColour]); | |||||
$this->graph->Add($lplot); | |||||
} | |||||
if ($bubble) { | |||||
$this->formatPointMarker($seriesPlot, 'dot'); | |||||
$seriesPlot->mark->SetColor('black'); | |||||
$seriesPlot->mark->SetSize($bubbleSize); | |||||
} else { | |||||
$marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); | |||||
$this->formatPointMarker($seriesPlot, $marker); | |||||
} | |||||
$dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); | |||||
$seriesPlot->SetLegend($dataLabel); | |||||
$this->graph->Add($seriesPlot); | |||||
} | |||||
} | |||||
private function renderPlotRadar($groupID) | |||||
{ | |||||
$radarStyle = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); | |||||
$seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); | |||||
$seriesPlots = array(); | |||||
// Loop through each data series in turn | |||||
for ($i = 0; $i < $seriesCount; ++$i) { | |||||
$dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); | |||||
$dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); | |||||
$marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); | |||||
$dataValues = array(); | |||||
foreach ($dataValuesY as $k => $dataValueY) { | |||||
$dataValues[$k] = implode(' ', array_reverse($dataValueY)); | |||||
} | |||||
$tmp = array_shift($dataValues); | |||||
$dataValues[] = $tmp; | |||||
$tmp = array_shift($dataValuesX); | |||||
$dataValuesX[] = $tmp; | |||||
$this->graph->SetTitles(array_reverse($dataValues)); | |||||
$seriesPlot = new RadarPlot(array_reverse($dataValuesX)); | |||||
$dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); | |||||
$seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); | |||||
if ($radarStyle == 'filled') { | |||||
$seriesPlot->SetFillColor(self::$colourSet[self::$plotColour]); | |||||
} | |||||
$this->formatPointMarker($seriesPlot, $marker); | |||||
$seriesPlot->SetLegend($dataLabel); | |||||
$this->graph->Add($seriesPlot); | |||||
} | |||||
} | |||||
private function renderPlotContour($groupID) | |||||
{ | |||||
$contourStyle = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); | |||||
$seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); | |||||
$seriesPlots = array(); | |||||
$dataValues = array(); | |||||
// Loop through each data series in turn | |||||
for ($i = 0; $i < $seriesCount; ++$i) { | |||||
$dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); | |||||
$dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); | |||||
$dataValues[$i] = $dataValuesX; | |||||
} | |||||
$seriesPlot = new ContourPlot($dataValues); | |||||
$this->graph->Add($seriesPlot); | |||||
} | |||||
private function renderPlotStock($groupID) | |||||
{ | |||||
$seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); | |||||
$plotOrder = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder(); | |||||
$dataValues = array(); | |||||
// Loop through each data series in turn and build the plot arrays | |||||
foreach ($plotOrder as $i => $v) { | |||||
$dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); | |||||
foreach ($dataValuesX as $j => $dataValueX) { | |||||
$dataValues[$plotOrder[$i]][$j] = $dataValueX; | |||||
} | |||||
} | |||||
if (empty($dataValues)) { | |||||
return; | |||||
} | |||||
$dataValuesPlot = array(); | |||||
// Flatten the plot arrays to a single dimensional array to work with jpgraph | |||||
for ($j = 0; $j < count($dataValues[0]); ++$j) { | |||||
for ($i = 0; $i < $seriesCount; ++$i) { | |||||
$dataValuesPlot[] = $dataValues[$i][$j]; | |||||
} | |||||
} | |||||
// Set the x-axis labels | |||||
$labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); | |||||
if ($labelCount > 0) { | |||||
$datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); | |||||
$datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); | |||||
$this->graph->xaxis->SetTickLabels($datasetLabels); | |||||
} | |||||
$seriesPlot = new StockPlot($dataValuesPlot); | |||||
$seriesPlot->SetWidth(20); | |||||
$this->graph->Add($seriesPlot); | |||||
} | |||||
private function renderAreaChart($groupCount, $dimensions = '2d') | |||||
{ | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); | |||||
$this->renderCartesianPlotArea(); | |||||
for ($i = 0; $i < $groupCount; ++$i) { | |||||
$this->renderPlotLine($i, true, false, $dimensions); | |||||
} | |||||
} | |||||
private function renderLineChart($groupCount, $dimensions = '2d') | |||||
{ | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); | |||||
$this->renderCartesianPlotArea(); | |||||
for ($i = 0; $i < $groupCount; ++$i) { | |||||
$this->renderPlotLine($i, false, false, $dimensions); | |||||
} | |||||
} | |||||
private function renderBarChart($groupCount, $dimensions = '2d') | |||||
{ | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php'); | |||||
$this->renderCartesianPlotArea(); | |||||
for ($i = 0; $i < $groupCount; ++$i) { | |||||
$this->renderPlotBar($i, $dimensions); | |||||
} | |||||
} | |||||
private function renderScatterChart($groupCount) | |||||
{ | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php'); | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); | |||||
$this->renderCartesianPlotArea('linlin'); | |||||
for ($i = 0; $i < $groupCount; ++$i) { | |||||
$this->renderPlotScatter($i, false); | |||||
} | |||||
} | |||||
private function renderBubbleChart($groupCount) | |||||
{ | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); | |||||
$this->renderCartesianPlotArea('linlin'); | |||||
for ($i = 0; $i < $groupCount; ++$i) { | |||||
$this->renderPlotScatter($i, true); | |||||
} | |||||
} | |||||
private function renderPieChart($groupCount, $dimensions = '2d', $doughnut = false, $multiplePlots = false) | |||||
{ | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie.php'); | |||||
if ($dimensions == '3d') { | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie3d.php'); | |||||
} | |||||
$this->renderPiePlotArea($doughnut); | |||||
$iLimit = ($multiplePlots) ? $groupCount : 1; | |||||
for ($groupID = 0; $groupID < $iLimit; ++$groupID) { | |||||
$grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); | |||||
$exploded = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); | |||||
if ($groupID == 0) { | |||||
$labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); | |||||
if ($labelCount > 0) { | |||||
$datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); | |||||
$datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); | |||||
} | |||||
} | |||||
$seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); | |||||
$seriesPlots = array(); | |||||
// For pie charts, we only display the first series: doughnut charts generally display all series | |||||
$jLimit = ($multiplePlots) ? $seriesCount : 1; | |||||
// Loop through each data series in turn | |||||
for ($j = 0; $j < $jLimit; ++$j) { | |||||
$dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); | |||||
// Fill in any missing values in the $dataValues array | |||||
$testCurrentIndex = 0; | |||||
foreach ($dataValues as $k => $dataValue) { | |||||
while ($k != $testCurrentIndex) { | |||||
$dataValues[$testCurrentIndex] = null; | |||||
++$testCurrentIndex; | |||||
} | |||||
++$testCurrentIndex; | |||||
} | |||||
if ($dimensions == '3d') { | |||||
$seriesPlot = new PiePlot3D($dataValues); | |||||
} else { | |||||
if ($doughnut) { | |||||
$seriesPlot = new PiePlotC($dataValues); | |||||
} else { | |||||
$seriesPlot = new PiePlot($dataValues); | |||||
} | |||||
} | |||||
if ($multiplePlots) { | |||||
$seriesPlot->SetSize(($jLimit-$j) / ($jLimit * 4)); | |||||
} | |||||
if ($doughnut) { | |||||
$seriesPlot->SetMidColor('white'); | |||||
} | |||||
$seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); | |||||
if (count($datasetLabels) > 0) { | |||||
$seriesPlot->SetLabels(array_fill(0, count($datasetLabels), '')); | |||||
} | |||||
if ($dimensions != '3d') { | |||||
$seriesPlot->SetGuideLines(false); | |||||
} | |||||
if ($j == 0) { | |||||
if ($exploded) { | |||||
$seriesPlot->ExplodeAll(); | |||||
} | |||||
$seriesPlot->SetLegends($datasetLabels); | |||||
} | |||||
$this->graph->Add($seriesPlot); | |||||
} | |||||
} | |||||
} | |||||
private function renderRadarChart($groupCount) | |||||
{ | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_radar.php'); | |||||
$this->renderRadarPlotArea(); | |||||
for ($groupID = 0; $groupID < $groupCount; ++$groupID) { | |||||
$this->renderPlotRadar($groupID); | |||||
} | |||||
} | |||||
private function renderStockChart($groupCount) | |||||
{ | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_stock.php'); | |||||
$this->renderCartesianPlotArea('intint'); | |||||
for ($groupID = 0; $groupID < $groupCount; ++$groupID) { | |||||
$this->renderPlotStock($groupID); | |||||
} | |||||
} | |||||
private function renderContourChart($groupCount, $dimensions) | |||||
{ | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_contour.php'); | |||||
$this->renderCartesianPlotArea('intint'); | |||||
for ($i = 0; $i < $groupCount; ++$i) { | |||||
$this->renderPlotContour($i); | |||||
} | |||||
} | |||||
private function renderCombinationChart($groupCount, $dimensions, $outputDestination) | |||||
{ | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php'); | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php'); | |||||
require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); | |||||
$this->renderCartesianPlotArea(); | |||||
for ($i = 0; $i < $groupCount; ++$i) { | |||||
$dimensions = null; | |||||
$chartType = $this->chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); | |||||
switch ($chartType) { | |||||
case 'area3DChart': | |||||
$dimensions = '3d'; | |||||
// no break | |||||
case 'areaChart': | |||||
$this->renderPlotLine($i, true, true, $dimensions); | |||||
break; | |||||
case 'bar3DChart': | |||||
$dimensions = '3d'; | |||||
// no break | |||||
case 'barChart': | |||||
$this->renderPlotBar($i, $dimensions); | |||||
break; | |||||
case 'line3DChart': | |||||
$dimensions = '3d'; | |||||
// no break | |||||
case 'lineChart': | |||||
$this->renderPlotLine($i, false, true, $dimensions); | |||||
break; | |||||
case 'scatterChart': | |||||
$this->renderPlotScatter($i, false); | |||||
break; | |||||
case 'bubbleChart': | |||||
$this->renderPlotScatter($i, true); | |||||
break; | |||||
default: | |||||
$this->graph = null; | |||||
return false; | |||||
} | |||||
} | |||||
$this->renderLegend(); | |||||
$this->graph->Stroke($outputDestination); | |||||
return true; | |||||
} | |||||
public function render($outputDestination) | |||||
{ | |||||
self::$plotColour = 0; | |||||
$groupCount = $this->chart->getPlotArea()->getPlotGroupCount(); | |||||
$dimensions = null; | |||||
if ($groupCount == 1) { | |||||
$chartType = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType(); | |||||
} else { | |||||
$chartTypes = array(); | |||||
for ($i = 0; $i < $groupCount; ++$i) { | |||||
$chartTypes[] = $this->chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); | |||||
} | |||||
$chartTypes = array_unique($chartTypes); | |||||
if (count($chartTypes) == 1) { | |||||
$chartType = array_pop($chartTypes); | |||||
} elseif (count($chartTypes) == 0) { | |||||
echo 'Chart is not yet implemented<br />'; | |||||
return false; | |||||
} else { | |||||
return $this->renderCombinationChart($groupCount, $dimensions, $outputDestination); | |||||
} | |||||
} | |||||
switch ($chartType) { | |||||
case 'area3DChart': | |||||
$dimensions = '3d'; | |||||
// no break | |||||
case 'areaChart': | |||||
$this->renderAreaChart($groupCount, $dimensions); | |||||
break; | |||||
case 'bar3DChart': | |||||
$dimensions = '3d'; | |||||
// no break | |||||
case 'barChart': | |||||
$this->renderBarChart($groupCount, $dimensions); | |||||
break; | |||||
case 'line3DChart': | |||||
$dimensions = '3d'; | |||||
// no break | |||||
case 'lineChart': | |||||
$this->renderLineChart($groupCount, $dimensions); | |||||
break; | |||||
case 'pie3DChart': | |||||
$dimensions = '3d'; | |||||
// no break | |||||
case 'pieChart': | |||||
$this->renderPieChart($groupCount, $dimensions, false, false); | |||||
break; | |||||
case 'doughnut3DChart': | |||||
$dimensions = '3d'; | |||||
// no break | |||||
case 'doughnutChart': | |||||
$this->renderPieChart($groupCount, $dimensions, true, true); | |||||
break; | |||||
case 'scatterChart': | |||||
$this->renderScatterChart($groupCount); | |||||
break; | |||||
case 'bubbleChart': | |||||
$this->renderBubbleChart($groupCount); | |||||
break; | |||||
case 'radarChart': | |||||
$this->renderRadarChart($groupCount); | |||||
break; | |||||
case 'surface3DChart': | |||||
$dimensions = '3d'; | |||||
// no break | |||||
case 'surfaceChart': | |||||
$this->renderContourChart($groupCount, $dimensions); | |||||
break; | |||||
case 'stockChart': | |||||
$this->renderStockChart($groupCount, $dimensions); | |||||
break; | |||||
default: | |||||
echo $chartType.' is not yet implemented<br />'; | |||||
return false; | |||||
} | |||||
$this->renderLegend(); | |||||
$this->graph->Stroke($outputDestination); | |||||
return true; | |||||
} | |||||
/** | |||||
* Create a new PHPExcel_Chart_Renderer_jpgraph | |||||
*/ | |||||
public function __construct(PHPExcel_Chart $chart) | |||||
{ | |||||
$this->graph = null; | |||||
$this->chart = $chart; | |||||
} | |||||
} |
@ -0,0 +1,86 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Chart_Title | |||||
* | |||||
* 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_Chart | |||||
* @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_Chart_Title | |||||
{ | |||||
/** | |||||
* Title Caption | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $caption = null; | |||||
/** | |||||
* Title Layout | |||||
* | |||||
* @var PHPExcel_Chart_Layout | |||||
*/ | |||||
private $layout = null; | |||||
/** | |||||
* Create a new PHPExcel_Chart_Title | |||||
*/ | |||||
public function __construct($caption = null, PHPExcel_Chart_Layout $layout = null) | |||||
{ | |||||
$this->caption = $caption; | |||||
$this->layout = $layout; | |||||
} | |||||
/** | |||||
* Get caption | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getCaption() | |||||
{ | |||||
return $this->caption; | |||||
} | |||||
/** | |||||
* Set caption | |||||
* | |||||
* @param string $caption | |||||
* @return PHPExcel_Chart_Title | |||||
*/ | |||||
public function setCaption($caption = null) | |||||
{ | |||||
$this->caption = $caption; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Layout | |||||
* | |||||
* @return PHPExcel_Chart_Layout | |||||
*/ | |||||
public function getLayout() | |||||
{ | |||||
return $this->layout; | |||||
} | |||||
} |
@ -0,0 +1,338 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Comment | |||||
* | |||||
* 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 | |||||
* @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_Comment implements PHPExcel_IComparable | |||||
{ | |||||
/** | |||||
* Author | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $author; | |||||
/** | |||||
* Rich text comment | |||||
* | |||||
* @var PHPExcel_RichText | |||||
*/ | |||||
private $text; | |||||
/** | |||||
* Comment width (CSS style, i.e. XXpx or YYpt) | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $width = '96pt'; | |||||
/** | |||||
* Left margin (CSS style, i.e. XXpx or YYpt) | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $marginLeft = '59.25pt'; | |||||
/** | |||||
* Top margin (CSS style, i.e. XXpx or YYpt) | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $marginTop = '1.5pt'; | |||||
/** | |||||
* Visible | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $visible = false; | |||||
/** | |||||
* Comment height (CSS style, i.e. XXpx or YYpt) | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $height = '55.5pt'; | |||||
/** | |||||
* Comment fill color | |||||
* | |||||
* @var PHPExcel_Style_Color | |||||
*/ | |||||
private $fillColor; | |||||
/** | |||||
* Alignment | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $alignment; | |||||
/** | |||||
* Create a new PHPExcel_Comment | |||||
* | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function __construct() | |||||
{ | |||||
// Initialise variables | |||||
$this->author = 'Author'; | |||||
$this->text = new PHPExcel_RichText(); | |||||
$this->fillColor = new PHPExcel_Style_Color('FFFFFFE1'); | |||||
$this->alignment = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; | |||||
} | |||||
/** | |||||
* Get Author | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getAuthor() | |||||
{ | |||||
return $this->author; | |||||
} | |||||
/** | |||||
* Set Author | |||||
* | |||||
* @param string $pValue | |||||
* @return PHPExcel_Comment | |||||
*/ | |||||
public function setAuthor($pValue = '') | |||||
{ | |||||
$this->author = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Rich text comment | |||||
* | |||||
* @return PHPExcel_RichText | |||||
*/ | |||||
public function getText() | |||||
{ | |||||
return $this->text; | |||||
} | |||||
/** | |||||
* Set Rich text comment | |||||
* | |||||
* @param PHPExcel_RichText $pValue | |||||
* @return PHPExcel_Comment | |||||
*/ | |||||
public function setText(PHPExcel_RichText $pValue) | |||||
{ | |||||
$this->text = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get comment width (CSS style, i.e. XXpx or YYpt) | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getWidth() | |||||
{ | |||||
return $this->width; | |||||
} | |||||
/** | |||||
* Set comment width (CSS style, i.e. XXpx or YYpt) | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_Comment | |||||
*/ | |||||
public function setWidth($value = '96pt') | |||||
{ | |||||
$this->width = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get comment height (CSS style, i.e. XXpx or YYpt) | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getHeight() | |||||
{ | |||||
return $this->height; | |||||
} | |||||
/** | |||||
* Set comment height (CSS style, i.e. XXpx or YYpt) | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_Comment | |||||
*/ | |||||
public function setHeight($value = '55.5pt') | |||||
{ | |||||
$this->height = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get left margin (CSS style, i.e. XXpx or YYpt) | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getMarginLeft() | |||||
{ | |||||
return $this->marginLeft; | |||||
} | |||||
/** | |||||
* Set left margin (CSS style, i.e. XXpx or YYpt) | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_Comment | |||||
*/ | |||||
public function setMarginLeft($value = '59.25pt') | |||||
{ | |||||
$this->marginLeft = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get top margin (CSS style, i.e. XXpx or YYpt) | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getMarginTop() | |||||
{ | |||||
return $this->marginTop; | |||||
} | |||||
/** | |||||
* Set top margin (CSS style, i.e. XXpx or YYpt) | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_Comment | |||||
*/ | |||||
public function setMarginTop($value = '1.5pt') | |||||
{ | |||||
$this->marginTop = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Is the comment visible by default? | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getVisible() | |||||
{ | |||||
return $this->visible; | |||||
} | |||||
/** | |||||
* Set comment default visibility | |||||
* | |||||
* @param boolean $value | |||||
* @return PHPExcel_Comment | |||||
*/ | |||||
public function setVisible($value = false) | |||||
{ | |||||
$this->visible = $value; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get fill color | |||||
* | |||||
* @return PHPExcel_Style_Color | |||||
*/ | |||||
public function getFillColor() | |||||
{ | |||||
return $this->fillColor; | |||||
} | |||||
/** | |||||
* Set Alignment | |||||
* | |||||
* @param string $pValue | |||||
* @return PHPExcel_Comment | |||||
*/ | |||||
public function setAlignment($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL) | |||||
{ | |||||
$this->alignment = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Alignment | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getAlignment() | |||||
{ | |||||
return $this->alignment; | |||||
} | |||||
/** | |||||
* Get hash code | |||||
* | |||||
* @return string Hash code | |||||
*/ | |||||
public function getHashCode() | |||||
{ | |||||
return md5( | |||||
$this->author . | |||||
$this->text->getHashCode() . | |||||
$this->width . | |||||
$this->height . | |||||
$this->marginLeft . | |||||
$this->marginTop . | |||||
($this->visible ? 1 : 0) . | |||||
$this->fillColor->getHashCode() . | |||||
$this->alignment . | |||||
__CLASS__ | |||||
); | |||||
} | |||||
/** | |||||
* Implement PHP __clone to create a deep clone, not just a shallow copy. | |||||
*/ | |||||
public function __clone() | |||||
{ | |||||
$vars = get_object_vars($this); | |||||
foreach ($vars as $key => $value) { | |||||
if (is_object($value)) { | |||||
$this->$key = clone $value; | |||||
} else { | |||||
$this->$key = $value; | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Convert to string | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function __toString() | |||||
{ | |||||
return $this->text->getPlainText(); | |||||
} | |||||
} |
@ -0,0 +1,611 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_DocumentProperties | |||||
* | |||||
* 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 | |||||
* @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_DocumentProperties | |||||
{ | |||||
/** constants */ | |||||
const PROPERTY_TYPE_BOOLEAN = 'b'; | |||||
const PROPERTY_TYPE_INTEGER = 'i'; | |||||
const PROPERTY_TYPE_FLOAT = 'f'; | |||||
const PROPERTY_TYPE_DATE = 'd'; | |||||
const PROPERTY_TYPE_STRING = 's'; | |||||
const PROPERTY_TYPE_UNKNOWN = 'u'; | |||||
/** | |||||
* Creator | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $creator = 'Unknown Creator'; | |||||
/** | |||||
* LastModifiedBy | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $lastModifiedBy; | |||||
/** | |||||
* Created | |||||
* | |||||
* @var datetime | |||||
*/ | |||||
private $created; | |||||
/** | |||||
* Modified | |||||
* | |||||
* @var datetime | |||||
*/ | |||||
private $modified; | |||||
/** | |||||
* Title | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $title = 'Untitled Spreadsheet'; | |||||
/** | |||||
* Description | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $description = ''; | |||||
/** | |||||
* Subject | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $subject = ''; | |||||
/** | |||||
* Keywords | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $keywords = ''; | |||||
/** | |||||
* Category | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $category = ''; | |||||
/** | |||||
* Manager | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $manager = ''; | |||||
/** | |||||
* Company | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $company = 'Microsoft Corporation'; | |||||
/** | |||||
* Custom Properties | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $customProperties = array(); | |||||
/** | |||||
* Create a new PHPExcel_DocumentProperties | |||||
*/ | |||||
public function __construct() | |||||
{ | |||||
// Initialise values | |||||
$this->lastModifiedBy = $this->creator; | |||||
$this->created = time(); | |||||
$this->modified = time(); | |||||
} | |||||
/** | |||||
* Get Creator | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getCreator() | |||||
{ | |||||
return $this->creator; | |||||
} | |||||
/** | |||||
* Set Creator | |||||
* | |||||
* @param string $pValue | |||||
* @return PHPExcel_DocumentProperties | |||||
*/ | |||||
public function setCreator($pValue = '') | |||||
{ | |||||
$this->creator = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Last Modified By | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getLastModifiedBy() | |||||
{ | |||||
return $this->lastModifiedBy; | |||||
} | |||||
/** | |||||
* Set Last Modified By | |||||
* | |||||
* @param string $pValue | |||||
* @return PHPExcel_DocumentProperties | |||||
*/ | |||||
public function setLastModifiedBy($pValue = '') | |||||
{ | |||||
$this->lastModifiedBy = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Created | |||||
* | |||||
* @return datetime | |||||
*/ | |||||
public function getCreated() | |||||
{ | |||||
return $this->created; | |||||
} | |||||
/** | |||||
* Set Created | |||||
* | |||||
* @param datetime $pValue | |||||
* @return PHPExcel_DocumentProperties | |||||
*/ | |||||
public function setCreated($pValue = null) | |||||
{ | |||||
if ($pValue === null) { | |||||
$pValue = time(); | |||||
} elseif (is_string($pValue)) { | |||||
if (is_numeric($pValue)) { | |||||
$pValue = intval($pValue); | |||||
} else { | |||||
$pValue = strtotime($pValue); | |||||
} | |||||
} | |||||
$this->created = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Modified | |||||
* | |||||
* @return datetime | |||||
*/ | |||||
public function getModified() | |||||
{ | |||||
return $this->modified; | |||||
} | |||||
/** | |||||
* Set Modified | |||||
* | |||||
* @param datetime $pValue | |||||
* @return PHPExcel_DocumentProperties | |||||
*/ | |||||
public function setModified($pValue = null) | |||||
{ | |||||
if ($pValue === null) { | |||||
$pValue = time(); | |||||
} elseif (is_string($pValue)) { | |||||
if (is_numeric($pValue)) { | |||||
$pValue = intval($pValue); | |||||
} else { | |||||
$pValue = strtotime($pValue); | |||||
} | |||||
} | |||||
$this->modified = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Title | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getTitle() | |||||
{ | |||||
return $this->title; | |||||
} | |||||
/** | |||||
* Set Title | |||||
* | |||||
* @param string $pValue | |||||
* @return PHPExcel_DocumentProperties | |||||
*/ | |||||
public function setTitle($pValue = '') | |||||
{ | |||||
$this->title = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Description | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getDescription() | |||||
{ | |||||
return $this->description; | |||||
} | |||||
/** | |||||
* Set Description | |||||
* | |||||
* @param string $pValue | |||||
* @return PHPExcel_DocumentProperties | |||||
*/ | |||||
public function setDescription($pValue = '') | |||||
{ | |||||
$this->description = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Subject | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getSubject() | |||||
{ | |||||
return $this->subject; | |||||
} | |||||
/** | |||||
* Set Subject | |||||
* | |||||
* @param string $pValue | |||||
* @return PHPExcel_DocumentProperties | |||||
*/ | |||||
public function setSubject($pValue = '') | |||||
{ | |||||
$this->subject = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Keywords | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getKeywords() | |||||
{ | |||||
return $this->keywords; | |||||
} | |||||
/** | |||||
* Set Keywords | |||||
* | |||||
* @param string $pValue | |||||
* @return PHPExcel_DocumentProperties | |||||
*/ | |||||
public function setKeywords($pValue = '') | |||||
{ | |||||
$this->keywords = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Category | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getCategory() | |||||
{ | |||||
return $this->category; | |||||
} | |||||
/** | |||||
* Set Category | |||||
* | |||||
* @param string $pValue | |||||
* @return PHPExcel_DocumentProperties | |||||
*/ | |||||
public function setCategory($pValue = '') | |||||
{ | |||||
$this->category = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Company | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getCompany() | |||||
{ | |||||
return $this->company; | |||||
} | |||||
/** | |||||
* Set Company | |||||
* | |||||
* @param string $pValue | |||||
* @return PHPExcel_DocumentProperties | |||||
*/ | |||||
public function setCompany($pValue = '') | |||||
{ | |||||
$this->company = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Manager | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getManager() | |||||
{ | |||||
return $this->manager; | |||||
} | |||||
/** | |||||
* Set Manager | |||||
* | |||||
* @param string $pValue | |||||
* @return PHPExcel_DocumentProperties | |||||
*/ | |||||
public function setManager($pValue = '') | |||||
{ | |||||
$this->manager = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get a List of Custom Property Names | |||||
* | |||||
* @return array of string | |||||
*/ | |||||
public function getCustomProperties() | |||||
{ | |||||
return array_keys($this->customProperties); | |||||
} | |||||
/** | |||||
* Check if a Custom Property is defined | |||||
* | |||||
* @param string $propertyName | |||||
* @return boolean | |||||
*/ | |||||
public function isCustomPropertySet($propertyName) | |||||
{ | |||||
return isset($this->customProperties[$propertyName]); | |||||
} | |||||
/** | |||||
* Get a Custom Property Value | |||||
* | |||||
* @param string $propertyName | |||||
* @return string | |||||
*/ | |||||
public function getCustomPropertyValue($propertyName) | |||||
{ | |||||
if (isset($this->customProperties[$propertyName])) { | |||||
return $this->customProperties[$propertyName]['value']; | |||||
} | |||||
} | |||||
/** | |||||
* Get a Custom Property Type | |||||
* | |||||
* @param string $propertyName | |||||
* @return string | |||||
*/ | |||||
public function getCustomPropertyType($propertyName) | |||||
{ | |||||
if (isset($this->customProperties[$propertyName])) { | |||||
return $this->customProperties[$propertyName]['type']; | |||||
} | |||||
} | |||||
/** | |||||
* Set a Custom Property | |||||
* | |||||
* @param string $propertyName | |||||
* @param mixed $propertyValue | |||||
* @param string $propertyType | |||||
* 'i' : Integer | |||||
* 'f' : Floating Point | |||||
* 's' : String | |||||
* 'd' : Date/Time | |||||
* 'b' : Boolean | |||||
* @return PHPExcel_DocumentProperties | |||||
*/ | |||||
public function setCustomProperty($propertyName, $propertyValue = '', $propertyType = null) | |||||
{ | |||||
if (($propertyType === null) || (!in_array($propertyType, array(self::PROPERTY_TYPE_INTEGER, | |||||
self::PROPERTY_TYPE_FLOAT, | |||||
self::PROPERTY_TYPE_STRING, | |||||
self::PROPERTY_TYPE_DATE, | |||||
self::PROPERTY_TYPE_BOOLEAN)))) { | |||||
if ($propertyValue === null) { | |||||
$propertyType = self::PROPERTY_TYPE_STRING; | |||||
} elseif (is_float($propertyValue)) { | |||||
$propertyType = self::PROPERTY_TYPE_FLOAT; | |||||
} elseif (is_int($propertyValue)) { | |||||
$propertyType = self::PROPERTY_TYPE_INTEGER; | |||||
} elseif (is_bool($propertyValue)) { | |||||
$propertyType = self::PROPERTY_TYPE_BOOLEAN; | |||||
} else { | |||||
$propertyType = self::PROPERTY_TYPE_STRING; | |||||
} | |||||
} | |||||
$this->customProperties[$propertyName] = array( | |||||
'value' => $propertyValue, | |||||
'type' => $propertyType | |||||
); | |||||
return $this; | |||||
} | |||||
/** | |||||
* Implement PHP __clone to create a deep clone, not just a shallow copy. | |||||
*/ | |||||
public function __clone() | |||||
{ | |||||
$vars = get_object_vars($this); | |||||
foreach ($vars as $key => $value) { | |||||
if (is_object($value)) { | |||||
$this->$key = clone $value; | |||||
} else { | |||||
$this->$key = $value; | |||||
} | |||||
} | |||||
} | |||||
public static function convertProperty($propertyValue, $propertyType) | |||||
{ | |||||
switch ($propertyType) { | |||||
case 'empty': // Empty | |||||
return ''; | |||||
break; | |||||
case 'null': // Null | |||||
return null; | |||||
break; | |||||
case 'i1': // 1-Byte Signed Integer | |||||
case 'i2': // 2-Byte Signed Integer | |||||
case 'i4': // 4-Byte Signed Integer | |||||
case 'i8': // 8-Byte Signed Integer | |||||
case 'int': // Integer | |||||
return (int) $propertyValue; | |||||
break; | |||||
case 'ui1': // 1-Byte Unsigned Integer | |||||
case 'ui2': // 2-Byte Unsigned Integer | |||||
case 'ui4': // 4-Byte Unsigned Integer | |||||
case 'ui8': // 8-Byte Unsigned Integer | |||||
case 'uint': // Unsigned Integer | |||||
return abs((int) $propertyValue); | |||||
break; | |||||
case 'r4': // 4-Byte Real Number | |||||
case 'r8': // 8-Byte Real Number | |||||
case 'decimal': // Decimal | |||||
return (float) $propertyValue; | |||||
break; | |||||
case 'lpstr': // LPSTR | |||||
case 'lpwstr': // LPWSTR | |||||
case 'bstr': // Basic String | |||||
return $propertyValue; | |||||
break; | |||||
case 'date': // Date and Time | |||||
case 'filetime': // File Time | |||||
return strtotime($propertyValue); | |||||
break; | |||||
case 'bool': // Boolean | |||||
return ($propertyValue == 'true') ? true : false; | |||||
break; | |||||
case 'cy': // Currency | |||||
case 'error': // Error Status Code | |||||
case 'vector': // Vector | |||||
case 'array': // Array | |||||
case 'blob': // Binary Blob | |||||
case 'oblob': // Binary Blob Object | |||||
case 'stream': // Binary Stream | |||||
case 'ostream': // Binary Stream Object | |||||
case 'storage': // Binary Storage | |||||
case 'ostorage': // Binary Storage Object | |||||
case 'vstream': // Binary Versioned Stream | |||||
case 'clsid': // Class ID | |||||
case 'cf': // Clipboard Data | |||||
return $propertyValue; | |||||
break; | |||||
} | |||||
return $propertyValue; | |||||
} | |||||
public static function convertPropertyType($propertyType) | |||||
{ | |||||
switch ($propertyType) { | |||||
case 'i1': // 1-Byte Signed Integer | |||||
case 'i2': // 2-Byte Signed Integer | |||||
case 'i4': // 4-Byte Signed Integer | |||||
case 'i8': // 8-Byte Signed Integer | |||||
case 'int': // Integer | |||||
case 'ui1': // 1-Byte Unsigned Integer | |||||
case 'ui2': // 2-Byte Unsigned Integer | |||||
case 'ui4': // 4-Byte Unsigned Integer | |||||
case 'ui8': // 8-Byte Unsigned Integer | |||||
case 'uint': // Unsigned Integer | |||||
return self::PROPERTY_TYPE_INTEGER; | |||||
break; | |||||
case 'r4': // 4-Byte Real Number | |||||
case 'r8': // 8-Byte Real Number | |||||
case 'decimal': // Decimal | |||||
return self::PROPERTY_TYPE_FLOAT; | |||||
break; | |||||
case 'empty': // Empty | |||||
case 'null': // Null | |||||
case 'lpstr': // LPSTR | |||||
case 'lpwstr': // LPWSTR | |||||
case 'bstr': // Basic String | |||||
return self::PROPERTY_TYPE_STRING; | |||||
break; | |||||
case 'date': // Date and Time | |||||
case 'filetime': // File Time | |||||
return self::PROPERTY_TYPE_DATE; | |||||
break; | |||||
case 'bool': // Boolean | |||||
return self::PROPERTY_TYPE_BOOLEAN; | |||||
break; | |||||
case 'cy': // Currency | |||||
case 'error': // Error Status Code | |||||
case 'vector': // Vector | |||||
case 'array': // Array | |||||
case 'blob': // Binary Blob | |||||
case 'oblob': // Binary Blob Object | |||||
case 'stream': // Binary Stream | |||||
case 'ostream': // Binary Stream Object | |||||
case 'storage': // Binary Storage | |||||
case 'ostorage': // Binary Storage Object | |||||
case 'vstream': // Binary Versioned Stream | |||||
case 'clsid': // Class ID | |||||
case 'cf': // Clipboard Data | |||||
return self::PROPERTY_TYPE_UNKNOWN; | |||||
break; | |||||
} | |||||
return self::PROPERTY_TYPE_UNKNOWN; | |||||
} | |||||
} |
@ -0,0 +1,222 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_DocumentSecurity | |||||
* | |||||
* 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 | |||||
* @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_DocumentSecurity | |||||
{ | |||||
/** | |||||
* LockRevision | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $lockRevision; | |||||
/** | |||||
* LockStructure | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $lockStructure; | |||||
/** | |||||
* LockWindows | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
private $lockWindows; | |||||
/** | |||||
* RevisionsPassword | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $revisionsPassword; | |||||
/** | |||||
* WorkbookPassword | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $workbookPassword; | |||||
/** | |||||
* Create a new PHPExcel_DocumentSecurity | |||||
*/ | |||||
public function __construct() | |||||
{ | |||||
// Initialise values | |||||
$this->lockRevision = false; | |||||
$this->lockStructure = false; | |||||
$this->lockWindows = false; | |||||
$this->revisionsPassword = ''; | |||||
$this->workbookPassword = ''; | |||||
} | |||||
/** | |||||
* Is some sort of document security enabled? | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function isSecurityEnabled() | |||||
{ | |||||
return $this->lockRevision || | |||||
$this->lockStructure || | |||||
$this->lockWindows; | |||||
} | |||||
/** | |||||
* Get LockRevision | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getLockRevision() | |||||
{ | |||||
return $this->lockRevision; | |||||
} | |||||
/** | |||||
* Set LockRevision | |||||
* | |||||
* @param boolean $pValue | |||||
* @return PHPExcel_DocumentSecurity | |||||
*/ | |||||
public function setLockRevision($pValue = false) | |||||
{ | |||||
$this->lockRevision = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get LockStructure | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getLockStructure() | |||||
{ | |||||
return $this->lockStructure; | |||||
} | |||||
/** | |||||
* Set LockStructure | |||||
* | |||||
* @param boolean $pValue | |||||
* @return PHPExcel_DocumentSecurity | |||||
*/ | |||||
public function setLockStructure($pValue = false) | |||||
{ | |||||
$this->lockStructure = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get LockWindows | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getLockWindows() | |||||
{ | |||||
return $this->lockWindows; | |||||
} | |||||
/** | |||||
* Set LockWindows | |||||
* | |||||
* @param boolean $pValue | |||||
* @return PHPExcel_DocumentSecurity | |||||
*/ | |||||
public function setLockWindows($pValue = false) | |||||
{ | |||||
$this->lockWindows = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get RevisionsPassword (hashed) | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getRevisionsPassword() | |||||
{ | |||||
return $this->revisionsPassword; | |||||
} | |||||
/** | |||||
* Set RevisionsPassword | |||||
* | |||||
* @param string $pValue | |||||
* @param boolean $pAlreadyHashed If the password has already been hashed, set this to true | |||||
* @return PHPExcel_DocumentSecurity | |||||
*/ | |||||
public function setRevisionsPassword($pValue = '', $pAlreadyHashed = false) | |||||
{ | |||||
if (!$pAlreadyHashed) { | |||||
$pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); | |||||
} | |||||
$this->revisionsPassword = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get WorkbookPassword (hashed) | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getWorkbookPassword() | |||||
{ | |||||
return $this->workbookPassword; | |||||
} | |||||
/** | |||||
* Set WorkbookPassword | |||||
* | |||||
* @param string $pValue | |||||
* @param boolean $pAlreadyHashed If the password has already been hashed, set this to true | |||||
* @return PHPExcel_DocumentSecurity | |||||
*/ | |||||
public function setWorkbookPassword($pValue = '', $pAlreadyHashed = false) | |||||
{ | |||||
if (!$pAlreadyHashed) { | |||||
$pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); | |||||
} | |||||
$this->workbookPassword = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Implement PHP __clone to create a deep clone, not just a shallow copy. | |||||
*/ | |||||
public function __clone() | |||||
{ | |||||
$vars = get_object_vars($this); | |||||
foreach ($vars as $key => $value) { | |||||
if (is_object($value)) { | |||||
$this->$key = clone $value; | |||||
} else { | |||||
$this->$key = $value; | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,54 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel | |||||
* | |||||
* 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 | |||||
* @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## | |||||
*/ | |||||
/** | |||||
* PHPExcel_Exception | |||||
* | |||||
* @category PHPExcel | |||||
* @package PHPExcel | |||||
* @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | |||||
*/ | |||||
class PHPExcel_Exception extends Exception | |||||
{ | |||||
/** | |||||
* Error handler callback | |||||
* | |||||
* @param mixed $code | |||||
* @param mixed $string | |||||
* @param mixed $file | |||||
* @param mixed $line | |||||
* @param mixed $context | |||||
*/ | |||||
public static function errorHandlerCallback($code, $string, $file, $line, $context) | |||||
{ | |||||
$e = new self($string, $code); | |||||
$e->line = $line; | |||||
$e->file = $file; | |||||
throw $e; | |||||
} | |||||
} |
@ -0,0 +1,204 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_HashTable | |||||
* | |||||
* 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 | |||||
* @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_HashTable | |||||
{ | |||||
/** | |||||
* HashTable elements | |||||
* | |||||
* @var array | |||||
*/ | |||||
protected $items = array(); | |||||
/** | |||||
* HashTable key map | |||||
* | |||||
* @var array | |||||
*/ | |||||
protected $keyMap = array(); | |||||
/** | |||||
* Create a new PHPExcel_HashTable | |||||
* | |||||
* @param PHPExcel_IComparable[] $pSource Optional source array to create HashTable from | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function __construct($pSource = null) | |||||
{ | |||||
if ($pSource !== null) { | |||||
// Create HashTable | |||||
$this->addFromSource($pSource); | |||||
} | |||||
} | |||||
/** | |||||
* Add HashTable items from source | |||||
* | |||||
* @param PHPExcel_IComparable[] $pSource Source array to create HashTable from | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function addFromSource($pSource = null) | |||||
{ | |||||
// Check if an array was passed | |||||
if ($pSource == null) { | |||||
return; | |||||
} elseif (!is_array($pSource)) { | |||||
throw new PHPExcel_Exception('Invalid array parameter passed.'); | |||||
} | |||||
foreach ($pSource as $item) { | |||||
$this->add($item); | |||||
} | |||||
} | |||||
/** | |||||
* Add HashTable item | |||||
* | |||||
* @param PHPExcel_IComparable $pSource Item to add | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function add(PHPExcel_IComparable $pSource = null) | |||||
{ | |||||
$hash = $pSource->getHashCode(); | |||||
if (!isset($this->items[$hash])) { | |||||
$this->items[$hash] = $pSource; | |||||
$this->keyMap[count($this->items) - 1] = $hash; | |||||
} | |||||
} | |||||
/** | |||||
* Remove HashTable item | |||||
* | |||||
* @param PHPExcel_IComparable $pSource Item to remove | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function remove(PHPExcel_IComparable $pSource = null) | |||||
{ | |||||
$hash = $pSource->getHashCode(); | |||||
if (isset($this->items[$hash])) { | |||||
unset($this->items[$hash]); | |||||
$deleteKey = -1; | |||||
foreach ($this->keyMap as $key => $value) { | |||||
if ($deleteKey >= 0) { | |||||
$this->keyMap[$key - 1] = $value; | |||||
} | |||||
if ($value == $hash) { | |||||
$deleteKey = $key; | |||||
} | |||||
} | |||||
unset($this->keyMap[count($this->keyMap) - 1]); | |||||
} | |||||
} | |||||
/** | |||||
* Clear HashTable | |||||
* | |||||
*/ | |||||
public function clear() | |||||
{ | |||||
$this->items = array(); | |||||
$this->keyMap = array(); | |||||
} | |||||
/** | |||||
* Count | |||||
* | |||||
* @return int | |||||
*/ | |||||
public function count() | |||||
{ | |||||
return count($this->items); | |||||
} | |||||
/** | |||||
* Get index for hash code | |||||
* | |||||
* @param string $pHashCode | |||||
* @return int Index | |||||
*/ | |||||
public function getIndexForHashCode($pHashCode = '') | |||||
{ | |||||
return array_search($pHashCode, $this->keyMap); | |||||
} | |||||
/** | |||||
* Get by index | |||||
* | |||||
* @param int $pIndex | |||||
* @return PHPExcel_IComparable | |||||
* | |||||
*/ | |||||
public function getByIndex($pIndex = 0) | |||||
{ | |||||
if (isset($this->keyMap[$pIndex])) { | |||||
return $this->getByHashCode($this->keyMap[$pIndex]); | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* Get by hashcode | |||||
* | |||||
* @param string $pHashCode | |||||
* @return PHPExcel_IComparable | |||||
* | |||||
*/ | |||||
public function getByHashCode($pHashCode = '') | |||||
{ | |||||
if (isset($this->items[$pHashCode])) { | |||||
return $this->items[$pHashCode]; | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* HashTable to array | |||||
* | |||||
* @return PHPExcel_IComparable[] | |||||
*/ | |||||
public function toArray() | |||||
{ | |||||
return $this->items; | |||||
} | |||||
/** | |||||
* Implement PHP __clone to create a deep clone, not just a shallow copy. | |||||
*/ | |||||
public function __clone() | |||||
{ | |||||
$vars = get_object_vars($this); | |||||
foreach ($vars as $key => $value) { | |||||
if (is_object($value)) { | |||||
$this->$key = clone $value; | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,808 @@ | |||||
<?php | |||||
class PHPExcel_Helper_HTML | |||||
{ | |||||
protected static $colourMap = array( | |||||
'aliceblue' => 'f0f8ff', | |||||
'antiquewhite' => 'faebd7', | |||||
'antiquewhite1' => 'ffefdb', | |||||
'antiquewhite2' => 'eedfcc', | |||||
'antiquewhite3' => 'cdc0b0', | |||||
'antiquewhite4' => '8b8378', | |||||
'aqua' => '00ffff', | |||||
'aquamarine1' => '7fffd4', | |||||
'aquamarine2' => '76eec6', | |||||
'aquamarine4' => '458b74', | |||||
'azure1' => 'f0ffff', | |||||
'azure2' => 'e0eeee', | |||||
'azure3' => 'c1cdcd', | |||||
'azure4' => '838b8b', | |||||
'beige' => 'f5f5dc', | |||||
'bisque1' => 'ffe4c4', | |||||
'bisque2' => 'eed5b7', | |||||
'bisque3' => 'cdb79e', | |||||
'bisque4' => '8b7d6b', | |||||
'black' => '000000', | |||||
'blanchedalmond' => 'ffebcd', | |||||
'blue' => '0000ff', | |||||
'blue1' => '0000ff', | |||||
'blue2' => '0000ee', | |||||
'blue4' => '00008b', | |||||
'blueviolet' => '8a2be2', | |||||
'brown' => 'a52a2a', | |||||
'brown1' => 'ff4040', | |||||
'brown2' => 'ee3b3b', | |||||
'brown3' => 'cd3333', | |||||
'brown4' => '8b2323', | |||||
'burlywood' => 'deb887', | |||||
'burlywood1' => 'ffd39b', | |||||
'burlywood2' => 'eec591', | |||||
'burlywood3' => 'cdaa7d', | |||||
'burlywood4' => '8b7355', | |||||
'cadetblue' => '5f9ea0', | |||||
'cadetblue1' => '98f5ff', | |||||
'cadetblue2' => '8ee5ee', | |||||
'cadetblue3' => '7ac5cd', | |||||
'cadetblue4' => '53868b', | |||||
'chartreuse1' => '7fff00', | |||||
'chartreuse2' => '76ee00', | |||||
'chartreuse3' => '66cd00', | |||||
'chartreuse4' => '458b00', | |||||
'chocolate' => 'd2691e', | |||||
'chocolate1' => 'ff7f24', | |||||
'chocolate2' => 'ee7621', | |||||
'chocolate3' => 'cd661d', | |||||
'coral' => 'ff7f50', | |||||
'coral1' => 'ff7256', | |||||
'coral2' => 'ee6a50', | |||||
'coral3' => 'cd5b45', | |||||
'coral4' => '8b3e2f', | |||||
'cornflowerblue' => '6495ed', | |||||
'cornsilk1' => 'fff8dc', | |||||
'cornsilk2' => 'eee8cd', | |||||
'cornsilk3' => 'cdc8b1', | |||||
'cornsilk4' => '8b8878', | |||||
'cyan1' => '00ffff', | |||||
'cyan2' => '00eeee', | |||||
'cyan3' => '00cdcd', | |||||
'cyan4' => '008b8b', | |||||
'darkgoldenrod' => 'b8860b', | |||||
'darkgoldenrod1' => 'ffb90f', | |||||
'darkgoldenrod2' => 'eead0e', | |||||
'darkgoldenrod3' => 'cd950c', | |||||
'darkgoldenrod4' => '8b6508', | |||||
'darkgreen' => '006400', | |||||
'darkkhaki' => 'bdb76b', | |||||
'darkolivegreen' => '556b2f', | |||||
'darkolivegreen1' => 'caff70', | |||||
'darkolivegreen2' => 'bcee68', | |||||
'darkolivegreen3' => 'a2cd5a', | |||||
'darkolivegreen4' => '6e8b3d', | |||||
'darkorange' => 'ff8c00', | |||||
'darkorange1' => 'ff7f00', | |||||
'darkorange2' => 'ee7600', | |||||
'darkorange3' => 'cd6600', | |||||
'darkorange4' => '8b4500', | |||||
'darkorchid' => '9932cc', | |||||
'darkorchid1' => 'bf3eff', | |||||
'darkorchid2' => 'b23aee', | |||||
'darkorchid3' => '9a32cd', | |||||
'darkorchid4' => '68228b', | |||||
'darksalmon' => 'e9967a', | |||||
'darkseagreen' => '8fbc8f', | |||||
'darkseagreen1' => 'c1ffc1', | |||||
'darkseagreen2' => 'b4eeb4', | |||||
'darkseagreen3' => '9bcd9b', | |||||
'darkseagreen4' => '698b69', | |||||
'darkslateblue' => '483d8b', | |||||
'darkslategray' => '2f4f4f', | |||||
'darkslategray1' => '97ffff', | |||||
'darkslategray2' => '8deeee', | |||||
'darkslategray3' => '79cdcd', | |||||
'darkslategray4' => '528b8b', | |||||
'darkturquoise' => '00ced1', | |||||
'darkviolet' => '9400d3', | |||||
'deeppink1' => 'ff1493', | |||||
'deeppink2' => 'ee1289', | |||||
'deeppink3' => 'cd1076', | |||||
'deeppink4' => '8b0a50', | |||||
'deepskyblue1' => '00bfff', | |||||
'deepskyblue2' => '00b2ee', | |||||
'deepskyblue3' => '009acd', | |||||
'deepskyblue4' => '00688b', | |||||
'dimgray' => '696969', | |||||
'dodgerblue1' => '1e90ff', | |||||
'dodgerblue2' => '1c86ee', | |||||
'dodgerblue3' => '1874cd', | |||||
'dodgerblue4' => '104e8b', | |||||
'firebrick' => 'b22222', | |||||
'firebrick1' => 'ff3030', | |||||
'firebrick2' => 'ee2c2c', | |||||
'firebrick3' => 'cd2626', | |||||
'firebrick4' => '8b1a1a', | |||||
'floralwhite' => 'fffaf0', | |||||
'forestgreen' => '228b22', | |||||
'fuchsia' => 'ff00ff', | |||||
'gainsboro' => 'dcdcdc', | |||||
'ghostwhite' => 'f8f8ff', | |||||
'gold1' => 'ffd700', | |||||
'gold2' => 'eec900', | |||||
'gold3' => 'cdad00', | |||||
'gold4' => '8b7500', | |||||
'goldenrod' => 'daa520', | |||||
'goldenrod1' => 'ffc125', | |||||
'goldenrod2' => 'eeb422', | |||||
'goldenrod3' => 'cd9b1d', | |||||
'goldenrod4' => '8b6914', | |||||
'gray' => 'bebebe', | |||||
'gray1' => '030303', | |||||
'gray10' => '1a1a1a', | |||||
'gray11' => '1c1c1c', | |||||
'gray12' => '1f1f1f', | |||||
'gray13' => '212121', | |||||
'gray14' => '242424', | |||||
'gray15' => '262626', | |||||
'gray16' => '292929', | |||||
'gray17' => '2b2b2b', | |||||
'gray18' => '2e2e2e', | |||||
'gray19' => '303030', | |||||
'gray2' => '050505', | |||||
'gray20' => '333333', | |||||
'gray21' => '363636', | |||||
'gray22' => '383838', | |||||
'gray23' => '3b3b3b', | |||||
'gray24' => '3d3d3d', | |||||
'gray25' => '404040', | |||||
'gray26' => '424242', | |||||
'gray27' => '454545', | |||||
'gray28' => '474747', | |||||
'gray29' => '4a4a4a', | |||||
'gray3' => '080808', | |||||
'gray30' => '4d4d4d', | |||||
'gray31' => '4f4f4f', | |||||
'gray32' => '525252', | |||||
'gray33' => '545454', | |||||
'gray34' => '575757', | |||||
'gray35' => '595959', | |||||
'gray36' => '5c5c5c', | |||||
'gray37' => '5e5e5e', | |||||
'gray38' => '616161', | |||||
'gray39' => '636363', | |||||
'gray4' => '0a0a0a', | |||||
'gray40' => '666666', | |||||
'gray41' => '696969', | |||||
'gray42' => '6b6b6b', | |||||
'gray43' => '6e6e6e', | |||||
'gray44' => '707070', | |||||
'gray45' => '737373', | |||||
'gray46' => '757575', | |||||
'gray47' => '787878', | |||||
'gray48' => '7a7a7a', | |||||
'gray49' => '7d7d7d', | |||||
'gray5' => '0d0d0d', | |||||
'gray50' => '7f7f7f', | |||||
'gray51' => '828282', | |||||
'gray52' => '858585', | |||||
'gray53' => '878787', | |||||
'gray54' => '8a8a8a', | |||||
'gray55' => '8c8c8c', | |||||
'gray56' => '8f8f8f', | |||||
'gray57' => '919191', | |||||
'gray58' => '949494', | |||||
'gray59' => '969696', | |||||
'gray6' => '0f0f0f', | |||||
'gray60' => '999999', | |||||
'gray61' => '9c9c9c', | |||||
'gray62' => '9e9e9e', | |||||
'gray63' => 'a1a1a1', | |||||
'gray64' => 'a3a3a3', | |||||
'gray65' => 'a6a6a6', | |||||
'gray66' => 'a8a8a8', | |||||
'gray67' => 'ababab', | |||||
'gray68' => 'adadad', | |||||
'gray69' => 'b0b0b0', | |||||
'gray7' => '121212', | |||||
'gray70' => 'b3b3b3', | |||||
'gray71' => 'b5b5b5', | |||||
'gray72' => 'b8b8b8', | |||||
'gray73' => 'bababa', | |||||
'gray74' => 'bdbdbd', | |||||
'gray75' => 'bfbfbf', | |||||
'gray76' => 'c2c2c2', | |||||
'gray77' => 'c4c4c4', | |||||
'gray78' => 'c7c7c7', | |||||
'gray79' => 'c9c9c9', | |||||
'gray8' => '141414', | |||||
'gray80' => 'cccccc', | |||||
'gray81' => 'cfcfcf', | |||||
'gray82' => 'd1d1d1', | |||||
'gray83' => 'd4d4d4', | |||||
'gray84' => 'd6d6d6', | |||||
'gray85' => 'd9d9d9', | |||||
'gray86' => 'dbdbdb', | |||||
'gray87' => 'dedede', | |||||
'gray88' => 'e0e0e0', | |||||
'gray89' => 'e3e3e3', | |||||
'gray9' => '171717', | |||||
'gray90' => 'e5e5e5', | |||||
'gray91' => 'e8e8e8', | |||||
'gray92' => 'ebebeb', | |||||
'gray93' => 'ededed', | |||||
'gray94' => 'f0f0f0', | |||||
'gray95' => 'f2f2f2', | |||||
'gray97' => 'f7f7f7', | |||||
'gray98' => 'fafafa', | |||||
'gray99' => 'fcfcfc', | |||||
'green' => '00ff00', | |||||
'green1' => '00ff00', | |||||
'green2' => '00ee00', | |||||
'green3' => '00cd00', | |||||
'green4' => '008b00', | |||||
'greenyellow' => 'adff2f', | |||||
'honeydew1' => 'f0fff0', | |||||
'honeydew2' => 'e0eee0', | |||||
'honeydew3' => 'c1cdc1', | |||||
'honeydew4' => '838b83', | |||||
'hotpink' => 'ff69b4', | |||||
'hotpink1' => 'ff6eb4', | |||||
'hotpink2' => 'ee6aa7', | |||||
'hotpink3' => 'cd6090', | |||||
'hotpink4' => '8b3a62', | |||||
'indianred' => 'cd5c5c', | |||||
'indianred1' => 'ff6a6a', | |||||
'indianred2' => 'ee6363', | |||||
'indianred3' => 'cd5555', | |||||
'indianred4' => '8b3a3a', | |||||
'ivory1' => 'fffff0', | |||||
'ivory2' => 'eeeee0', | |||||
'ivory3' => 'cdcdc1', | |||||
'ivory4' => '8b8b83', | |||||
'khaki' => 'f0e68c', | |||||
'khaki1' => 'fff68f', | |||||
'khaki2' => 'eee685', | |||||
'khaki3' => 'cdc673', | |||||
'khaki4' => '8b864e', | |||||
'lavender' => 'e6e6fa', | |||||
'lavenderblush1' => 'fff0f5', | |||||
'lavenderblush2' => 'eee0e5', | |||||
'lavenderblush3' => 'cdc1c5', | |||||
'lavenderblush4' => '8b8386', | |||||
'lawngreen' => '7cfc00', | |||||
'lemonchiffon1' => 'fffacd', | |||||
'lemonchiffon2' => 'eee9bf', | |||||
'lemonchiffon3' => 'cdc9a5', | |||||
'lemonchiffon4' => '8b8970', | |||||
'light' => 'eedd82', | |||||
'lightblue' => 'add8e6', | |||||
'lightblue1' => 'bfefff', | |||||
'lightblue2' => 'b2dfee', | |||||
'lightblue3' => '9ac0cd', | |||||
'lightblue4' => '68838b', | |||||
'lightcoral' => 'f08080', | |||||
'lightcyan1' => 'e0ffff', | |||||
'lightcyan2' => 'd1eeee', | |||||
'lightcyan3' => 'b4cdcd', | |||||
'lightcyan4' => '7a8b8b', | |||||
'lightgoldenrod1' => 'ffec8b', | |||||
'lightgoldenrod2' => 'eedc82', | |||||
'lightgoldenrod3' => 'cdbe70', | |||||
'lightgoldenrod4' => '8b814c', | |||||
'lightgoldenrodyellow' => 'fafad2', | |||||
'lightgray' => 'd3d3d3', | |||||
'lightpink' => 'ffb6c1', | |||||
'lightpink1' => 'ffaeb9', | |||||
'lightpink2' => 'eea2ad', | |||||
'lightpink3' => 'cd8c95', | |||||
'lightpink4' => '8b5f65', | |||||
'lightsalmon1' => 'ffa07a', | |||||
'lightsalmon2' => 'ee9572', | |||||
'lightsalmon3' => 'cd8162', | |||||
'lightsalmon4' => '8b5742', | |||||
'lightseagreen' => '20b2aa', | |||||
'lightskyblue' => '87cefa', | |||||
'lightskyblue1' => 'b0e2ff', | |||||
'lightskyblue2' => 'a4d3ee', | |||||
'lightskyblue3' => '8db6cd', | |||||
'lightskyblue4' => '607b8b', | |||||
'lightslateblue' => '8470ff', | |||||
'lightslategray' => '778899', | |||||
'lightsteelblue' => 'b0c4de', | |||||
'lightsteelblue1' => 'cae1ff', | |||||
'lightsteelblue2' => 'bcd2ee', | |||||
'lightsteelblue3' => 'a2b5cd', | |||||
'lightsteelblue4' => '6e7b8b', | |||||
'lightyellow1' => 'ffffe0', | |||||
'lightyellow2' => 'eeeed1', | |||||
'lightyellow3' => 'cdcdb4', | |||||
'lightyellow4' => '8b8b7a', | |||||
'lime' => '00ff00', | |||||
'limegreen' => '32cd32', | |||||
'linen' => 'faf0e6', | |||||
'magenta' => 'ff00ff', | |||||
'magenta2' => 'ee00ee', | |||||
'magenta3' => 'cd00cd', | |||||
'magenta4' => '8b008b', | |||||
'maroon' => 'b03060', | |||||
'maroon1' => 'ff34b3', | |||||
'maroon2' => 'ee30a7', | |||||
'maroon3' => 'cd2990', | |||||
'maroon4' => '8b1c62', | |||||
'medium' => '66cdaa', | |||||
'mediumaquamarine' => '66cdaa', | |||||
'mediumblue' => '0000cd', | |||||
'mediumorchid' => 'ba55d3', | |||||
'mediumorchid1' => 'e066ff', | |||||
'mediumorchid2' => 'd15fee', | |||||
'mediumorchid3' => 'b452cd', | |||||
'mediumorchid4' => '7a378b', | |||||
'mediumpurple' => '9370db', | |||||
'mediumpurple1' => 'ab82ff', | |||||
'mediumpurple2' => '9f79ee', | |||||
'mediumpurple3' => '8968cd', | |||||
'mediumpurple4' => '5d478b', | |||||
'mediumseagreen' => '3cb371', | |||||
'mediumslateblue' => '7b68ee', | |||||
'mediumspringgreen' => '00fa9a', | |||||
'mediumturquoise' => '48d1cc', | |||||
'mediumvioletred' => 'c71585', | |||||
'midnightblue' => '191970', | |||||
'mintcream' => 'f5fffa', | |||||
'mistyrose1' => 'ffe4e1', | |||||
'mistyrose2' => 'eed5d2', | |||||
'mistyrose3' => 'cdb7b5', | |||||
'mistyrose4' => '8b7d7b', | |||||
'moccasin' => 'ffe4b5', | |||||
'navajowhite1' => 'ffdead', | |||||
'navajowhite2' => 'eecfa1', | |||||
'navajowhite3' => 'cdb38b', | |||||
'navajowhite4' => '8b795e', | |||||
'navy' => '000080', | |||||
'navyblue' => '000080', | |||||
'oldlace' => 'fdf5e6', | |||||
'olive' => '808000', | |||||
'olivedrab' => '6b8e23', | |||||
'olivedrab1' => 'c0ff3e', | |||||
'olivedrab2' => 'b3ee3a', | |||||
'olivedrab4' => '698b22', | |||||
'orange' => 'ffa500', | |||||
'orange1' => 'ffa500', | |||||
'orange2' => 'ee9a00', | |||||
'orange3' => 'cd8500', | |||||
'orange4' => '8b5a00', | |||||
'orangered1' => 'ff4500', | |||||
'orangered2' => 'ee4000', | |||||
'orangered3' => 'cd3700', | |||||
'orangered4' => '8b2500', | |||||
'orchid' => 'da70d6', | |||||
'orchid1' => 'ff83fa', | |||||
'orchid2' => 'ee7ae9', | |||||
'orchid3' => 'cd69c9', | |||||
'orchid4' => '8b4789', | |||||
'pale' => 'db7093', | |||||
'palegoldenrod' => 'eee8aa', | |||||
'palegreen' => '98fb98', | |||||
'palegreen1' => '9aff9a', | |||||
'palegreen2' => '90ee90', | |||||
'palegreen3' => '7ccd7c', | |||||
'palegreen4' => '548b54', | |||||
'paleturquoise' => 'afeeee', | |||||
'paleturquoise1' => 'bbffff', | |||||
'paleturquoise2' => 'aeeeee', | |||||
'paleturquoise3' => '96cdcd', | |||||
'paleturquoise4' => '668b8b', | |||||
'palevioletred' => 'db7093', | |||||
'palevioletred1' => 'ff82ab', | |||||
'palevioletred2' => 'ee799f', | |||||
'palevioletred3' => 'cd6889', | |||||
'palevioletred4' => '8b475d', | |||||
'papayawhip' => 'ffefd5', | |||||
'peachpuff1' => 'ffdab9', | |||||
'peachpuff2' => 'eecbad', | |||||
'peachpuff3' => 'cdaf95', | |||||
'peachpuff4' => '8b7765', | |||||
'pink' => 'ffc0cb', | |||||
'pink1' => 'ffb5c5', | |||||
'pink2' => 'eea9b8', | |||||
'pink3' => 'cd919e', | |||||
'pink4' => '8b636c', | |||||
'plum' => 'dda0dd', | |||||
'plum1' => 'ffbbff', | |||||
'plum2' => 'eeaeee', | |||||
'plum3' => 'cd96cd', | |||||
'plum4' => '8b668b', | |||||
'powderblue' => 'b0e0e6', | |||||
'purple' => 'a020f0', | |||||
'rebeccapurple' => '663399', | |||||
'purple1' => '9b30ff', | |||||
'purple2' => '912cee', | |||||
'purple3' => '7d26cd', | |||||
'purple4' => '551a8b', | |||||
'red' => 'ff0000', | |||||
'red1' => 'ff0000', | |||||
'red2' => 'ee0000', | |||||
'red3' => 'cd0000', | |||||
'red4' => '8b0000', | |||||
'rosybrown' => 'bc8f8f', | |||||
'rosybrown1' => 'ffc1c1', | |||||
'rosybrown2' => 'eeb4b4', | |||||
'rosybrown3' => 'cd9b9b', | |||||
'rosybrown4' => '8b6969', | |||||
'royalblue' => '4169e1', | |||||
'royalblue1' => '4876ff', | |||||
'royalblue2' => '436eee', | |||||
'royalblue3' => '3a5fcd', | |||||
'royalblue4' => '27408b', | |||||
'saddlebrown' => '8b4513', | |||||
'salmon' => 'fa8072', | |||||
'salmon1' => 'ff8c69', | |||||
'salmon2' => 'ee8262', | |||||
'salmon3' => 'cd7054', | |||||
'salmon4' => '8b4c39', | |||||
'sandybrown' => 'f4a460', | |||||
'seagreen1' => '54ff9f', | |||||
'seagreen2' => '4eee94', | |||||
'seagreen3' => '43cd80', | |||||
'seagreen4' => '2e8b57', | |||||
'seashell1' => 'fff5ee', | |||||
'seashell2' => 'eee5de', | |||||
'seashell3' => 'cdc5bf', | |||||
'seashell4' => '8b8682', | |||||
'sienna' => 'a0522d', | |||||
'sienna1' => 'ff8247', | |||||
'sienna2' => 'ee7942', | |||||
'sienna3' => 'cd6839', | |||||
'sienna4' => '8b4726', | |||||
'silver' => 'c0c0c0', | |||||
'skyblue' => '87ceeb', | |||||
'skyblue1' => '87ceff', | |||||
'skyblue2' => '7ec0ee', | |||||
'skyblue3' => '6ca6cd', | |||||
'skyblue4' => '4a708b', | |||||
'slateblue' => '6a5acd', | |||||
'slateblue1' => '836fff', | |||||
'slateblue2' => '7a67ee', | |||||
'slateblue3' => '6959cd', | |||||
'slateblue4' => '473c8b', | |||||
'slategray' => '708090', | |||||
'slategray1' => 'c6e2ff', | |||||
'slategray2' => 'b9d3ee', | |||||
'slategray3' => '9fb6cd', | |||||
'slategray4' => '6c7b8b', | |||||
'snow1' => 'fffafa', | |||||
'snow2' => 'eee9e9', | |||||
'snow3' => 'cdc9c9', | |||||
'snow4' => '8b8989', | |||||
'springgreen1' => '00ff7f', | |||||
'springgreen2' => '00ee76', | |||||
'springgreen3' => '00cd66', | |||||
'springgreen4' => '008b45', | |||||
'steelblue' => '4682b4', | |||||
'steelblue1' => '63b8ff', | |||||
'steelblue2' => '5cacee', | |||||
'steelblue3' => '4f94cd', | |||||
'steelblue4' => '36648b', | |||||
'tan' => 'd2b48c', | |||||
'tan1' => 'ffa54f', | |||||
'tan2' => 'ee9a49', | |||||
'tan3' => 'cd853f', | |||||
'tan4' => '8b5a2b', | |||||
'teal' => '008080', | |||||
'thistle' => 'd8bfd8', | |||||
'thistle1' => 'ffe1ff', | |||||
'thistle2' => 'eed2ee', | |||||
'thistle3' => 'cdb5cd', | |||||
'thistle4' => '8b7b8b', | |||||
'tomato1' => 'ff6347', | |||||
'tomato2' => 'ee5c42', | |||||
'tomato3' => 'cd4f39', | |||||
'tomato4' => '8b3626', | |||||
'turquoise' => '40e0d0', | |||||
'turquoise1' => '00f5ff', | |||||
'turquoise2' => '00e5ee', | |||||
'turquoise3' => '00c5cd', | |||||
'turquoise4' => '00868b', | |||||
'violet' => 'ee82ee', | |||||
'violetred' => 'd02090', | |||||
'violetred1' => 'ff3e96', | |||||
'violetred2' => 'ee3a8c', | |||||
'violetred3' => 'cd3278', | |||||
'violetred4' => '8b2252', | |||||
'wheat' => 'f5deb3', | |||||
'wheat1' => 'ffe7ba', | |||||
'wheat2' => 'eed8ae', | |||||
'wheat3' => 'cdba96', | |||||
'wheat4' => '8b7e66', | |||||
'white' => 'ffffff', | |||||
'whitesmoke' => 'f5f5f5', | |||||
'yellow' => 'ffff00', | |||||
'yellow1' => 'ffff00', | |||||
'yellow2' => 'eeee00', | |||||
'yellow3' => 'cdcd00', | |||||
'yellow4' => '8b8b00', | |||||
'yellowgreen' => '9acd32', | |||||
); | |||||
protected $face; | |||||
protected $size; | |||||
protected $color; | |||||
protected $bold = false; | |||||
protected $italic = false; | |||||
protected $underline = false; | |||||
protected $superscript = false; | |||||
protected $subscript = false; | |||||
protected $strikethrough = false; | |||||
protected $startTagCallbacks = array( | |||||
'font' => 'startFontTag', | |||||
'b' => 'startBoldTag', | |||||
'strong' => 'startBoldTag', | |||||
'i' => 'startItalicTag', | |||||
'em' => 'startItalicTag', | |||||
'u' => 'startUnderlineTag', | |||||
'ins' => 'startUnderlineTag', | |||||
'del' => 'startStrikethruTag', | |||||
'sup' => 'startSuperscriptTag', | |||||
'sub' => 'startSubscriptTag', | |||||
); | |||||
protected $endTagCallbacks = array( | |||||
'font' => 'endFontTag', | |||||
'b' => 'endBoldTag', | |||||
'strong' => 'endBoldTag', | |||||
'i' => 'endItalicTag', | |||||
'em' => 'endItalicTag', | |||||
'u' => 'endUnderlineTag', | |||||
'ins' => 'endUnderlineTag', | |||||
'del' => 'endStrikethruTag', | |||||
'sup' => 'endSuperscriptTag', | |||||
'sub' => 'endSubscriptTag', | |||||
'br' => 'breakTag', | |||||
'p' => 'breakTag', | |||||
'h1' => 'breakTag', | |||||
'h2' => 'breakTag', | |||||
'h3' => 'breakTag', | |||||
'h4' => 'breakTag', | |||||
'h5' => 'breakTag', | |||||
'h6' => 'breakTag', | |||||
); | |||||
protected $stack = array(); | |||||
protected $stringData = ''; | |||||
protected $richTextObject; | |||||
protected function initialise() | |||||
{ | |||||
$this->face = $this->size = $this->color = null; | |||||
$this->bold = $this->italic = $this->underline = $this->superscript = $this->subscript = $this->strikethrough = false; | |||||
$this->stack = array(); | |||||
$this->stringData = ''; | |||||
} | |||||
public function toRichTextObject($html) | |||||
{ | |||||
$this->initialise(); | |||||
// Create a new DOM object | |||||
$dom = new \DOMDocument; | |||||
// Load the HTML file into the DOM object | |||||
// Note the use of error suppression, because typically this will be an html fragment, so not fully valid markup | |||||
$loaded = @$dom->loadHTML($html); | |||||
// Discard excess white space | |||||
$dom->preserveWhiteSpace = false; | |||||
$this->richTextObject = new PHPExcel_RichText();; | |||||
$this->parseElements($dom); | |||||
// Clean any further spurious whitespace | |||||
$this->cleanWhitespace(); | |||||
return $this->richTextObject; | |||||
} | |||||
protected function cleanWhitespace() | |||||
{ | |||||
foreach ($this->richTextObject->getRichTextElements() as $key => $element) { | |||||
$text = $element->getText(); | |||||
// Trim any leading spaces on the first run | |||||
if ($key == 0) { | |||||
$text = ltrim($text); | |||||
} | |||||
// Trim any spaces immediately after a line break | |||||
$text = preg_replace('/\n */mu', "\n", $text); | |||||
$element->setText($text); | |||||
} | |||||
} | |||||
protected function buildTextRun() | |||||
{ | |||||
$text = $this->stringData; | |||||
if (trim($text) === '') { | |||||
return; | |||||
} | |||||
$richtextRun = $this->richTextObject->createTextRun($this->stringData); | |||||
if ($this->face) { | |||||
$richtextRun->getFont()->setName($this->face); | |||||
} | |||||
if ($this->size) { | |||||
$richtextRun->getFont()->setSize($this->size); | |||||
} | |||||
if ($this->color) { | |||||
$richtextRun->getFont()->setColor(new PHPExcel_Style_Color('ff' . $this->color)); | |||||
} | |||||
if ($this->bold) { | |||||
$richtextRun->getFont()->setBold(true); | |||||
} | |||||
if ($this->italic) { | |||||
$richtextRun->getFont()->setItalic(true); | |||||
} | |||||
if ($this->underline) { | |||||
$richtextRun->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); | |||||
} | |||||
if ($this->superscript) { | |||||
$richtextRun->getFont()->setSuperScript(true); | |||||
} | |||||
if ($this->subscript) { | |||||
$richtextRun->getFont()->setSubScript(true); | |||||
} | |||||
if ($this->strikethrough) { | |||||
$richtextRun->getFont()->setStrikethrough(true); | |||||
} | |||||
$this->stringData = ''; | |||||
} | |||||
protected function rgbToColour($rgb) | |||||
{ | |||||
preg_match_all('/\d+/', $rgb, $values); | |||||
foreach ($values[0] as &$value) { | |||||
$value = str_pad(dechex($value), 2, '0', STR_PAD_LEFT); | |||||
} | |||||
return implode($values[0]); | |||||
} | |||||
protected function colourNameLookup($rgb) | |||||
{ | |||||
return self::$colourMap[$rgb]; | |||||
} | |||||
protected function startFontTag($tag) | |||||
{ | |||||
foreach ($tag->attributes as $attribute) { | |||||
$attributeName = strtolower($attribute->name); | |||||
$attributeValue = $attribute->value; | |||||
if ($attributeName == 'color') { | |||||
if (preg_match('/rgb\s*\(/', $attributeValue)) { | |||||
$this->$attributeName = $this->rgbToColour($attributeValue); | |||||
} elseif (strpos(trim($attributeValue), '#') === 0) { | |||||
$this->$attributeName = ltrim($attributeValue, '#'); | |||||
} else { | |||||
$this->$attributeName = $this->colourNameLookup($attributeValue); | |||||
} | |||||
} else { | |||||
$this->$attributeName = $attributeValue; | |||||
} | |||||
} | |||||
} | |||||
protected function endFontTag() | |||||
{ | |||||
$this->face = $this->size = $this->color = null; | |||||
} | |||||
protected function startBoldTag() | |||||
{ | |||||
$this->bold = true; | |||||
} | |||||
protected function endBoldTag() | |||||
{ | |||||
$this->bold = false; | |||||
} | |||||
protected function startItalicTag() | |||||
{ | |||||
$this->italic = true; | |||||
} | |||||
protected function endItalicTag() | |||||
{ | |||||
$this->italic = false; | |||||
} | |||||
protected function startUnderlineTag() | |||||
{ | |||||
$this->underline = true; | |||||
} | |||||
protected function endUnderlineTag() | |||||
{ | |||||
$this->underline = false; | |||||
} | |||||
protected function startSubscriptTag() | |||||
{ | |||||
$this->subscript = true; | |||||
} | |||||
protected function endSubscriptTag() | |||||
{ | |||||
$this->subscript = false; | |||||
} | |||||
protected function startSuperscriptTag() | |||||
{ | |||||
$this->superscript = true; | |||||
} | |||||
protected function endSuperscriptTag() | |||||
{ | |||||
$this->superscript = false; | |||||
} | |||||
protected function startStrikethruTag() | |||||
{ | |||||
$this->strikethrough = true; | |||||
} | |||||
protected function endStrikethruTag() | |||||
{ | |||||
$this->strikethrough = false; | |||||
} | |||||
protected function breakTag() | |||||
{ | |||||
$this->stringData .= "\n"; | |||||
} | |||||
protected function parseTextNode(DOMText $textNode) | |||||
{ | |||||
$domText = preg_replace( | |||||
'/\s+/u', | |||||
' ', | |||||
str_replace(array("\r", "\n"), ' ', $textNode->nodeValue) | |||||
); | |||||
$this->stringData .= $domText; | |||||
$this->buildTextRun(); | |||||
} | |||||
protected function handleCallback($element, $callbackTag, $callbacks) | |||||
{ | |||||
if (isset($callbacks[$callbackTag])) { | |||||
$elementHandler = $callbacks[$callbackTag]; | |||||
if (method_exists($this, $elementHandler)) { | |||||
call_user_func(array($this, $elementHandler), $element); | |||||
} | |||||
} | |||||
} | |||||
protected function parseElementNode(DOMElement $element) | |||||
{ | |||||
$callbackTag = strtolower($element->nodeName); | |||||
$this->stack[] = $callbackTag; | |||||
$this->handleCallback($element, $callbackTag, $this->startTagCallbacks); | |||||
$this->parseElements($element); | |||||
array_pop($this->stack); | |||||
$this->handleCallback($element, $callbackTag, $this->endTagCallbacks); | |||||
} | |||||
protected function parseElements(DOMNode $element) | |||||
{ | |||||
foreach ($element->childNodes as $child) { | |||||
if ($child instanceof DOMText) { | |||||
$this->parseTextNode($child); | |||||
} elseif ($child instanceof DOMElement) { | |||||
$this->parseElementNode($child); | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,34 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_IComparable | |||||
* | |||||
* 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 | |||||
* @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## | |||||
*/ | |||||
interface PHPExcel_IComparable | |||||
{ | |||||
/** | |||||
* Get hash code | |||||
* | |||||
* @return string Hash code | |||||
*/ | |||||
public function getHashCode(); | |||||
} |
@ -0,0 +1,289 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_IOFactory | |||||
* | |||||
* 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 | |||||
* @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_IOFactory | |||||
{ | |||||
/** | |||||
* Search locations | |||||
* | |||||
* @var array | |||||
* @access private | |||||
* @static | |||||
*/ | |||||
private static $searchLocations = array( | |||||
array( 'type' => 'IWriter', 'path' => 'PHPExcel/Writer/{0}.php', 'class' => 'PHPExcel_Writer_{0}' ), | |||||
array( 'type' => 'IReader', 'path' => 'PHPExcel/Reader/{0}.php', 'class' => 'PHPExcel_Reader_{0}' ) | |||||
); | |||||
/** | |||||
* Autoresolve classes | |||||
* | |||||
* @var array | |||||
* @access private | |||||
* @static | |||||
*/ | |||||
private static $autoResolveClasses = array( | |||||
'Excel2007', | |||||
'Excel5', | |||||
'Excel2003XML', | |||||
'OOCalc', | |||||
'SYLK', | |||||
'Gnumeric', | |||||
'HTML', | |||||
'CSV', | |||||
); | |||||
/** | |||||
* Private constructor for PHPExcel_IOFactory | |||||
*/ | |||||
private function __construct() | |||||
{ | |||||
} | |||||
/** | |||||
* Get search locations | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @return array | |||||
*/ | |||||
public static function getSearchLocations() | |||||
{ | |||||
return self::$searchLocations; | |||||
} | |||||
/** | |||||
* Set search locations | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param array $value | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function setSearchLocations($value) | |||||
{ | |||||
if (is_array($value)) { | |||||
self::$searchLocations = $value; | |||||
} else { | |||||
throw new PHPExcel_Reader_Exception('Invalid parameter passed.'); | |||||
} | |||||
} | |||||
/** | |||||
* Add search location | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param string $type Example: IWriter | |||||
* @param string $location Example: PHPExcel/Writer/{0}.php | |||||
* @param string $classname Example: PHPExcel_Writer_[0] | |||||
*/ | |||||
public static function addSearchLocation($type = '', $location = '', $classname = '') | |||||
{ | |||||
self::$searchLocations[] = array( 'type' => $type, 'path' => $location, 'class' => $classname ); | |||||
} | |||||
/** | |||||
* Create PHPExcel_Writer_IWriter | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param PHPExcel $phpExcel | |||||
* @param string $writerType Example: Excel2007 | |||||
* @return PHPExcel_Writer_IWriter | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function createWriter(PHPExcel $phpExcel, $writerType = '') | |||||
{ | |||||
// Search type | |||||
$searchType = 'IWriter'; | |||||
// Include class | |||||
foreach (self::$searchLocations as $searchLocation) { | |||||
if ($searchLocation['type'] == $searchType) { | |||||
$className = str_replace('{0}', $writerType, $searchLocation['class']); | |||||
$instance = new $className($phpExcel); | |||||
if ($instance !== null) { | |||||
return $instance; | |||||
} | |||||
} | |||||
} | |||||
// Nothing found... | |||||
throw new PHPExcel_Reader_Exception("No $searchType found for type $writerType"); | |||||
} | |||||
/** | |||||
* Create PHPExcel_Reader_IReader | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param string $readerType Example: Excel2007 | |||||
* @return PHPExcel_Reader_IReader | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function createReader($readerType = '') | |||||
{ | |||||
// Search type | |||||
$searchType = 'IReader'; | |||||
// Include class | |||||
foreach (self::$searchLocations as $searchLocation) { | |||||
if ($searchLocation['type'] == $searchType) { | |||||
$className = str_replace('{0}', $readerType, $searchLocation['class']); | |||||
$instance = new $className(); | |||||
if ($instance !== null) { | |||||
return $instance; | |||||
} | |||||
} | |||||
} | |||||
// Nothing found... | |||||
throw new PHPExcel_Reader_Exception("No $searchType found for type $readerType"); | |||||
} | |||||
/** | |||||
* Loads PHPExcel from file using automatic PHPExcel_Reader_IReader resolution | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param string $pFilename The name of the spreadsheet file | |||||
* @return PHPExcel | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function load($pFilename) | |||||
{ | |||||
$reader = self::createReaderForFile($pFilename); | |||||
return $reader->load($pFilename); | |||||
} | |||||
/** | |||||
* Identify file type using automatic PHPExcel_Reader_IReader resolution | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param string $pFilename The name of the spreadsheet file to identify | |||||
* @return string | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function identify($pFilename) | |||||
{ | |||||
$reader = self::createReaderForFile($pFilename); | |||||
$className = get_class($reader); | |||||
$classType = explode('_', $className); | |||||
unset($reader); | |||||
return array_pop($classType); | |||||
} | |||||
/** | |||||
* Create PHPExcel_Reader_IReader for file using automatic PHPExcel_Reader_IReader resolution | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param string $pFilename The name of the spreadsheet file | |||||
* @return PHPExcel_Reader_IReader | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function createReaderForFile($pFilename) | |||||
{ | |||||
// First, lucky guess by inspecting file extension | |||||
$pathinfo = pathinfo($pFilename); | |||||
$extensionType = null; | |||||
if (isset($pathinfo['extension'])) { | |||||
switch (strtolower($pathinfo['extension'])) { | |||||
case 'xlsx': // Excel (OfficeOpenXML) Spreadsheet | |||||
case 'xlsm': // Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded) | |||||
case 'xltx': // Excel (OfficeOpenXML) Template | |||||
case 'xltm': // Excel (OfficeOpenXML) Macro Template (macros will be discarded) | |||||
$extensionType = 'Excel2007'; | |||||
break; | |||||
case 'xls': // Excel (BIFF) Spreadsheet | |||||
case 'xlt': // Excel (BIFF) Template | |||||
$extensionType = 'Excel5'; | |||||
break; | |||||
case 'ods': // Open/Libre Offic Calc | |||||
case 'ots': // Open/Libre Offic Calc Template | |||||
$extensionType = 'OOCalc'; | |||||
break; | |||||
case 'slk': | |||||
$extensionType = 'SYLK'; | |||||
break; | |||||
case 'xml': // Excel 2003 SpreadSheetML | |||||
$extensionType = 'Excel2003XML'; | |||||
break; | |||||
case 'gnumeric': | |||||
$extensionType = 'Gnumeric'; | |||||
break; | |||||
case 'htm': | |||||
case 'html': | |||||
$extensionType = 'HTML'; | |||||
break; | |||||
case 'csv': | |||||
// Do nothing | |||||
// We must not try to use CSV reader since it loads | |||||
// all files including Excel files etc. | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
if ($extensionType !== null) { | |||||
$reader = self::createReader($extensionType); | |||||
// Let's see if we are lucky | |||||
if (isset($reader) && $reader->canRead($pFilename)) { | |||||
return $reader; | |||||
} | |||||
} | |||||
} | |||||
// If we reach here then "lucky guess" didn't give any result | |||||
// Try walking through all the options in self::$autoResolveClasses | |||||
foreach (self::$autoResolveClasses as $autoResolveClass) { | |||||
// Ignore our original guess, we know that won't work | |||||
if ($autoResolveClass !== $extensionType) { | |||||
$reader = self::createReader($autoResolveClass); | |||||
if ($reader->canRead($pFilename)) { | |||||
return $reader; | |||||
} | |||||
} | |||||
} | |||||
throw new PHPExcel_Reader_Exception('Unable to identify a reader for this file'); | |||||
} | |||||
} |
@ -0,0 +1,289 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_IOFactory | |||||
* | |||||
* 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 | |||||
* @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_IOFactory | |||||
{ | |||||
/** | |||||
* Search locations | |||||
* | |||||
* @var array | |||||
* @access private | |||||
* @static | |||||
*/ | |||||
private static $searchLocations = array( | |||||
array( 'type' => 'IWriter', 'path' => 'PHPExcel/Writer/{0}.php', 'class' => 'PHPExcel_Writer_{0}' ), | |||||
array( 'type' => 'IReader', 'path' => 'PHPExcel/Reader/{0}.php', 'class' => 'PHPExcel_Reader_{0}' ) | |||||
); | |||||
/** | |||||
* Autoresolve classes | |||||
* | |||||
* @var array | |||||
* @access private | |||||
* @static | |||||
*/ | |||||
private static $autoResolveClasses = array( | |||||
'Excel2007', | |||||
'Excel5', | |||||
'Excel2003XML', | |||||
'OOCalc', | |||||
'SYLK', | |||||
'Gnumeric', | |||||
'HTML', | |||||
'CSV', | |||||
); | |||||
/** | |||||
* Private constructor for PHPExcel_IOFactory | |||||
*/ | |||||
private function __construct() | |||||
{ | |||||
} | |||||
/** | |||||
* Get search locations | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @return array | |||||
*/ | |||||
public static function getSearchLocations() | |||||
{ | |||||
return self::$searchLocations; | |||||
} | |||||
/** | |||||
* Set search locations | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param array $value | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function setSearchLocations($value) | |||||
{ | |||||
if (is_array($value)) { | |||||
self::$searchLocations = $value; | |||||
} else { | |||||
throw new PHPExcel_Reader_Exception('Invalid parameter passed.'); | |||||
} | |||||
} | |||||
/** | |||||
* Add search location | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param string $type Example: IWriter | |||||
* @param string $location Example: PHPExcel/Writer/{0}.php | |||||
* @param string $classname Example: PHPExcel_Writer_{0} | |||||
*/ | |||||
public static function addSearchLocation($type = '', $location = '', $classname = '') | |||||
{ | |||||
self::$searchLocations[] = array( 'type' => $type, 'path' => $location, 'class' => $classname ); | |||||
} | |||||
/** | |||||
* Create PHPExcel_Writer_IWriter | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param PHPExcel $phpExcel | |||||
* @param string $writerType Example: Excel2007 | |||||
* @return PHPExcel_Writer_IWriter | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function createWriter(PHPExcel $phpExcel, $writerType = '') | |||||
{ | |||||
// Search type | |||||
$searchType = 'IWriter'; | |||||
// Include class | |||||
foreach (self::$searchLocations as $searchLocation) { | |||||
if ($searchLocation['type'] == $searchType) { | |||||
$className = str_replace('{0}', $writerType, $searchLocation['class']); | |||||
$instance = new $className($phpExcel); | |||||
if ($instance !== null) { | |||||
return $instance; | |||||
} | |||||
} | |||||
} | |||||
// Nothing found... | |||||
throw new PHPExcel_Reader_Exception("No $searchType found for type $writerType"); | |||||
} | |||||
/** | |||||
* Create PHPExcel_Reader_IReader | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param string $readerType Example: Excel2007 | |||||
* @return PHPExcel_Reader_IReader | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function createReader($readerType = '') | |||||
{ | |||||
// Search type | |||||
$searchType = 'IReader'; | |||||
// Include class | |||||
foreach (self::$searchLocations as $searchLocation) { | |||||
if ($searchLocation['type'] == $searchType) { | |||||
$className = str_replace('{0}', $readerType, $searchLocation['class']); | |||||
$instance = new $className(); | |||||
if ($instance !== null) { | |||||
return $instance; | |||||
} | |||||
} | |||||
} | |||||
// Nothing found... | |||||
throw new PHPExcel_Reader_Exception("No $searchType found for type $readerType"); | |||||
} | |||||
/** | |||||
* Loads PHPExcel from file using automatic PHPExcel_Reader_IReader resolution | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param string $pFilename The name of the spreadsheet file | |||||
* @return PHPExcel | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function load($pFilename) | |||||
{ | |||||
$reader = self::createReaderForFile($pFilename); | |||||
return $reader->load($pFilename); | |||||
} | |||||
/** | |||||
* Identify file type using automatic PHPExcel_Reader_IReader resolution | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param string $pFilename The name of the spreadsheet file to identify | |||||
* @return string | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function identify($pFilename) | |||||
{ | |||||
$reader = self::createReaderForFile($pFilename); | |||||
$className = get_class($reader); | |||||
$classType = explode('_', $className); | |||||
unset($reader); | |||||
return array_pop($classType); | |||||
} | |||||
/** | |||||
* Create PHPExcel_Reader_IReader for file using automatic PHPExcel_Reader_IReader resolution | |||||
* | |||||
* @static | |||||
* @access public | |||||
* @param string $pFilename The name of the spreadsheet file | |||||
* @return PHPExcel_Reader_IReader | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public static function createReaderForFile($pFilename) | |||||
{ | |||||
// First, lucky guess by inspecting file extension | |||||
$pathinfo = pathinfo($pFilename); | |||||
$extensionType = null; | |||||
if (isset($pathinfo['extension'])) { | |||||
switch (strtolower($pathinfo['extension'])) { | |||||
case 'xlsx': // Excel (OfficeOpenXML) Spreadsheet | |||||
case 'xlsm': // Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded) | |||||
case 'xltx': // Excel (OfficeOpenXML) Template | |||||
case 'xltm': // Excel (OfficeOpenXML) Macro Template (macros will be discarded) | |||||
$extensionType = 'Excel2007'; | |||||
break; | |||||
case 'xls': // Excel (BIFF) Spreadsheet | |||||
case 'xlt': // Excel (BIFF) Template | |||||
$extensionType = 'Excel5'; | |||||
break; | |||||
case 'ods': // Open/Libre Offic Calc | |||||
case 'ots': // Open/Libre Offic Calc Template | |||||
$extensionType = 'OOCalc'; | |||||
break; | |||||
case 'slk': | |||||
$extensionType = 'SYLK'; | |||||
break; | |||||
case 'xml': // Excel 2003 SpreadSheetML | |||||
$extensionType = 'Excel2003XML'; | |||||
break; | |||||
case 'gnumeric': | |||||
$extensionType = 'Gnumeric'; | |||||
break; | |||||
case 'htm': | |||||
case 'html': | |||||
$extensionType = 'HTML'; | |||||
break; | |||||
case 'csv': | |||||
// Do nothing | |||||
// We must not try to use CSV reader since it loads | |||||
// all files including Excel files etc. | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
if ($extensionType !== null) { | |||||
$reader = self::createReader($extensionType); | |||||
// Let's see if we are lucky | |||||
if (isset($reader) && $reader->canRead($pFilename)) { | |||||
return $reader; | |||||
} | |||||
} | |||||
} | |||||
// If we reach here then "lucky guess" didn't give any result | |||||
// Try walking through all the options in self::$autoResolveClasses | |||||
foreach (self::$autoResolveClasses as $autoResolveClass) { | |||||
// Ignore our original guess, we know that won't work | |||||
if ($autoResolveClass !== $extensionType) { | |||||
$reader = self::createReader($autoResolveClass); | |||||
if ($reader->canRead($pFilename)) { | |||||
return $reader; | |||||
} | |||||
} | |||||
} | |||||
throw new PHPExcel_Reader_Exception('Unable to identify a reader for this file'); | |||||
} | |||||
} |
@ -0,0 +1,249 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_NamedRange | |||||
* | |||||
* 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 | |||||
* @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_NamedRange | |||||
{ | |||||
/** | |||||
* Range name | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $name; | |||||
/** | |||||
* Worksheet on which the named range can be resolved | |||||
* | |||||
* @var PHPExcel_Worksheet | |||||
*/ | |||||
private $worksheet; | |||||
/** | |||||
* Range of the referenced cells | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $range; | |||||
/** | |||||
* Is the named range local? (i.e. can only be used on $this->worksheet) | |||||
* | |||||
* @var bool | |||||
*/ | |||||
private $localOnly; | |||||
/** | |||||
* Scope | |||||
* | |||||
* @var PHPExcel_Worksheet | |||||
*/ | |||||
private $scope; | |||||
/** | |||||
* Create a new NamedRange | |||||
* | |||||
* @param string $pName | |||||
* @param PHPExcel_Worksheet $pWorksheet | |||||
* @param string $pRange | |||||
* @param bool $pLocalOnly | |||||
* @param PHPExcel_Worksheet|null $pScope Scope. Only applies when $pLocalOnly = true. Null for global scope. | |||||
* @throws PHPExcel_Exception | |||||
*/ | |||||
public function __construct($pName = null, PHPExcel_Worksheet $pWorksheet, $pRange = 'A1', $pLocalOnly = false, $pScope = null) | |||||
{ | |||||
// Validate data | |||||
if (($pName === null) || ($pWorksheet === null) || ($pRange === null)) { | |||||
throw new PHPExcel_Exception('Parameters can not be null.'); | |||||
} | |||||
// Set local members | |||||
$this->name = $pName; | |||||
$this->worksheet = $pWorksheet; | |||||
$this->range = $pRange; | |||||
$this->localOnly = $pLocalOnly; | |||||
$this->scope = ($pLocalOnly == true) ? (($pScope == null) ? $pWorksheet : $pScope) : null; | |||||
} | |||||
/** | |||||
* Get name | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getName() | |||||
{ | |||||
return $this->name; | |||||
} | |||||
/** | |||||
* Set name | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_NamedRange | |||||
*/ | |||||
public function setName($value = null) | |||||
{ | |||||
if ($value !== null) { | |||||
// Old title | |||||
$oldTitle = $this->name; | |||||
// Re-attach | |||||
if ($this->worksheet !== null) { | |||||
$this->worksheet->getParent()->removeNamedRange($this->name, $this->worksheet); | |||||
} | |||||
$this->name = $value; | |||||
if ($this->worksheet !== null) { | |||||
$this->worksheet->getParent()->addNamedRange($this); | |||||
} | |||||
// New title | |||||
$newTitle = $this->name; | |||||
PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->worksheet->getParent(), $oldTitle, $newTitle); | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get worksheet | |||||
* | |||||
* @return PHPExcel_Worksheet | |||||
*/ | |||||
public function getWorksheet() | |||||
{ | |||||
return $this->worksheet; | |||||
} | |||||
/** | |||||
* Set worksheet | |||||
* | |||||
* @param PHPExcel_Worksheet $value | |||||
* @return PHPExcel_NamedRange | |||||
*/ | |||||
public function setWorksheet(PHPExcel_Worksheet $value = null) | |||||
{ | |||||
if ($value !== null) { | |||||
$this->worksheet = $value; | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get range | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getRange() | |||||
{ | |||||
return $this->range; | |||||
} | |||||
/** | |||||
* Set range | |||||
* | |||||
* @param string $value | |||||
* @return PHPExcel_NamedRange | |||||
*/ | |||||
public function setRange($value = null) | |||||
{ | |||||
if ($value !== null) { | |||||
$this->range = $value; | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get localOnly | |||||
* | |||||
* @return bool | |||||
*/ | |||||
public function getLocalOnly() | |||||
{ | |||||
return $this->localOnly; | |||||
} | |||||
/** | |||||
* Set localOnly | |||||
* | |||||
* @param bool $value | |||||
* @return PHPExcel_NamedRange | |||||
*/ | |||||
public function setLocalOnly($value = false) | |||||
{ | |||||
$this->localOnly = $value; | |||||
$this->scope = $value ? $this->worksheet : null; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get scope | |||||
* | |||||
* @return PHPExcel_Worksheet|null | |||||
*/ | |||||
public function getScope() | |||||
{ | |||||
return $this->scope; | |||||
} | |||||
/** | |||||
* Set scope | |||||
* | |||||
* @param PHPExcel_Worksheet|null $value | |||||
* @return PHPExcel_NamedRange | |||||
*/ | |||||
public function setScope(PHPExcel_Worksheet $value = null) | |||||
{ | |||||
$this->scope = $value; | |||||
$this->localOnly = ($value == null) ? false : true; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Resolve a named range to a regular cell range | |||||
* | |||||
* @param string $pNamedRange Named range | |||||
* @param PHPExcel_Worksheet|null $pSheet Scope. Use null for global scope | |||||
* @return PHPExcel_NamedRange | |||||
*/ | |||||
public static function resolveRange($pNamedRange = '', PHPExcel_Worksheet $pSheet) | |||||
{ | |||||
return $pSheet->getParent()->getNamedRange($pNamedRange, $pSheet); | |||||
} | |||||
/** | |||||
* Implement PHP __clone to create a deep clone, not just a shallow copy. | |||||
*/ | |||||
public function __clone() | |||||
{ | |||||
$vars = get_object_vars($this); | |||||
foreach ($vars as $key => $value) { | |||||
if (is_object($value)) { | |||||
$this->$key = clone $value; | |||||
} else { | |||||
$this->$key = $value; | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,289 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Reader_Abstract | |||||
* | |||||
* 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_Reader | |||||
* @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## | |||||
*/ | |||||
abstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader | |||||
{ | |||||
/** | |||||
* Read data only? | |||||
* Identifies whether the Reader should only read data values for cells, and ignore any formatting information; | |||||
* or whether it should read both data and formatting | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
protected $readDataOnly = false; | |||||
/** | |||||
* Read empty cells? | |||||
* Identifies whether the Reader should read data values for cells all cells, or should ignore cells containing | |||||
* null value or empty string | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
protected $readEmptyCells = true; | |||||
/** | |||||
* Read charts that are defined in the workbook? | |||||
* Identifies whether the Reader should read the definitions for any charts that exist in the workbook; | |||||
* | |||||
* @var boolean | |||||
*/ | |||||
protected $includeCharts = false; | |||||
/** | |||||
* Restrict which sheets should be loaded? | |||||
* This property holds an array of worksheet names to be loaded. If null, then all worksheets will be loaded. | |||||
* | |||||
* @var array of string | |||||
*/ | |||||
protected $loadSheetsOnly; | |||||
/** | |||||
* PHPExcel_Reader_IReadFilter instance | |||||
* | |||||
* @var PHPExcel_Reader_IReadFilter | |||||
*/ | |||||
protected $readFilter; | |||||
protected $fileHandle = null; | |||||
/** | |||||
* Read data only? | |||||
* If this is true, then the Reader will only read data values for cells, it will not read any formatting information. | |||||
* If false (the default) it will read data and formatting. | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getReadDataOnly() | |||||
{ | |||||
return $this->readDataOnly; | |||||
} | |||||
/** | |||||
* Set read data only | |||||
* Set to true, to advise the Reader only to read data values for cells, and to ignore any formatting information. | |||||
* Set to false (the default) to advise the Reader to read both data and formatting for cells. | |||||
* | |||||
* @param boolean $pValue | |||||
* | |||||
* @return PHPExcel_Reader_IReader | |||||
*/ | |||||
public function setReadDataOnly($pValue = false) | |||||
{ | |||||
$this->readDataOnly = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Read empty cells? | |||||
* If this is true (the default), then the Reader will read data values for all cells, irrespective of value. | |||||
* If false it will not read data for cells containing a null value or an empty string. | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getReadEmptyCells() | |||||
{ | |||||
return $this->readEmptyCells; | |||||
} | |||||
/** | |||||
* Set read empty cells | |||||
* Set to true (the default) to advise the Reader read data values for all cells, irrespective of value. | |||||
* Set to false to advise the Reader to ignore cells containing a null value or an empty string. | |||||
* | |||||
* @param boolean $pValue | |||||
* | |||||
* @return PHPExcel_Reader_IReader | |||||
*/ | |||||
public function setReadEmptyCells($pValue = true) | |||||
{ | |||||
$this->readEmptyCells = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Read charts in workbook? | |||||
* If this is true, then the Reader will include any charts that exist in the workbook. | |||||
* Note that a ReadDataOnly value of false overrides, and charts won't be read regardless of the IncludeCharts value. | |||||
* If false (the default) it will ignore any charts defined in the workbook file. | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getIncludeCharts() | |||||
{ | |||||
return $this->includeCharts; | |||||
} | |||||
/** | |||||
* Set read charts in workbook | |||||
* Set to true, to advise the Reader to include any charts that exist in the workbook. | |||||
* Note that a ReadDataOnly value of false overrides, and charts won't be read regardless of the IncludeCharts value. | |||||
* Set to false (the default) to discard charts. | |||||
* | |||||
* @param boolean $pValue | |||||
* | |||||
* @return PHPExcel_Reader_IReader | |||||
*/ | |||||
public function setIncludeCharts($pValue = false) | |||||
{ | |||||
$this->includeCharts = (boolean) $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get which sheets to load | |||||
* Returns either an array of worksheet names (the list of worksheets that should be loaded), or a null | |||||
* indicating that all worksheets in the workbook should be loaded. | |||||
* | |||||
* @return mixed | |||||
*/ | |||||
public function getLoadSheetsOnly() | |||||
{ | |||||
return $this->loadSheetsOnly; | |||||
} | |||||
/** | |||||
* Set which sheets to load | |||||
* | |||||
* @param mixed $value | |||||
* This should be either an array of worksheet names to be loaded, or a string containing a single worksheet name. | |||||
* If NULL, then it tells the Reader to read all worksheets in the workbook | |||||
* | |||||
* @return PHPExcel_Reader_IReader | |||||
*/ | |||||
public function setLoadSheetsOnly($value = null) | |||||
{ | |||||
if ($value === null) { | |||||
return $this->setLoadAllSheets(); | |||||
} | |||||
$this->loadSheetsOnly = is_array($value) ? $value : array($value); | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set all sheets to load | |||||
* Tells the Reader to load all worksheets from the workbook. | |||||
* | |||||
* @return PHPExcel_Reader_IReader | |||||
*/ | |||||
public function setLoadAllSheets() | |||||
{ | |||||
$this->loadSheetsOnly = null; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Read filter | |||||
* | |||||
* @return PHPExcel_Reader_IReadFilter | |||||
*/ | |||||
public function getReadFilter() | |||||
{ | |||||
return $this->readFilter; | |||||
} | |||||
/** | |||||
* Set read filter | |||||
* | |||||
* @param PHPExcel_Reader_IReadFilter $pValue | |||||
* @return PHPExcel_Reader_IReader | |||||
*/ | |||||
public function setReadFilter(PHPExcel_Reader_IReadFilter $pValue) | |||||
{ | |||||
$this->readFilter = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Open file for reading | |||||
* | |||||
* @param string $pFilename | |||||
* @throws PHPExcel_Reader_Exception | |||||
* @return resource | |||||
*/ | |||||
protected function openFile($pFilename) | |||||
{ | |||||
// Check if file exists | |||||
if (!file_exists($pFilename) || !is_readable($pFilename)) { | |||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); | |||||
} | |||||
// Open file | |||||
$this->fileHandle = fopen($pFilename, 'r'); | |||||
if ($this->fileHandle === false) { | |||||
throw new PHPExcel_Reader_Exception("Could not open file " . $pFilename . " for reading."); | |||||
} | |||||
} | |||||
/** | |||||
* Can the current PHPExcel_Reader_IReader read the file? | |||||
* | |||||
* @param string $pFilename | |||||
* @return boolean | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function canRead($pFilename) | |||||
{ | |||||
// Check if file exists | |||||
try { | |||||
$this->openFile($pFilename); | |||||
} catch (Exception $e) { | |||||
return false; | |||||
} | |||||
$readable = $this->isValidFormat(); | |||||
fclose($this->fileHandle); | |||||
return $readable; | |||||
} | |||||
/** | |||||
* Scan theXML for use of <!ENTITY to prevent XXE/XEE attacks | |||||
* | |||||
* @param string $xml | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function securityScan($xml) | |||||
{ | |||||
$pattern = '/\\0?' . implode('\\0?', str_split('<!DOCTYPE')) . '\\0?/'; | |||||
if (preg_match($pattern, $xml)) { | |||||
throw new PHPExcel_Reader_Exception('Detected use of ENTITY in XML, spreadsheet file load() aborted to prevent XXE/XEE attacks'); | |||||
} | |||||
return $xml; | |||||
} | |||||
/** | |||||
* Scan theXML for use of <!ENTITY to prevent XXE/XEE attacks | |||||
* | |||||
* @param string $filestream | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function securityScanFile($filestream) | |||||
{ | |||||
return $this->securityScan(file_get_contents($filestream)); | |||||
} | |||||
} |
@ -0,0 +1,406 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_Reader_CSV | |||||
* | |||||
* 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_Reader | |||||
* @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_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader | |||||
{ | |||||
/** | |||||
* Input encoding | |||||
* | |||||
* @access private | |||||
* @var string | |||||
*/ | |||||
private $inputEncoding = 'UTF-8'; | |||||
/** | |||||
* Delimiter | |||||
* | |||||
* @access private | |||||
* @var string | |||||
*/ | |||||
private $delimiter = ','; | |||||
/** | |||||
* Enclosure | |||||
* | |||||
* @access private | |||||
* @var string | |||||
*/ | |||||
private $enclosure = '"'; | |||||
/** | |||||
* Sheet index to read | |||||
* | |||||
* @access private | |||||
* @var int | |||||
*/ | |||||
private $sheetIndex = 0; | |||||
/** | |||||
* Load rows contiguously | |||||
* | |||||
* @access private | |||||
* @var int | |||||
*/ | |||||
private $contiguous = false; | |||||
/** | |||||
* Row counter for loading rows contiguously | |||||
* | |||||
* @var int | |||||
*/ | |||||
private $contiguousRow = -1; | |||||
/** | |||||
* Create a new PHPExcel_Reader_CSV | |||||
*/ | |||||
public function __construct() | |||||
{ | |||||
$this->readFilter = new PHPExcel_Reader_DefaultReadFilter(); | |||||
} | |||||
/** | |||||
* Validate that the current file is a CSV file | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
protected function isValidFormat() | |||||
{ | |||||
return true; | |||||
} | |||||
/** | |||||
* Set input encoding | |||||
* | |||||
* @param string $pValue Input encoding | |||||
*/ | |||||
public function setInputEncoding($pValue = 'UTF-8') | |||||
{ | |||||
$this->inputEncoding = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get input encoding | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getInputEncoding() | |||||
{ | |||||
return $this->inputEncoding; | |||||
} | |||||
/** | |||||
* Move filepointer past any BOM marker | |||||
* | |||||
*/ | |||||
protected function skipBOM() | |||||
{ | |||||
rewind($this->fileHandle); | |||||
switch ($this->inputEncoding) { | |||||
case 'UTF-8': | |||||
fgets($this->fileHandle, 4) == "\xEF\xBB\xBF" ? | |||||
fseek($this->fileHandle, 3) : fseek($this->fileHandle, 0); | |||||
break; | |||||
case 'UTF-16LE': | |||||
fgets($this->fileHandle, 3) == "\xFF\xFE" ? | |||||
fseek($this->fileHandle, 2) : fseek($this->fileHandle, 0); | |||||
break; | |||||
case 'UTF-16BE': | |||||
fgets($this->fileHandle, 3) == "\xFE\xFF" ? | |||||
fseek($this->fileHandle, 2) : fseek($this->fileHandle, 0); | |||||
break; | |||||
case 'UTF-32LE': | |||||
fgets($this->fileHandle, 5) == "\xFF\xFE\x00\x00" ? | |||||
fseek($this->fileHandle, 4) : fseek($this->fileHandle, 0); | |||||
break; | |||||
case 'UTF-32BE': | |||||
fgets($this->fileHandle, 5) == "\x00\x00\xFE\xFF" ? | |||||
fseek($this->fileHandle, 4) : fseek($this->fileHandle, 0); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
} | |||||
/** | |||||
* Identify any separator that is explicitly set in the file | |||||
* | |||||
*/ | |||||
protected function checkSeparator() | |||||
{ | |||||
$line = fgets($this->fileHandle); | |||||
if ($line === false) { | |||||
return; | |||||
} | |||||
if ((strlen(trim($line, "\r\n")) == 5) && (stripos($line, 'sep=') === 0)) { | |||||
$this->delimiter = substr($line, 4, 1); | |||||
return; | |||||
} | |||||
return $this->skipBOM(); | |||||
} | |||||
/** | |||||
* Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) | |||||
* | |||||
* @param string $pFilename | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function listWorksheetInfo($pFilename) | |||||
{ | |||||
// Open file | |||||
$this->openFile($pFilename); | |||||
if (!$this->isValidFormat()) { | |||||
fclose($this->fileHandle); | |||||
throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); | |||||
} | |||||
$fileHandle = $this->fileHandle; | |||||
// Skip BOM, if any | |||||
$this->skipBOM(); | |||||
$this->checkSeparator(); | |||||
$escapeEnclosures = array( "\\" . $this->enclosure, $this->enclosure . $this->enclosure ); | |||||
$worksheetInfo = array(); | |||||
$worksheetInfo[0]['worksheetName'] = 'Worksheet'; | |||||
$worksheetInfo[0]['lastColumnLetter'] = 'A'; | |||||
$worksheetInfo[0]['lastColumnIndex'] = 0; | |||||
$worksheetInfo[0]['totalRows'] = 0; | |||||
$worksheetInfo[0]['totalColumns'] = 0; | |||||
// Loop through each line of the file in turn | |||||
while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure)) !== false) { | |||||
$worksheetInfo[0]['totalRows']++; | |||||
$worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1); | |||||
} | |||||
$worksheetInfo[0]['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']); | |||||
$worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1; | |||||
// Close file | |||||
fclose($fileHandle); | |||||
return $worksheetInfo; | |||||
} | |||||
/** | |||||
* Loads PHPExcel from file | |||||
* | |||||
* @param string $pFilename | |||||
* @return PHPExcel | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function load($pFilename) | |||||
{ | |||||
// Create new PHPExcel | |||||
$objPHPExcel = new PHPExcel(); | |||||
// Load into this instance | |||||
return $this->loadIntoExisting($pFilename, $objPHPExcel); | |||||
} | |||||
/** | |||||
* Loads PHPExcel from file into PHPExcel instance | |||||
* | |||||
* @param string $pFilename | |||||
* @param PHPExcel $objPHPExcel | |||||
* @return PHPExcel | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) | |||||
{ | |||||
$lineEnding = ini_get('auto_detect_line_endings'); | |||||
ini_set('auto_detect_line_endings', true); | |||||
// Open file | |||||
$this->openFile($pFilename); | |||||
if (!$this->isValidFormat()) { | |||||
fclose($this->fileHandle); | |||||
throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); | |||||
} | |||||
$fileHandle = $this->fileHandle; | |||||
// Skip BOM, if any | |||||
$this->skipBOM(); | |||||
$this->checkSeparator(); | |||||
// Create new PHPExcel object | |||||
while ($objPHPExcel->getSheetCount() <= $this->sheetIndex) { | |||||
$objPHPExcel->createSheet(); | |||||
} | |||||
$sheet = $objPHPExcel->setActiveSheetIndex($this->sheetIndex); | |||||
$escapeEnclosures = array( "\\" . $this->enclosure, | |||||
$this->enclosure . $this->enclosure | |||||
); | |||||
// Set our starting row based on whether we're in contiguous mode or not | |||||
$currentRow = 1; | |||||
if ($this->contiguous) { | |||||
$currentRow = ($this->contiguousRow == -1) ? $sheet->getHighestRow(): $this->contiguousRow; | |||||
} | |||||
// Loop through each line of the file in turn | |||||
while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure)) !== false) { | |||||
$columnLetter = 'A'; | |||||
foreach ($rowData as $rowDatum) { | |||||
if ($rowDatum != '' && $this->readFilter->readCell($columnLetter, $currentRow)) { | |||||
// Unescape enclosures | |||||
$rowDatum = str_replace($escapeEnclosures, $this->enclosure, $rowDatum); | |||||
// Convert encoding if necessary | |||||
if ($this->inputEncoding !== 'UTF-8') { | |||||
$rowDatum = PHPExcel_Shared_String::ConvertEncoding($rowDatum, 'UTF-8', $this->inputEncoding); | |||||
} | |||||
// Set cell value | |||||
$sheet->getCell($columnLetter . $currentRow)->setValue($rowDatum); | |||||
} | |||||
++$columnLetter; | |||||
} | |||||
++$currentRow; | |||||
} | |||||
// Close file | |||||
fclose($fileHandle); | |||||
if ($this->contiguous) { | |||||
$this->contiguousRow = $currentRow; | |||||
} | |||||
ini_set('auto_detect_line_endings', $lineEnding); | |||||
// Return | |||||
return $objPHPExcel; | |||||
} | |||||
/** | |||||
* Get delimiter | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getDelimiter() | |||||
{ | |||||
return $this->delimiter; | |||||
} | |||||
/** | |||||
* Set delimiter | |||||
* | |||||
* @param string $pValue Delimiter, defaults to , | |||||
* @return PHPExcel_Reader_CSV | |||||
*/ | |||||
public function setDelimiter($pValue = ',') | |||||
{ | |||||
$this->delimiter = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get enclosure | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getEnclosure() | |||||
{ | |||||
return $this->enclosure; | |||||
} | |||||
/** | |||||
* Set enclosure | |||||
* | |||||
* @param string $pValue Enclosure, defaults to " | |||||
* @return PHPExcel_Reader_CSV | |||||
*/ | |||||
public function setEnclosure($pValue = '"') | |||||
{ | |||||
if ($pValue == '') { | |||||
$pValue = '"'; | |||||
} | |||||
$this->enclosure = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get sheet index | |||||
* | |||||
* @return integer | |||||
*/ | |||||
public function getSheetIndex() | |||||
{ | |||||
return $this->sheetIndex; | |||||
} | |||||
/** | |||||
* Set sheet index | |||||
* | |||||
* @param integer $pValue Sheet index | |||||
* @return PHPExcel_Reader_CSV | |||||
*/ | |||||
public function setSheetIndex($pValue = 0) | |||||
{ | |||||
$this->sheetIndex = $pValue; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set Contiguous | |||||
* | |||||
* @param boolean $contiguous | |||||
*/ | |||||
public function setContiguous($contiguous = false) | |||||
{ | |||||
$this->contiguous = (bool) $contiguous; | |||||
if (!$contiguous) { | |||||
$this->contiguousRow = -1; | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Get Contiguous | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
public function getContiguous() | |||||
{ | |||||
return $this->contiguous; | |||||
} | |||||
} |
@ -0,0 +1,51 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_Reader_DefaultReadFilter | |||||
* | |||||
* 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_Reader | |||||
* @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_Reader_DefaultReadFilter implements PHPExcel_Reader_IReadFilter | |||||
{ | |||||
/** | |||||
* Should this cell be read? | |||||
* | |||||
* @param $column Column address (as a string value like "A", or "IV") | |||||
* @param $row Row number | |||||
* @param $worksheetName Optional worksheet name | |||||
* @return boolean | |||||
*/ | |||||
public function readCell($column, $row, $worksheetName = '') | |||||
{ | |||||
return true; | |||||
} | |||||
} |
@ -0,0 +1,801 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_Reader_Excel2003XML | |||||
* | |||||
* 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_Reader | |||||
* @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_Reader_Excel2003XML extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader | |||||
{ | |||||
/** | |||||
* Formats | |||||
* | |||||
* @var array | |||||
*/ | |||||
protected $styles = array(); | |||||
/** | |||||
* Character set used in the file | |||||
* | |||||
* @var string | |||||
*/ | |||||
protected $charSet = 'UTF-8'; | |||||
/** | |||||
* Create a new PHPExcel_Reader_Excel2003XML | |||||
*/ | |||||
public function __construct() | |||||
{ | |||||
$this->readFilter = new PHPExcel_Reader_DefaultReadFilter(); | |||||
} | |||||
/** | |||||
* Can the current PHPExcel_Reader_IReader read the file? | |||||
* | |||||
* @param string $pFilename | |||||
* @return boolean | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function canRead($pFilename) | |||||
{ | |||||
// Office xmlns:o="urn:schemas-microsoft-com:office:office" | |||||
// Excel xmlns:x="urn:schemas-microsoft-com:office:excel" | |||||
// XML Spreadsheet xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" | |||||
// Spreadsheet component xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" | |||||
// XML schema xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" | |||||
// XML data type xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" | |||||
// MS-persist recordset xmlns:rs="urn:schemas-microsoft-com:rowset" | |||||
// Rowset xmlns:z="#RowsetSchema" | |||||
// | |||||
$signature = array( | |||||
'<?xml version="1.0"', | |||||
'<?mso-application progid="Excel.Sheet"?>' | |||||
); | |||||
// Open file | |||||
$this->openFile($pFilename); | |||||
$fileHandle = $this->fileHandle; | |||||
// Read sample data (first 2 KB will do) | |||||
$data = fread($fileHandle, 2048); | |||||
fclose($fileHandle); | |||||
$valid = true; | |||||
foreach ($signature as $match) { | |||||
// every part of the signature must be present | |||||
if (strpos($data, $match) === false) { | |||||
$valid = false; | |||||
break; | |||||
} | |||||
} | |||||
// Retrieve charset encoding | |||||
if (preg_match('/<?xml.*encoding=[\'"](.*?)[\'"].*?>/um', $data, $matches)) { | |||||
$this->charSet = strtoupper($matches[1]); | |||||
} | |||||
// echo 'Character Set is ', $this->charSet,'<br />'; | |||||
return $valid; | |||||
} | |||||
/** | |||||
* Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object | |||||
* | |||||
* @param string $pFilename | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function listWorksheetNames($pFilename) | |||||
{ | |||||
// Check if file exists | |||||
if (!file_exists($pFilename)) { | |||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); | |||||
} | |||||
if (!$this->canRead($pFilename)) { | |||||
throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); | |||||
} | |||||
$worksheetNames = array(); | |||||
$xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); | |||||
$namespaces = $xml->getNamespaces(true); | |||||
$xml_ss = $xml->children($namespaces['ss']); | |||||
foreach ($xml_ss->Worksheet as $worksheet) { | |||||
$worksheet_ss = $worksheet->attributes($namespaces['ss']); | |||||
$worksheetNames[] = self::convertStringEncoding((string) $worksheet_ss['Name'], $this->charSet); | |||||
} | |||||
return $worksheetNames; | |||||
} | |||||
/** | |||||
* Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) | |||||
* | |||||
* @param string $pFilename | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function listWorksheetInfo($pFilename) | |||||
{ | |||||
// Check if file exists | |||||
if (!file_exists($pFilename)) { | |||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); | |||||
} | |||||
$worksheetInfo = array(); | |||||
$xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); | |||||
$namespaces = $xml->getNamespaces(true); | |||||
$worksheetID = 1; | |||||
$xml_ss = $xml->children($namespaces['ss']); | |||||
foreach ($xml_ss->Worksheet as $worksheet) { | |||||
$worksheet_ss = $worksheet->attributes($namespaces['ss']); | |||||
$tmpInfo = array(); | |||||
$tmpInfo['worksheetName'] = ''; | |||||
$tmpInfo['lastColumnLetter'] = 'A'; | |||||
$tmpInfo['lastColumnIndex'] = 0; | |||||
$tmpInfo['totalRows'] = 0; | |||||
$tmpInfo['totalColumns'] = 0; | |||||
if (isset($worksheet_ss['Name'])) { | |||||
$tmpInfo['worksheetName'] = (string) $worksheet_ss['Name']; | |||||
} else { | |||||
$tmpInfo['worksheetName'] = "Worksheet_[$worksheetID]"; | |||||
} | |||||
if (isset($worksheet->Table->Row)) { | |||||
$rowIndex = 0; | |||||
foreach ($worksheet->Table->Row as $rowData) { | |||||
$columnIndex = 0; | |||||
$rowHasData = false; | |||||
foreach ($rowData->Cell as $cell) { | |||||
if (isset($cell->Data)) { | |||||
$tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); | |||||
$rowHasData = true; | |||||
} | |||||
++$columnIndex; | |||||
} | |||||
++$rowIndex; | |||||
if ($rowHasData) { | |||||
$tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); | |||||
} | |||||
} | |||||
} | |||||
$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); | |||||
$tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; | |||||
$worksheetInfo[] = $tmpInfo; | |||||
++$worksheetID; | |||||
} | |||||
return $worksheetInfo; | |||||
} | |||||
/** | |||||
* Loads PHPExcel from file | |||||
* | |||||
* @param string $pFilename | |||||
* @return PHPExcel | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function load($pFilename) | |||||
{ | |||||
// Create new PHPExcel | |||||
$objPHPExcel = new PHPExcel(); | |||||
$objPHPExcel->removeSheetByIndex(0); | |||||
// Load into this instance | |||||
return $this->loadIntoExisting($pFilename, $objPHPExcel); | |||||
} | |||||
protected static function identifyFixedStyleValue($styleList, &$styleAttributeValue) | |||||
{ | |||||
$styleAttributeValue = strtolower($styleAttributeValue); | |||||
foreach ($styleList as $style) { | |||||
if ($styleAttributeValue == strtolower($style)) { | |||||
$styleAttributeValue = $style; | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* pixel units to excel width units(units of 1/256th of a character width) | |||||
* @param pxs | |||||
* @return | |||||
*/ | |||||
protected static function pixel2WidthUnits($pxs) | |||||
{ | |||||
$UNIT_OFFSET_MAP = array(0, 36, 73, 109, 146, 182, 219); | |||||
$widthUnits = 256 * ($pxs / 7); | |||||
$widthUnits += $UNIT_OFFSET_MAP[($pxs % 7)]; | |||||
return $widthUnits; | |||||
} | |||||
/** | |||||
* excel width units(units of 1/256th of a character width) to pixel units | |||||
* @param widthUnits | |||||
* @return | |||||
*/ | |||||
protected static function widthUnits2Pixel($widthUnits) | |||||
{ | |||||
$pixels = ($widthUnits / 256) * 7; | |||||
$offsetWidthUnits = $widthUnits % 256; | |||||
$pixels += round($offsetWidthUnits / (256 / 7)); | |||||
return $pixels; | |||||
} | |||||
protected static function hex2str($hex) | |||||
{ | |||||
return chr(hexdec($hex[1])); | |||||
} | |||||
/** | |||||
* Loads PHPExcel from file into PHPExcel instance | |||||
* | |||||
* @param string $pFilename | |||||
* @param PHPExcel $objPHPExcel | |||||
* @return PHPExcel | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) | |||||
{ | |||||
$fromFormats = array('\-', '\ '); | |||||
$toFormats = array('-', ' '); | |||||
$underlineStyles = array ( | |||||
PHPExcel_Style_Font::UNDERLINE_NONE, | |||||
PHPExcel_Style_Font::UNDERLINE_DOUBLE, | |||||
PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING, | |||||
PHPExcel_Style_Font::UNDERLINE_SINGLE, | |||||
PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING | |||||
); | |||||
$verticalAlignmentStyles = array ( | |||||
PHPExcel_Style_Alignment::VERTICAL_BOTTOM, | |||||
PHPExcel_Style_Alignment::VERTICAL_TOP, | |||||
PHPExcel_Style_Alignment::VERTICAL_CENTER, | |||||
PHPExcel_Style_Alignment::VERTICAL_JUSTIFY | |||||
); | |||||
$horizontalAlignmentStyles = array ( | |||||
PHPExcel_Style_Alignment::HORIZONTAL_GENERAL, | |||||
PHPExcel_Style_Alignment::HORIZONTAL_LEFT, | |||||
PHPExcel_Style_Alignment::HORIZONTAL_RIGHT, | |||||
PHPExcel_Style_Alignment::HORIZONTAL_CENTER, | |||||
PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS, | |||||
PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY | |||||
); | |||||
$timezoneObj = new DateTimeZone('Europe/London'); | |||||
$GMT = new DateTimeZone('UTC'); | |||||
// Check if file exists | |||||
if (!file_exists($pFilename)) { | |||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); | |||||
} | |||||
if (!$this->canRead($pFilename)) { | |||||
throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); | |||||
} | |||||
$xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); | |||||
$namespaces = $xml->getNamespaces(true); | |||||
$docProps = $objPHPExcel->getProperties(); | |||||
if (isset($xml->DocumentProperties[0])) { | |||||
foreach ($xml->DocumentProperties[0] as $propertyName => $propertyValue) { | |||||
switch ($propertyName) { | |||||
case 'Title': | |||||
$docProps->setTitle(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'Subject': | |||||
$docProps->setSubject(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'Author': | |||||
$docProps->setCreator(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'Created': | |||||
$creationDate = strtotime($propertyValue); | |||||
$docProps->setCreated($creationDate); | |||||
break; | |||||
case 'LastAuthor': | |||||
$docProps->setLastModifiedBy(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'LastSaved': | |||||
$lastSaveDate = strtotime($propertyValue); | |||||
$docProps->setModified($lastSaveDate); | |||||
break; | |||||
case 'Company': | |||||
$docProps->setCompany(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'Category': | |||||
$docProps->setCategory(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'Manager': | |||||
$docProps->setManager(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'Keywords': | |||||
$docProps->setKeywords(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'Description': | |||||
$docProps->setDescription(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
if (isset($xml->CustomDocumentProperties)) { | |||||
foreach ($xml->CustomDocumentProperties[0] as $propertyName => $propertyValue) { | |||||
$propertyAttributes = $propertyValue->attributes($namespaces['dt']); | |||||
$propertyName = preg_replace_callback('/_x([0-9a-z]{4})_/', 'PHPExcel_Reader_Excel2003XML::hex2str', $propertyName); | |||||
$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_UNKNOWN; | |||||
switch ((string) $propertyAttributes) { | |||||
case 'string': | |||||
$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; | |||||
$propertyValue = trim($propertyValue); | |||||
break; | |||||
case 'boolean': | |||||
$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN; | |||||
$propertyValue = (bool) $propertyValue; | |||||
break; | |||||
case 'integer': | |||||
$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_INTEGER; | |||||
$propertyValue = intval($propertyValue); | |||||
break; | |||||
case 'float': | |||||
$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT; | |||||
$propertyValue = floatval($propertyValue); | |||||
break; | |||||
case 'dateTime.tz': | |||||
$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE; | |||||
$propertyValue = strtotime(trim($propertyValue)); | |||||
break; | |||||
} | |||||
$docProps->setCustomProperty($propertyName, $propertyValue, $propertyType); | |||||
} | |||||
} | |||||
foreach ($xml->Styles[0] as $style) { | |||||
$style_ss = $style->attributes($namespaces['ss']); | |||||
$styleID = (string) $style_ss['ID']; | |||||
// echo 'Style ID = '.$styleID.'<br />'; | |||||
$this->styles[$styleID] = (isset($this->styles['Default'])) ? $this->styles['Default'] : array(); | |||||
foreach ($style as $styleType => $styleData) { | |||||
$styleAttributes = $styleData->attributes($namespaces['ss']); | |||||
// echo $styleType.'<br />'; | |||||
switch ($styleType) { | |||||
case 'Alignment': | |||||
foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { | |||||
// echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; | |||||
$styleAttributeValue = (string) $styleAttributeValue; | |||||
switch ($styleAttributeKey) { | |||||
case 'Vertical': | |||||
if (self::identifyFixedStyleValue($verticalAlignmentStyles, $styleAttributeValue)) { | |||||
$this->styles[$styleID]['alignment']['vertical'] = $styleAttributeValue; | |||||
} | |||||
break; | |||||
case 'Horizontal': | |||||
if (self::identifyFixedStyleValue($horizontalAlignmentStyles, $styleAttributeValue)) { | |||||
$this->styles[$styleID]['alignment']['horizontal'] = $styleAttributeValue; | |||||
} | |||||
break; | |||||
case 'WrapText': | |||||
$this->styles[$styleID]['alignment']['wrap'] = true; | |||||
break; | |||||
} | |||||
} | |||||
break; | |||||
case 'Borders': | |||||
foreach ($styleData->Border as $borderStyle) { | |||||
$borderAttributes = $borderStyle->attributes($namespaces['ss']); | |||||
$thisBorder = array(); | |||||
foreach ($borderAttributes as $borderStyleKey => $borderStyleValue) { | |||||
// echo $borderStyleKey.' = '.$borderStyleValue.'<br />'; | |||||
switch ($borderStyleKey) { | |||||
case 'LineStyle': | |||||
$thisBorder['style'] = PHPExcel_Style_Border::BORDER_MEDIUM; | |||||
// $thisBorder['style'] = $borderStyleValue; | |||||
break; | |||||
case 'Weight': | |||||
// $thisBorder['style'] = $borderStyleValue; | |||||
break; | |||||
case 'Position': | |||||
$borderPosition = strtolower($borderStyleValue); | |||||
break; | |||||
case 'Color': | |||||
$borderColour = substr($borderStyleValue, 1); | |||||
$thisBorder['color']['rgb'] = $borderColour; | |||||
break; | |||||
} | |||||
} | |||||
if (!empty($thisBorder)) { | |||||
if (($borderPosition == 'left') || ($borderPosition == 'right') || ($borderPosition == 'top') || ($borderPosition == 'bottom')) { | |||||
$this->styles[$styleID]['borders'][$borderPosition] = $thisBorder; | |||||
} | |||||
} | |||||
} | |||||
break; | |||||
case 'Font': | |||||
foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { | |||||
// echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; | |||||
$styleAttributeValue = (string) $styleAttributeValue; | |||||
switch ($styleAttributeKey) { | |||||
case 'FontName': | |||||
$this->styles[$styleID]['font']['name'] = $styleAttributeValue; | |||||
break; | |||||
case 'Size': | |||||
$this->styles[$styleID]['font']['size'] = $styleAttributeValue; | |||||
break; | |||||
case 'Color': | |||||
$this->styles[$styleID]['font']['color']['rgb'] = substr($styleAttributeValue, 1); | |||||
break; | |||||
case 'Bold': | |||||
$this->styles[$styleID]['font']['bold'] = true; | |||||
break; | |||||
case 'Italic': | |||||
$this->styles[$styleID]['font']['italic'] = true; | |||||
break; | |||||
case 'Underline': | |||||
if (self::identifyFixedStyleValue($underlineStyles, $styleAttributeValue)) { | |||||
$this->styles[$styleID]['font']['underline'] = $styleAttributeValue; | |||||
} | |||||
break; | |||||
} | |||||
} | |||||
break; | |||||
case 'Interior': | |||||
foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { | |||||
// echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; | |||||
switch ($styleAttributeKey) { | |||||
case 'Color': | |||||
$this->styles[$styleID]['fill']['color']['rgb'] = substr($styleAttributeValue, 1); | |||||
break; | |||||
} | |||||
} | |||||
break; | |||||
case 'NumberFormat': | |||||
foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { | |||||
// echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; | |||||
$styleAttributeValue = str_replace($fromFormats, $toFormats, $styleAttributeValue); | |||||
switch ($styleAttributeValue) { | |||||
case 'Short Date': | |||||
$styleAttributeValue = 'dd/mm/yyyy'; | |||||
break; | |||||
} | |||||
if ($styleAttributeValue > '') { | |||||
$this->styles[$styleID]['numberformat']['code'] = $styleAttributeValue; | |||||
} | |||||
} | |||||
break; | |||||
case 'Protection': | |||||
foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { | |||||
// echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; | |||||
} | |||||
break; | |||||
} | |||||
} | |||||
// print_r($this->styles[$styleID]); | |||||
// echo '<hr />'; | |||||
} | |||||
// echo '<hr />'; | |||||
$worksheetID = 0; | |||||
$xml_ss = $xml->children($namespaces['ss']); | |||||
foreach ($xml_ss->Worksheet as $worksheet) { | |||||
$worksheet_ss = $worksheet->attributes($namespaces['ss']); | |||||
if ((isset($this->loadSheetsOnly)) && (isset($worksheet_ss['Name'])) && | |||||
(!in_array($worksheet_ss['Name'], $this->loadSheetsOnly))) { | |||||
continue; | |||||
} | |||||
// echo '<h3>Worksheet: ', $worksheet_ss['Name'],'<h3>'; | |||||
// | |||||
// Create new Worksheet | |||||
$objPHPExcel->createSheet(); | |||||
$objPHPExcel->setActiveSheetIndex($worksheetID); | |||||
if (isset($worksheet_ss['Name'])) { | |||||
$worksheetName = self::convertStringEncoding((string) $worksheet_ss['Name'], $this->charSet); | |||||
// Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in | |||||
// formula cells... during the load, all formulae should be correct, and we're simply bringing | |||||
// the worksheet name in line with the formula, not the reverse | |||||
$objPHPExcel->getActiveSheet()->setTitle($worksheetName, false); | |||||
} | |||||
$columnID = 'A'; | |||||
if (isset($worksheet->Table->Column)) { | |||||
foreach ($worksheet->Table->Column as $columnData) { | |||||
$columnData_ss = $columnData->attributes($namespaces['ss']); | |||||
if (isset($columnData_ss['Index'])) { | |||||
$columnID = PHPExcel_Cell::stringFromColumnIndex($columnData_ss['Index']-1); | |||||
} | |||||
if (isset($columnData_ss['Width'])) { | |||||
$columnWidth = $columnData_ss['Width']; | |||||
// echo '<b>Setting column width for '.$columnID.' to '.$columnWidth.'</b><br />'; | |||||
$objPHPExcel->getActiveSheet()->getColumnDimension($columnID)->setWidth($columnWidth / 5.4); | |||||
} | |||||
++$columnID; | |||||
} | |||||
} | |||||
$rowID = 1; | |||||
if (isset($worksheet->Table->Row)) { | |||||
$additionalMergedCells = 0; | |||||
foreach ($worksheet->Table->Row as $rowData) { | |||||
$rowHasData = false; | |||||
$row_ss = $rowData->attributes($namespaces['ss']); | |||||
if (isset($row_ss['Index'])) { | |||||
$rowID = (integer) $row_ss['Index']; | |||||
} | |||||
// echo '<b>Row '.$rowID.'</b><br />'; | |||||
$columnID = 'A'; | |||||
foreach ($rowData->Cell as $cell) { | |||||
$cell_ss = $cell->attributes($namespaces['ss']); | |||||
if (isset($cell_ss['Index'])) { | |||||
$columnID = PHPExcel_Cell::stringFromColumnIndex($cell_ss['Index']-1); | |||||
} | |||||
$cellRange = $columnID.$rowID; | |||||
if ($this->getReadFilter() !== null) { | |||||
if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { | |||||
continue; | |||||
} | |||||
} | |||||
if ((isset($cell_ss['MergeAcross'])) || (isset($cell_ss['MergeDown']))) { | |||||
$columnTo = $columnID; | |||||
if (isset($cell_ss['MergeAcross'])) { | |||||
$additionalMergedCells += (int)$cell_ss['MergeAcross']; | |||||
$columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cell_ss['MergeAcross'] -1); | |||||
} | |||||
$rowTo = $rowID; | |||||
if (isset($cell_ss['MergeDown'])) { | |||||
$rowTo = $rowTo + $cell_ss['MergeDown']; | |||||
} | |||||
$cellRange .= ':'.$columnTo.$rowTo; | |||||
$objPHPExcel->getActiveSheet()->mergeCells($cellRange); | |||||
} | |||||
$cellIsSet = $hasCalculatedValue = false; | |||||
$cellDataFormula = ''; | |||||
if (isset($cell_ss['Formula'])) { | |||||
$cellDataFormula = $cell_ss['Formula']; | |||||
// added this as a check for array formulas | |||||
if (isset($cell_ss['ArrayRange'])) { | |||||
$cellDataCSEFormula = $cell_ss['ArrayRange']; | |||||
// echo "found an array formula at ".$columnID.$rowID."<br />"; | |||||
} | |||||
$hasCalculatedValue = true; | |||||
} | |||||
if (isset($cell->Data)) { | |||||
$cellValue = $cellData = $cell->Data; | |||||
$type = PHPExcel_Cell_DataType::TYPE_NULL; | |||||
$cellData_ss = $cellData->attributes($namespaces['ss']); | |||||
if (isset($cellData_ss['Type'])) { | |||||
$cellDataType = $cellData_ss['Type']; | |||||
switch ($cellDataType) { | |||||
/* | |||||
const TYPE_STRING = 's'; | |||||
const TYPE_FORMULA = 'f'; | |||||
const TYPE_NUMERIC = 'n'; | |||||
const TYPE_BOOL = 'b'; | |||||
const TYPE_NULL = 'null'; | |||||
const TYPE_INLINE = 'inlineStr'; | |||||
const TYPE_ERROR = 'e'; | |||||
*/ | |||||
case 'String': | |||||
$cellValue = self::convertStringEncoding($cellValue, $this->charSet); | |||||
$type = PHPExcel_Cell_DataType::TYPE_STRING; | |||||
break; | |||||
case 'Number': | |||||
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC; | |||||
$cellValue = (float) $cellValue; | |||||
if (floor($cellValue) == $cellValue) { | |||||
$cellValue = (integer) $cellValue; | |||||
} | |||||
break; | |||||
case 'Boolean': | |||||
$type = PHPExcel_Cell_DataType::TYPE_BOOL; | |||||
$cellValue = ($cellValue != 0); | |||||
break; | |||||
case 'DateTime': | |||||
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC; | |||||
$cellValue = PHPExcel_Shared_Date::PHPToExcel(strtotime($cellValue)); | |||||
break; | |||||
case 'Error': | |||||
$type = PHPExcel_Cell_DataType::TYPE_ERROR; | |||||
break; | |||||
} | |||||
} | |||||
if ($hasCalculatedValue) { | |||||
// echo 'FORMULA<br />'; | |||||
$type = PHPExcel_Cell_DataType::TYPE_FORMULA; | |||||
$columnNumber = PHPExcel_Cell::columnIndexFromString($columnID); | |||||
if (substr($cellDataFormula, 0, 3) == 'of:') { | |||||
$cellDataFormula = substr($cellDataFormula, 3); | |||||
// echo 'Before: ', $cellDataFormula,'<br />'; | |||||
$temp = explode('"', $cellDataFormula); | |||||
$key = false; | |||||
foreach ($temp as &$value) { | |||||
// Only replace in alternate array entries (i.e. non-quoted blocks) | |||||
if ($key = !$key) { | |||||
$value = str_replace(array('[.', '.', ']'), '', $value); | |||||
} | |||||
} | |||||
} else { | |||||
// Convert R1C1 style references to A1 style references (but only when not quoted) | |||||
// echo 'Before: ', $cellDataFormula,'<br />'; | |||||
$temp = explode('"', $cellDataFormula); | |||||
$key = false; | |||||
foreach ($temp as &$value) { | |||||
// Only replace in alternate array entries (i.e. non-quoted blocks) | |||||
if ($key = !$key) { | |||||
preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/', $value, $cellReferences, PREG_SET_ORDER + PREG_OFFSET_CAPTURE); | |||||
// Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way | |||||
// through the formula from left to right. Reversing means that we work right to left.through | |||||
// the formula | |||||
$cellReferences = array_reverse($cellReferences); | |||||
// Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent, | |||||
// then modify the formula to use that new reference | |||||
foreach ($cellReferences as $cellReference) { | |||||
$rowReference = $cellReference[2][0]; | |||||
// Empty R reference is the current row | |||||
if ($rowReference == '') { | |||||
$rowReference = $rowID; | |||||
} | |||||
// Bracketed R references are relative to the current row | |||||
if ($rowReference[0] == '[') { | |||||
$rowReference = $rowID + trim($rowReference, '[]'); | |||||
} | |||||
$columnReference = $cellReference[4][0]; | |||||
// Empty C reference is the current column | |||||
if ($columnReference == '') { | |||||
$columnReference = $columnNumber; | |||||
} | |||||
// Bracketed C references are relative to the current column | |||||
if ($columnReference[0] == '[') { | |||||
$columnReference = $columnNumber + trim($columnReference, '[]'); | |||||
} | |||||
$A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; | |||||
$value = substr_replace($value, $A1CellReference, $cellReference[0][1], strlen($cellReference[0][0])); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
unset($value); | |||||
// Then rebuild the formula string | |||||
$cellDataFormula = implode('"', $temp); | |||||
// echo 'After: ', $cellDataFormula,'<br />'; | |||||
} | |||||
// echo 'Cell '.$columnID.$rowID.' is a '.$type.' with a value of '.(($hasCalculatedValue) ? $cellDataFormula : $cellValue).'<br />'; | |||||
// | |||||
$objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $cellValue), $type); | |||||
if ($hasCalculatedValue) { | |||||
// echo 'Formula result is '.$cellValue.'<br />'; | |||||
$objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setCalculatedValue($cellValue); | |||||
} | |||||
$cellIsSet = $rowHasData = true; | |||||
} | |||||
if (isset($cell->Comment)) { | |||||
// echo '<b>comment found</b><br />'; | |||||
$commentAttributes = $cell->Comment->attributes($namespaces['ss']); | |||||
$author = 'unknown'; | |||||
if (isset($commentAttributes->Author)) { | |||||
$author = (string)$commentAttributes->Author; | |||||
// echo 'Author: ', $author,'<br />'; | |||||
} | |||||
$node = $cell->Comment->Data->asXML(); | |||||
// $annotation = str_replace('html:','',substr($node,49,-10)); | |||||
// echo $annotation,'<br />'; | |||||
$annotation = strip_tags($node); | |||||
// echo 'Annotation: ', $annotation,'<br />'; | |||||
$objPHPExcel->getActiveSheet()->getComment($columnID.$rowID)->setAuthor(self::convertStringEncoding($author, $this->charSet))->setText($this->parseRichText($annotation)); | |||||
} | |||||
if (($cellIsSet) && (isset($cell_ss['StyleID']))) { | |||||
$style = (string) $cell_ss['StyleID']; | |||||
// echo 'Cell style for '.$columnID.$rowID.' is '.$style.'<br />'; | |||||
if ((isset($this->styles[$style])) && (!empty($this->styles[$style]))) { | |||||
// echo 'Cell '.$columnID.$rowID.'<br />'; | |||||
// print_r($this->styles[$style]); | |||||
// echo '<br />'; | |||||
if (!$objPHPExcel->getActiveSheet()->cellExists($columnID.$rowID)) { | |||||
$objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValue(null); | |||||
} | |||||
$objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($this->styles[$style]); | |||||
} | |||||
} | |||||
++$columnID; | |||||
while ($additionalMergedCells > 0) { | |||||
++$columnID; | |||||
$additionalMergedCells--; | |||||
} | |||||
} | |||||
if ($rowHasData) { | |||||
if (isset($row_ss['StyleID'])) { | |||||
$rowStyle = $row_ss['StyleID']; | |||||
} | |||||
if (isset($row_ss['Height'])) { | |||||
$rowHeight = $row_ss['Height']; | |||||
// echo '<b>Setting row height to '.$rowHeight.'</b><br />'; | |||||
$objPHPExcel->getActiveSheet()->getRowDimension($rowID)->setRowHeight($rowHeight); | |||||
} | |||||
} | |||||
++$rowID; | |||||
} | |||||
} | |||||
++$worksheetID; | |||||
} | |||||
// Return | |||||
return $objPHPExcel; | |||||
} | |||||
protected static function convertStringEncoding($string, $charset) | |||||
{ | |||||
if ($charset != 'UTF-8') { | |||||
return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', $charset); | |||||
} | |||||
return $string; | |||||
} | |||||
protected function parseRichText($is = '') | |||||
{ | |||||
$value = new PHPExcel_RichText(); | |||||
$value->createText(self::convertStringEncoding($is, $this->charSet)); | |||||
return $value; | |||||
} | |||||
} |
@ -0,0 +1,801 @@ | |||||
<?php | |||||
/** PHPExcel root directory */ | |||||
if (!defined('PHPEXCEL_ROOT')) { | |||||
/** | |||||
* @ignore | |||||
*/ | |||||
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); | |||||
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | |||||
} | |||||
/** | |||||
* PHPExcel_Reader_Excel2003XML | |||||
* | |||||
* 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_Reader | |||||
* @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_Reader_Excel2003XML extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader | |||||
{ | |||||
/** | |||||
* Formats | |||||
* | |||||
* @var array | |||||
*/ | |||||
protected $styles = array(); | |||||
/** | |||||
* Character set used in the file | |||||
* | |||||
* @var string | |||||
*/ | |||||
protected $charSet = 'UTF-8'; | |||||
/** | |||||
* Create a new PHPExcel_Reader_Excel2003XML | |||||
*/ | |||||
public function __construct() | |||||
{ | |||||
$this->readFilter = new PHPExcel_Reader_DefaultReadFilter(); | |||||
} | |||||
/** | |||||
* Can the current PHPExcel_Reader_IReader read the file? | |||||
* | |||||
* @param string $pFilename | |||||
* @return boolean | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function canRead($pFilename) | |||||
{ | |||||
// Office xmlns:o="urn:schemas-microsoft-com:office:office" | |||||
// Excel xmlns:x="urn:schemas-microsoft-com:office:excel" | |||||
// XML Spreadsheet xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" | |||||
// Spreadsheet component xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" | |||||
// XML schema xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" | |||||
// XML data type xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" | |||||
// MS-persist recordset xmlns:rs="urn:schemas-microsoft-com:rowset" | |||||
// Rowset xmlns:z="#RowsetSchema" | |||||
// | |||||
$signature = array( | |||||
'<?xml version="1.0"', | |||||
'<?mso-application progid="Excel.Sheet"?>' | |||||
); | |||||
// Open file | |||||
$this->openFile($pFilename); | |||||
$fileHandle = $this->fileHandle; | |||||
// Read sample data (first 2 KB will do) | |||||
$data = fread($fileHandle, 2048); | |||||
fclose($fileHandle); | |||||
$valid = true; | |||||
foreach ($signature as $match) { | |||||
// every part of the signature must be present | |||||
if (strpos($data, $match) === false) { | |||||
$valid = false; | |||||
break; | |||||
} | |||||
} | |||||
// Retrieve charset encoding | |||||
if (preg_match('/<?xml.*encoding=[\'"](.*?)[\'"].*?>/um', $data, $matches)) { | |||||
$this->charSet = strtoupper($matches[1]); | |||||
} | |||||
// echo 'Character Set is ', $this->charSet,'<br />'; | |||||
return $valid; | |||||
} | |||||
/** | |||||
* Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object | |||||
* | |||||
* @param string $pFilename | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function listWorksheetNames($pFilename) | |||||
{ | |||||
// Check if file exists | |||||
if (!file_exists($pFilename)) { | |||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); | |||||
} | |||||
if (!$this->canRead($pFilename)) { | |||||
throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); | |||||
} | |||||
$worksheetNames = array(); | |||||
$xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); | |||||
$namespaces = $xml->getNamespaces(true); | |||||
$xml_ss = $xml->children($namespaces['ss']); | |||||
foreach ($xml_ss->Worksheet as $worksheet) { | |||||
$worksheet_ss = $worksheet->attributes($namespaces['ss']); | |||||
$worksheetNames[] = self::convertStringEncoding((string) $worksheet_ss['Name'], $this->charSet); | |||||
} | |||||
return $worksheetNames; | |||||
} | |||||
/** | |||||
* Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) | |||||
* | |||||
* @param string $pFilename | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function listWorksheetInfo($pFilename) | |||||
{ | |||||
// Check if file exists | |||||
if (!file_exists($pFilename)) { | |||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); | |||||
} | |||||
$worksheetInfo = array(); | |||||
$xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); | |||||
$namespaces = $xml->getNamespaces(true); | |||||
$worksheetID = 1; | |||||
$xml_ss = $xml->children($namespaces['ss']); | |||||
foreach ($xml_ss->Worksheet as $worksheet) { | |||||
$worksheet_ss = $worksheet->attributes($namespaces['ss']); | |||||
$tmpInfo = array(); | |||||
$tmpInfo['worksheetName'] = ''; | |||||
$tmpInfo['lastColumnLetter'] = 'A'; | |||||
$tmpInfo['lastColumnIndex'] = 0; | |||||
$tmpInfo['totalRows'] = 0; | |||||
$tmpInfo['totalColumns'] = 0; | |||||
if (isset($worksheet_ss['Name'])) { | |||||
$tmpInfo['worksheetName'] = (string) $worksheet_ss['Name']; | |||||
} else { | |||||
$tmpInfo['worksheetName'] = "Worksheet_{$worksheetID}"; | |||||
} | |||||
if (isset($worksheet->Table->Row)) { | |||||
$rowIndex = 0; | |||||
foreach ($worksheet->Table->Row as $rowData) { | |||||
$columnIndex = 0; | |||||
$rowHasData = false; | |||||
foreach ($rowData->Cell as $cell) { | |||||
if (isset($cell->Data)) { | |||||
$tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); | |||||
$rowHasData = true; | |||||
} | |||||
++$columnIndex; | |||||
} | |||||
++$rowIndex; | |||||
if ($rowHasData) { | |||||
$tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); | |||||
} | |||||
} | |||||
} | |||||
$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); | |||||
$tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; | |||||
$worksheetInfo[] = $tmpInfo; | |||||
++$worksheetID; | |||||
} | |||||
return $worksheetInfo; | |||||
} | |||||
/** | |||||
* Loads PHPExcel from file | |||||
* | |||||
* @param string $pFilename | |||||
* @return PHPExcel | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function load($pFilename) | |||||
{ | |||||
// Create new PHPExcel | |||||
$objPHPExcel = new PHPExcel(); | |||||
$objPHPExcel->removeSheetByIndex(0); | |||||
// Load into this instance | |||||
return $this->loadIntoExisting($pFilename, $objPHPExcel); | |||||
} | |||||
protected static function identifyFixedStyleValue($styleList, &$styleAttributeValue) | |||||
{ | |||||
$styleAttributeValue = strtolower($styleAttributeValue); | |||||
foreach ($styleList as $style) { | |||||
if ($styleAttributeValue == strtolower($style)) { | |||||
$styleAttributeValue = $style; | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* pixel units to excel width units(units of 1/256th of a character width) | |||||
* @param pxs | |||||
* @return | |||||
*/ | |||||
protected static function pixel2WidthUnits($pxs) | |||||
{ | |||||
$UNIT_OFFSET_MAP = array(0, 36, 73, 109, 146, 182, 219); | |||||
$widthUnits = 256 * ($pxs / 7); | |||||
$widthUnits += $UNIT_OFFSET_MAP[($pxs % 7)]; | |||||
return $widthUnits; | |||||
} | |||||
/** | |||||
* excel width units(units of 1/256th of a character width) to pixel units | |||||
* @param widthUnits | |||||
* @return | |||||
*/ | |||||
protected static function widthUnits2Pixel($widthUnits) | |||||
{ | |||||
$pixels = ($widthUnits / 256) * 7; | |||||
$offsetWidthUnits = $widthUnits % 256; | |||||
$pixels += round($offsetWidthUnits / (256 / 7)); | |||||
return $pixels; | |||||
} | |||||
protected static function hex2str($hex) | |||||
{ | |||||
return chr(hexdec($hex[1])); | |||||
} | |||||
/** | |||||
* Loads PHPExcel from file into PHPExcel instance | |||||
* | |||||
* @param string $pFilename | |||||
* @param PHPExcel $objPHPExcel | |||||
* @return PHPExcel | |||||
* @throws PHPExcel_Reader_Exception | |||||
*/ | |||||
public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) | |||||
{ | |||||
$fromFormats = array('\-', '\ '); | |||||
$toFormats = array('-', ' '); | |||||
$underlineStyles = array ( | |||||
PHPExcel_Style_Font::UNDERLINE_NONE, | |||||
PHPExcel_Style_Font::UNDERLINE_DOUBLE, | |||||
PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING, | |||||
PHPExcel_Style_Font::UNDERLINE_SINGLE, | |||||
PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING | |||||
); | |||||
$verticalAlignmentStyles = array ( | |||||
PHPExcel_Style_Alignment::VERTICAL_BOTTOM, | |||||
PHPExcel_Style_Alignment::VERTICAL_TOP, | |||||
PHPExcel_Style_Alignment::VERTICAL_CENTER, | |||||
PHPExcel_Style_Alignment::VERTICAL_JUSTIFY | |||||
); | |||||
$horizontalAlignmentStyles = array ( | |||||
PHPExcel_Style_Alignment::HORIZONTAL_GENERAL, | |||||
PHPExcel_Style_Alignment::HORIZONTAL_LEFT, | |||||
PHPExcel_Style_Alignment::HORIZONTAL_RIGHT, | |||||
PHPExcel_Style_Alignment::HORIZONTAL_CENTER, | |||||
PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS, | |||||
PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY | |||||
); | |||||
$timezoneObj = new DateTimeZone('Europe/London'); | |||||
$GMT = new DateTimeZone('UTC'); | |||||
// Check if file exists | |||||
if (!file_exists($pFilename)) { | |||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); | |||||
} | |||||
if (!$this->canRead($pFilename)) { | |||||
throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); | |||||
} | |||||
$xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); | |||||
$namespaces = $xml->getNamespaces(true); | |||||
$docProps = $objPHPExcel->getProperties(); | |||||
if (isset($xml->DocumentProperties[0])) { | |||||
foreach ($xml->DocumentProperties[0] as $propertyName => $propertyValue) { | |||||
switch ($propertyName) { | |||||
case 'Title': | |||||
$docProps->setTitle(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'Subject': | |||||
$docProps->setSubject(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'Author': | |||||
$docProps->setCreator(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'Created': | |||||
$creationDate = strtotime($propertyValue); | |||||
$docProps->setCreated($creationDate); | |||||
break; | |||||
case 'LastAuthor': | |||||
$docProps->setLastModifiedBy(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'LastSaved': | |||||
$lastSaveDate = strtotime($propertyValue); | |||||
$docProps->setModified($lastSaveDate); | |||||
break; | |||||
case 'Company': | |||||
$docProps->setCompany(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'Category': | |||||
$docProps->setCategory(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'Manager': | |||||
$docProps->setManager(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'Keywords': | |||||
$docProps->setKeywords(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
case 'Description': | |||||
$docProps->setDescription(self::convertStringEncoding($propertyValue, $this->charSet)); | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
if (isset($xml->CustomDocumentProperties)) { | |||||
foreach ($xml->CustomDocumentProperties[0] as $propertyName => $propertyValue) { | |||||
$propertyAttributes = $propertyValue->attributes($namespaces['dt']); | |||||
$propertyName = preg_replace_callback('/_x([0-9a-z]{4})_/', 'PHPExcel_Reader_Excel2003XML::hex2str', $propertyName); | |||||
$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_UNKNOWN; | |||||
switch ((string) $propertyAttributes) { | |||||
case 'string': | |||||
$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; | |||||
$propertyValue = trim($propertyValue); | |||||
break; | |||||
case 'boolean': | |||||
$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN; | |||||
$propertyValue = (bool) $propertyValue; | |||||
break; | |||||
case 'integer': | |||||
$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_INTEGER; | |||||
$propertyValue = intval($propertyValue); | |||||
break; | |||||
case 'float': | |||||
$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT; | |||||
$propertyValue = floatval($propertyValue); | |||||
break; | |||||
case 'dateTime.tz': | |||||
$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE; | |||||
$propertyValue = strtotime(trim($propertyValue)); | |||||
break; | |||||
} | |||||
$docProps->setCustomProperty($propertyName, $propertyValue, $propertyType); | |||||
} | |||||
} | |||||
foreach ($xml->Styles[0] as $style) { | |||||
$style_ss = $style->attributes($namespaces['ss']); | |||||
$styleID = (string) $style_ss['ID']; | |||||
// echo 'Style ID = '.$styleID.'<br />'; | |||||
$this->styles[$styleID] = (isset($this->styles['Default'])) ? $this->styles['Default'] : array(); | |||||
foreach ($style as $styleType => $styleData) { | |||||
$styleAttributes = $styleData->attributes($namespaces['ss']); | |||||
// echo $styleType.'<br />'; | |||||
switch ($styleType) { | |||||
case 'Alignment': | |||||
foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { | |||||
// echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; | |||||
$styleAttributeValue = (string) $styleAttributeValue; | |||||
switch ($styleAttributeKey) { | |||||
case 'Vertical': | |||||
if (self::identifyFixedStyleValue($verticalAlignmentStyles, $styleAttributeValue)) { | |||||
$this->styles[$styleID]['alignment']['vertical'] = $styleAttributeValue; | |||||
} | |||||
break; | |||||
case 'Horizontal': | |||||
if (self::identifyFixedStyleValue($horizontalAlignmentStyles, $styleAttributeValue)) { | |||||
$this->styles[$styleID]['alignment']['horizontal'] = $styleAttributeValue; | |||||
} | |||||
break; | |||||
case 'WrapText': | |||||
$this->styles[$styleID]['alignment']['wrap'] = true; | |||||
break; | |||||
} | |||||
} | |||||
break; | |||||
case 'Borders': | |||||
foreach ($styleData->Border as $borderStyle) { | |||||
$borderAttributes = $borderStyle->attributes($namespaces['ss']); | |||||
$thisBorder = array(); | |||||
foreach ($borderAttributes as $borderStyleKey => $borderStyleValue) { | |||||
// echo $borderStyleKey.' = '.$borderStyleValue.'<br />'; | |||||
switch ($borderStyleKey) { | |||||
case 'LineStyle': | |||||
$thisBorder['style'] = PHPExcel_Style_Border::BORDER_MEDIUM; | |||||
// $thisBorder['style'] = $borderStyleValue; | |||||
break; | |||||
case 'Weight': | |||||
// $thisBorder['style'] = $borderStyleValue; | |||||
break; | |||||
case 'Position': | |||||
$borderPosition = strtolower($borderStyleValue); | |||||
break; | |||||
case 'Color': | |||||
$borderColour = substr($borderStyleValue, 1); | |||||
$thisBorder['color']['rgb'] = $borderColour; | |||||
break; | |||||
} | |||||
} | |||||
if (!empty($thisBorder)) { | |||||
if (($borderPosition == 'left') || ($borderPosition == 'right') || ($borderPosition == 'top') || ($borderPosition == 'bottom')) { | |||||
$this->styles[$styleID]['borders'][$borderPosition] = $thisBorder; | |||||
} | |||||
} | |||||
} | |||||
break; | |||||
case 'Font': | |||||
foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { | |||||
// echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; | |||||
$styleAttributeValue = (string) $styleAttributeValue; | |||||
switch ($styleAttributeKey) { | |||||
case 'FontName': | |||||
$this->styles[$styleID]['font']['name'] = $styleAttributeValue; | |||||
break; | |||||
case 'Size': | |||||
$this->styles[$styleID]['font']['size'] = $styleAttributeValue; | |||||
break; | |||||
case 'Color': | |||||
$this->styles[$styleID]['font']['color']['rgb'] = substr($styleAttributeValue, 1); | |||||
break; | |||||
case 'Bold': | |||||
$this->styles[$styleID]['font']['bold'] = true; | |||||
break; | |||||
case 'Italic': | |||||
$this->styles[$styleID]['font']['italic'] = true; | |||||
break; | |||||
case 'Underline': | |||||
if (self::identifyFixedStyleValue($underlineStyles, $styleAttributeValue)) { | |||||
$this->styles[$styleID]['font']['underline'] = $styleAttributeValue; | |||||
} | |||||
break; | |||||
} | |||||
} | |||||
break; | |||||
case 'Interior': | |||||
foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { | |||||
// echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; | |||||
switch ($styleAttributeKey) { | |||||
case 'Color': | |||||
$this->styles[$styleID]['fill']['color']['rgb'] = substr($styleAttributeValue, 1); | |||||
break; | |||||
} | |||||
} | |||||
break; | |||||
case 'NumberFormat': | |||||
foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { | |||||
// echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; | |||||
$styleAttributeValue = str_replace($fromFormats, $toFormats, $styleAttributeValue); | |||||
switch ($styleAttributeValue) { | |||||
case 'Short Date': | |||||
$styleAttributeValue = 'dd/mm/yyyy'; | |||||
break; | |||||
} | |||||
if ($styleAttributeValue > '') { | |||||
$this->styles[$styleID]['numberformat']['code'] = $styleAttributeValue; | |||||
} | |||||
} | |||||
break; | |||||
case 'Protection': | |||||
foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { | |||||
// echo $styleAttributeKey.' = '.$styleAttributeValue.'<br />'; | |||||
} | |||||
break; | |||||
} | |||||
} | |||||
// print_r($this->styles[$styleID]); | |||||
// echo '<hr />'; | |||||
} | |||||
// echo '<hr />'; | |||||
$worksheetID = 0; | |||||
$xml_ss = $xml->children($namespaces['ss']); | |||||
foreach ($xml_ss->Worksheet as $worksheet) { | |||||
$worksheet_ss = $worksheet->attributes($namespaces['ss']); | |||||
if ((isset($this->loadSheetsOnly)) && (isset($worksheet_ss['Name'])) && | |||||
(!in_array($worksheet_ss['Name'], $this->loadSheetsOnly))) { | |||||
continue; | |||||
} | |||||
// echo '<h3>Worksheet: ', $worksheet_ss['Name'],'<h3>'; | |||||
// | |||||
// Create new Worksheet | |||||
$objPHPExcel->createSheet(); | |||||
$objPHPExcel->setActiveSheetIndex($worksheetID); | |||||
if (isset($worksheet_ss['Name'])) { | |||||
$worksheetName = self::convertStringEncoding((string) $worksheet_ss['Name'], $this->charSet); | |||||
// Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in | |||||
// formula cells... during the load, all formulae should be correct, and we're simply bringing | |||||
// the worksheet name in line with the formula, not the reverse | |||||
$objPHPExcel->getActiveSheet()->setTitle($worksheetName, false); | |||||
} | |||||
$columnID = 'A'; | |||||
if (isset($worksheet->Table->Column)) { | |||||
foreach ($worksheet->Table->Column as $columnData) { | |||||
$columnData_ss = $columnData->attributes($namespaces['ss']); | |||||
if (isset($columnData_ss['Index'])) { | |||||
$columnID = PHPExcel_Cell::stringFromColumnIndex($columnData_ss['Index']-1); | |||||
} | |||||
if (isset($columnData_ss['Width'])) { | |||||
$columnWidth = $columnData_ss['Width']; | |||||
// echo '<b>Setting column width for '.$columnID.' to '.$columnWidth.'</b><br />'; | |||||
$objPHPExcel->getActiveSheet()->getColumnDimension($columnID)->setWidth($columnWidth / 5.4); | |||||
} | |||||
++$columnID; | |||||
} | |||||
} | |||||
$rowID = 1; | |||||
if (isset($worksheet->Table->Row)) { | |||||
$additionalMergedCells = 0; | |||||
foreach ($worksheet->Table->Row as $rowData) { | |||||
$rowHasData = false; | |||||
$row_ss = $rowData->attributes($namespaces['ss']); | |||||
if (isset($row_ss['Index'])) { | |||||
$rowID = (integer) $row_ss['Index']; | |||||
} | |||||
// echo '<b>Row '.$rowID.'</b><br />'; | |||||
$columnID = 'A'; | |||||
foreach ($rowData->Cell as $cell) { | |||||
$cell_ss = $cell->attributes($namespaces['ss']); | |||||
if (isset($cell_ss['Index'])) { | |||||
$columnID = PHPExcel_Cell::stringFromColumnIndex($cell_ss['Index']-1); | |||||
} | |||||
$cellRange = $columnID.$rowID; | |||||
if ($this->getReadFilter() !== null) { | |||||
if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { | |||||
continue; | |||||
} | |||||
} | |||||
if ((isset($cell_ss['MergeAcross'])) || (isset($cell_ss['MergeDown']))) { | |||||
$columnTo = $columnID; | |||||
if (isset($cell_ss['MergeAcross'])) { | |||||
$additionalMergedCells += (int)$cell_ss['MergeAcross']; | |||||
$columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cell_ss['MergeAcross'] -1); | |||||
} | |||||
$rowTo = $rowID; | |||||
if (isset($cell_ss['MergeDown'])) { | |||||
$rowTo = $rowTo + $cell_ss['MergeDown']; | |||||
} | |||||
$cellRange .= ':'.$columnTo.$rowTo; | |||||
$objPHPExcel->getActiveSheet()->mergeCells($cellRange); | |||||
} | |||||
$cellIsSet = $hasCalculatedValue = false; | |||||
$cellDataFormula = ''; | |||||
if (isset($cell_ss['Formula'])) { | |||||
$cellDataFormula = $cell_ss['Formula']; | |||||
// added this as a check for array formulas | |||||
if (isset($cell_ss['ArrayRange'])) { | |||||
$cellDataCSEFormula = $cell_ss['ArrayRange']; | |||||
// echo "found an array formula at ".$columnID.$rowID."<br />"; | |||||
} | |||||
$hasCalculatedValue = true; | |||||
} | |||||
if (isset($cell->Data)) { | |||||
$cellValue = $cellData = $cell->Data; | |||||
$type = PHPExcel_Cell_DataType::TYPE_NULL; | |||||
$cellData_ss = $cellData->attributes($namespaces['ss']); | |||||
if (isset($cellData_ss['Type'])) { | |||||
$cellDataType = $cellData_ss['Type']; | |||||
switch ($cellDataType) { | |||||
/* | |||||
const TYPE_STRING = 's'; | |||||
const TYPE_FORMULA = 'f'; | |||||
const TYPE_NUMERIC = 'n'; | |||||
const TYPE_BOOL = 'b'; | |||||
const TYPE_NULL = 'null'; | |||||
const TYPE_INLINE = 'inlineStr'; | |||||
const TYPE_ERROR = 'e'; | |||||
*/ | |||||
case 'String': | |||||
$cellValue = self::convertStringEncoding($cellValue, $this->charSet); | |||||
$type = PHPExcel_Cell_DataType::TYPE_STRING; | |||||
break; | |||||
case 'Number': | |||||
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC; | |||||
$cellValue = (float) $cellValue; | |||||
if (floor($cellValue) == $cellValue) { | |||||
$cellValue = (integer) $cellValue; | |||||
} | |||||
break; | |||||
case 'Boolean': | |||||
$type = PHPExcel_Cell_DataType::TYPE_BOOL; | |||||
$cellValue = ($cellValue != 0); | |||||
break; | |||||
case 'DateTime': | |||||
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC; | |||||
$cellValue = PHPExcel_Shared_Date::PHPToExcel(strtotime($cellValue)); | |||||
break; | |||||
case 'Error': | |||||
$type = PHPExcel_Cell_DataType::TYPE_ERROR; | |||||
break; | |||||
} | |||||
} | |||||
if ($hasCalculatedValue) { | |||||
// echo 'FORMULA<br />'; | |||||
$type = PHPExcel_Cell_DataType::TYPE_FORMULA; | |||||
$columnNumber = PHPExcel_Cell::columnIndexFromString($columnID); | |||||
if (substr($cellDataFormula, 0, 3) == 'of:') { | |||||
$cellDataFormula = substr($cellDataFormula, 3); | |||||
// echo 'Before: ', $cellDataFormula,'<br />'; | |||||
$temp = explode('"', $cellDataFormula); | |||||
$key = false; | |||||
foreach ($temp as &$value) { | |||||
// Only replace in alternate array entries (i.e. non-quoted blocks) | |||||
if ($key = !$key) { | |||||
$value = str_replace(array('[.', '.', ']'), '', $value); | |||||
} | |||||
} | |||||
} else { | |||||
// Convert R1C1 style references to A1 style references (but only when not quoted) | |||||
// echo 'Before: ', $cellDataFormula,'<br />'; | |||||
$temp = explode('"', $cellDataFormula); | |||||
$key = false; | |||||
foreach ($temp as &$value) { | |||||
// Only replace in alternate array entries (i.e. non-quoted blocks) | |||||
if ($key = !$key) { | |||||
preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/', $value, $cellReferences, PREG_SET_ORDER + PREG_OFFSET_CAPTURE); | |||||
// Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way | |||||
// through the formula from left to right. Reversing means that we work right to left.through | |||||
// the formula | |||||
$cellReferences = array_reverse($cellReferences); | |||||
// Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent, | |||||
// then modify the formula to use that new reference | |||||
foreach ($cellReferences as $cellReference) { | |||||
$rowReference = $cellReference[2][0]; | |||||
// Empty R reference is the current row | |||||
if ($rowReference == '') { | |||||
$rowReference = $rowID; | |||||
} | |||||
// Bracketed R references are relative to the current row | |||||
if ($rowReference{0} == '[') { | |||||
$rowReference = $rowID + trim($rowReference, '[]'); | |||||
} | |||||
$columnReference = $cellReference[4][0]; | |||||
// Empty C reference is the current column | |||||
if ($columnReference == '') { | |||||
$columnReference = $columnNumber; | |||||
} | |||||
// Bracketed C references are relative to the current column | |||||
if ($columnReference{0} == '[') { | |||||
$columnReference = $columnNumber + trim($columnReference, '[]'); | |||||
} | |||||
$A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; | |||||
$value = substr_replace($value, $A1CellReference, $cellReference[0][1], strlen($cellReference[0][0])); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
unset($value); | |||||
// Then rebuild the formula string | |||||
$cellDataFormula = implode('"', $temp); | |||||
// echo 'After: ', $cellDataFormula,'<br />'; | |||||
} | |||||
// echo 'Cell '.$columnID.$rowID.' is a '.$type.' with a value of '.(($hasCalculatedValue) ? $cellDataFormula : $cellValue).'<br />'; | |||||
// | |||||
$objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $cellValue), $type); | |||||
if ($hasCalculatedValue) { | |||||
// echo 'Formula result is '.$cellValue.'<br />'; | |||||
$objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setCalculatedValue($cellValue); | |||||
} | |||||
$cellIsSet = $rowHasData = true; | |||||
} | |||||
if (isset($cell->Comment)) { | |||||
// echo '<b>comment found</b><br />'; | |||||
$commentAttributes = $cell->Comment->attributes($namespaces['ss']); | |||||
$author = 'unknown'; | |||||
if (isset($commentAttributes->Author)) { | |||||
$author = (string)$commentAttributes->Author; | |||||
// echo 'Author: ', $author,'<br />'; | |||||
} | |||||
$node = $cell->Comment->Data->asXML(); | |||||
// $annotation = str_replace('html:','',substr($node,49,-10)); | |||||
// echo $annotation,'<br />'; | |||||
$annotation = strip_tags($node); | |||||
// echo 'Annotation: ', $annotation,'<br />'; | |||||
$objPHPExcel->getActiveSheet()->getComment($columnID.$rowID)->setAuthor(self::convertStringEncoding($author, $this->charSet))->setText($this->parseRichText($annotation)); | |||||
} | |||||
if (($cellIsSet) && (isset($cell_ss['StyleID']))) { | |||||
$style = (string) $cell_ss['StyleID']; | |||||
// echo 'Cell style for '.$columnID.$rowID.' is '.$style.'<br />'; | |||||
if ((isset($this->styles[$style])) && (!empty($this->styles[$style]))) { | |||||
// echo 'Cell '.$columnID.$rowID.'<br />'; | |||||
// print_r($this->styles[$style]); | |||||
// echo '<br />'; | |||||
if (!$objPHPExcel->getActiveSheet()->cellExists($columnID.$rowID)) { | |||||
$objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValue(null); | |||||
} | |||||
$objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($this->styles[$style]); | |||||
} | |||||
} | |||||
++$columnID; | |||||
while ($additionalMergedCells > 0) { | |||||
++$columnID; | |||||
$additionalMergedCells--; | |||||
} | |||||
} | |||||
if ($rowHasData) { | |||||
if (isset($row_ss['StyleID'])) { | |||||
$rowStyle = $row_ss['StyleID']; | |||||
} | |||||
if (isset($row_ss['Height'])) { | |||||
$rowHeight = $row_ss['Height']; | |||||
// echo '<b>Setting row height to '.$rowHeight.'</b><br />'; | |||||
$objPHPExcel->getActiveSheet()->getRowDimension($rowID)->setRowHeight($rowHeight); | |||||
} | |||||
} | |||||
++$rowID; | |||||
} | |||||
} | |||||
++$worksheetID; | |||||
} | |||||
// Return | |||||
return $objPHPExcel; | |||||
} | |||||
protected static function convertStringEncoding($string, $charset) | |||||
{ | |||||
if ($charset != 'UTF-8') { | |||||
return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', $charset); | |||||
} | |||||
return $string; | |||||
} | |||||
protected function parseRichText($is = '') | |||||
{ | |||||
$value = new PHPExcel_RichText(); | |||||
$value->createText(self::convertStringEncoding($is, $this->charSet)); | |||||
return $value; | |||||
} | |||||
} |
@ -0,0 +1,520 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel | |||||
* | |||||
* 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_Reader_Excel2007 | |||||
* @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## | |||||
*/ | |||||
/** | |||||
* PHPExcel_Reader_Excel2007_Chart | |||||
* | |||||
* @category PHPExcel | |||||
* @package PHPExcel_Reader_Excel2007 | |||||
* @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | |||||
*/ | |||||
class PHPExcel_Reader_Excel2007_Chart | |||||
{ | |||||
private static function getAttribute($component, $name, $format) | |||||
{ | |||||
$attributes = $component->attributes(); | |||||
if (isset($attributes[$name])) { | |||||
if ($format == 'string') { | |||||
return (string) $attributes[$name]; | |||||
} elseif ($format == 'integer') { | |||||
return (integer) $attributes[$name]; | |||||
} elseif ($format == 'boolean') { | |||||
return (boolean) ($attributes[$name] === '0' || $attributes[$name] !== 'true') ? false : true; | |||||
} else { | |||||
return (float) $attributes[$name]; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
private static function readColor($color, $background = false) | |||||
{ | |||||
if (isset($color["rgb"])) { | |||||
return (string)$color["rgb"]; | |||||
} elseif (isset($color["indexed"])) { | |||||
return PHPExcel_Style_Color::indexedColor($color["indexed"]-7, $background)->getARGB(); | |||||
} | |||||
} | |||||
public static function readChart($chartElements, $chartName) | |||||
{ | |||||
$namespacesChartMeta = $chartElements->getNamespaces(true); | |||||
$chartElementsC = $chartElements->children($namespacesChartMeta['c']); | |||||
$XaxisLabel = $YaxisLabel = $legend = $title = null; | |||||
$dispBlanksAs = $plotVisOnly = null; | |||||
foreach ($chartElementsC as $chartElementKey => $chartElement) { | |||||
switch ($chartElementKey) { | |||||
case "chart": | |||||
foreach ($chartElement as $chartDetailsKey => $chartDetails) { | |||||
$chartDetailsC = $chartDetails->children($namespacesChartMeta['c']); | |||||
switch ($chartDetailsKey) { | |||||
case "plotArea": | |||||
$plotAreaLayout = $XaxisLable = $YaxisLable = null; | |||||
$plotSeries = $plotAttributes = array(); | |||||
foreach ($chartDetails as $chartDetailKey => $chartDetail) { | |||||
switch ($chartDetailKey) { | |||||
case "layout": | |||||
$plotAreaLayout = self::chartLayoutDetails($chartDetail, $namespacesChartMeta, 'plotArea'); | |||||
break; | |||||
case "catAx": | |||||
if (isset($chartDetail->title)) { | |||||
$XaxisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta, 'cat'); | |||||
} | |||||
break; | |||||
case "dateAx": | |||||
if (isset($chartDetail->title)) { | |||||
$XaxisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta, 'cat'); | |||||
} | |||||
break; | |||||
case "valAx": | |||||
if (isset($chartDetail->title)) { | |||||
$YaxisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta, 'cat'); | |||||
} | |||||
break; | |||||
case "barChart": | |||||
case "bar3DChart": | |||||
$barDirection = self::getAttribute($chartDetail->barDir, 'val', 'string'); | |||||
$plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); | |||||
$plotSer->setPlotDirection($barDirection); | |||||
$plotSeries[] = $plotSer; | |||||
$plotAttributes = self::readChartAttributes($chartDetail); | |||||
break; | |||||
case "lineChart": | |||||
case "line3DChart": | |||||
$plotSeries[] = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); | |||||
$plotAttributes = self::readChartAttributes($chartDetail); | |||||
break; | |||||
case "areaChart": | |||||
case "area3DChart": | |||||
$plotSeries[] = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); | |||||
$plotAttributes = self::readChartAttributes($chartDetail); | |||||
break; | |||||
case "doughnutChart": | |||||
case "pieChart": | |||||
case "pie3DChart": | |||||
$explosion = isset($chartDetail->ser->explosion); | |||||
$plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); | |||||
$plotSer->setPlotStyle($explosion); | |||||
$plotSeries[] = $plotSer; | |||||
$plotAttributes = self::readChartAttributes($chartDetail); | |||||
break; | |||||
case "scatterChart": | |||||
$scatterStyle = self::getAttribute($chartDetail->scatterStyle, 'val', 'string'); | |||||
$plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); | |||||
$plotSer->setPlotStyle($scatterStyle); | |||||
$plotSeries[] = $plotSer; | |||||
$plotAttributes = self::readChartAttributes($chartDetail); | |||||
break; | |||||
case "bubbleChart": | |||||
$bubbleScale = self::getAttribute($chartDetail->bubbleScale, 'val', 'integer'); | |||||
$plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); | |||||
$plotSer->setPlotStyle($bubbleScale); | |||||
$plotSeries[] = $plotSer; | |||||
$plotAttributes = self::readChartAttributes($chartDetail); | |||||
break; | |||||
case "radarChart": | |||||
$radarStyle = self::getAttribute($chartDetail->radarStyle, 'val', 'string'); | |||||
$plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); | |||||
$plotSer->setPlotStyle($radarStyle); | |||||
$plotSeries[] = $plotSer; | |||||
$plotAttributes = self::readChartAttributes($chartDetail); | |||||
break; | |||||
case "surfaceChart": | |||||
case "surface3DChart": | |||||
$wireFrame = self::getAttribute($chartDetail->wireframe, 'val', 'boolean'); | |||||
$plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); | |||||
$plotSer->setPlotStyle($wireFrame); | |||||
$plotSeries[] = $plotSer; | |||||
$plotAttributes = self::readChartAttributes($chartDetail); | |||||
break; | |||||
case "stockChart": | |||||
$plotSeries[] = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); | |||||
$plotAttributes = self::readChartAttributes($plotAreaLayout); | |||||
break; | |||||
} | |||||
} | |||||
if ($plotAreaLayout == null) { | |||||
$plotAreaLayout = new PHPExcel_Chart_Layout(); | |||||
} | |||||
$plotArea = new PHPExcel_Chart_PlotArea($plotAreaLayout, $plotSeries); | |||||
self::setChartAttributes($plotAreaLayout, $plotAttributes); | |||||
break; | |||||
case "plotVisOnly": | |||||
$plotVisOnly = self::getAttribute($chartDetails, 'val', 'string'); | |||||
break; | |||||
case "dispBlanksAs": | |||||
$dispBlanksAs = self::getAttribute($chartDetails, 'val', 'string'); | |||||
break; | |||||
case "title": | |||||
$title = self::chartTitle($chartDetails, $namespacesChartMeta, 'title'); | |||||
break; | |||||
case "legend": | |||||
$legendPos = 'r'; | |||||
$legendLayout = null; | |||||
$legendOverlay = false; | |||||
foreach ($chartDetails as $chartDetailKey => $chartDetail) { | |||||
switch ($chartDetailKey) { | |||||
case "legendPos": | |||||
$legendPos = self::getAttribute($chartDetail, 'val', 'string'); | |||||
break; | |||||
case "overlay": | |||||
$legendOverlay = self::getAttribute($chartDetail, 'val', 'boolean'); | |||||
break; | |||||
case "layout": | |||||
$legendLayout = self::chartLayoutDetails($chartDetail, $namespacesChartMeta, 'legend'); | |||||
break; | |||||
} | |||||
} | |||||
$legend = new PHPExcel_Chart_Legend($legendPos, $legendLayout, $legendOverlay); | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
$chart = new PHPExcel_Chart($chartName, $title, $legend, $plotArea, $plotVisOnly, $dispBlanksAs, $XaxisLabel, $YaxisLabel); | |||||
return $chart; | |||||
} | |||||
private static function chartTitle($titleDetails, $namespacesChartMeta, $type) | |||||
{ | |||||
$caption = array(); | |||||
$titleLayout = null; | |||||
foreach ($titleDetails as $titleDetailKey => $chartDetail) { | |||||
switch ($titleDetailKey) { | |||||
case "tx": | |||||
$titleDetails = $chartDetail->rich->children($namespacesChartMeta['a']); | |||||
foreach ($titleDetails as $titleKey => $titleDetail) { | |||||
switch ($titleKey) { | |||||
case "p": | |||||
$titleDetailPart = $titleDetail->children($namespacesChartMeta['a']); | |||||
$caption[] = self::parseRichText($titleDetailPart); | |||||
} | |||||
} | |||||
break; | |||||
case "layout": | |||||
$titleLayout = self::chartLayoutDetails($chartDetail, $namespacesChartMeta); | |||||
break; | |||||
} | |||||
} | |||||
return new PHPExcel_Chart_Title($caption, $titleLayout); | |||||
} | |||||
private static function chartLayoutDetails($chartDetail, $namespacesChartMeta) | |||||
{ | |||||
if (!isset($chartDetail->manualLayout)) { | |||||
return null; | |||||
} | |||||
$details = $chartDetail->manualLayout->children($namespacesChartMeta['c']); | |||||
if (is_null($details)) { | |||||
return null; | |||||
} | |||||
$layout = array(); | |||||
foreach ($details as $detailKey => $detail) { | |||||
// echo $detailKey, ' => ',self::getAttribute($detail, 'val', 'string'),PHP_EOL; | |||||
$layout[$detailKey] = self::getAttribute($detail, 'val', 'string'); | |||||
} | |||||
return new PHPExcel_Chart_Layout($layout); | |||||
} | |||||
private static function chartDataSeries($chartDetail, $namespacesChartMeta, $plotType) | |||||
{ | |||||
$multiSeriesType = null; | |||||
$smoothLine = false; | |||||
$seriesLabel = $seriesCategory = $seriesValues = $plotOrder = array(); | |||||
$seriesDetailSet = $chartDetail->children($namespacesChartMeta['c']); | |||||
foreach ($seriesDetailSet as $seriesDetailKey => $seriesDetails) { | |||||
switch ($seriesDetailKey) { | |||||
case "grouping": | |||||
$multiSeriesType = self::getAttribute($chartDetail->grouping, 'val', 'string'); | |||||
break; | |||||
case "ser": | |||||
$marker = null; | |||||
foreach ($seriesDetails as $seriesKey => $seriesDetail) { | |||||
switch ($seriesKey) { | |||||
case "idx": | |||||
$seriesIndex = self::getAttribute($seriesDetail, 'val', 'integer'); | |||||
break; | |||||
case "order": | |||||
$seriesOrder = self::getAttribute($seriesDetail, 'val', 'integer'); | |||||
$plotOrder[$seriesIndex] = $seriesOrder; | |||||
break; | |||||
case "tx": | |||||
$seriesLabel[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta); | |||||
break; | |||||
case "marker": | |||||
$marker = self::getAttribute($seriesDetail->symbol, 'val', 'string'); | |||||
break; | |||||
case "smooth": | |||||
$smoothLine = self::getAttribute($seriesDetail, 'val', 'boolean'); | |||||
break; | |||||
case "cat": | |||||
$seriesCategory[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta); | |||||
break; | |||||
case "val": | |||||
$seriesValues[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker); | |||||
break; | |||||
case "xVal": | |||||
$seriesCategory[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker); | |||||
break; | |||||
case "yVal": | |||||
$seriesValues[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker); | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return new PHPExcel_Chart_DataSeries($plotType, $multiSeriesType, $plotOrder, $seriesLabel, $seriesCategory, $seriesValues, $smoothLine); | |||||
} | |||||
private static function chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker = null, $smoothLine = false) | |||||
{ | |||||
if (isset($seriesDetail->strRef)) { | |||||
$seriesSource = (string) $seriesDetail->strRef->f; | |||||
$seriesData = self::chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']), 's'); | |||||
return new PHPExcel_Chart_DataSeriesValues('String', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); | |||||
} elseif (isset($seriesDetail->numRef)) { | |||||
$seriesSource = (string) $seriesDetail->numRef->f; | |||||
$seriesData = self::chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c'])); | |||||
return new PHPExcel_Chart_DataSeriesValues('Number', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); | |||||
} elseif (isset($seriesDetail->multiLvlStrRef)) { | |||||
$seriesSource = (string) $seriesDetail->multiLvlStrRef->f; | |||||
$seriesData = self::chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']), 's'); | |||||
$seriesData['pointCount'] = count($seriesData['dataValues']); | |||||
return new PHPExcel_Chart_DataSeriesValues('String', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); | |||||
} elseif (isset($seriesDetail->multiLvlNumRef)) { | |||||
$seriesSource = (string) $seriesDetail->multiLvlNumRef->f; | |||||
$seriesData = self::chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']), 's'); | |||||
$seriesData['pointCount'] = count($seriesData['dataValues']); | |||||
return new PHPExcel_Chart_DataSeriesValues('String', $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker, $smoothLine); | |||||
} | |||||
return null; | |||||
} | |||||
private static function chartDataSeriesValues($seriesValueSet, $dataType = 'n') | |||||
{ | |||||
$seriesVal = array(); | |||||
$formatCode = ''; | |||||
$pointCount = 0; | |||||
foreach ($seriesValueSet as $seriesValueIdx => $seriesValue) { | |||||
switch ($seriesValueIdx) { | |||||
case 'ptCount': | |||||
$pointCount = self::getAttribute($seriesValue, 'val', 'integer'); | |||||
break; | |||||
case 'formatCode': | |||||
$formatCode = (string) $seriesValue; | |||||
break; | |||||
case 'pt': | |||||
$pointVal = self::getAttribute($seriesValue, 'idx', 'integer'); | |||||
if ($dataType == 's') { | |||||
$seriesVal[$pointVal] = (string) $seriesValue->v; | |||||
} else { | |||||
$seriesVal[$pointVal] = (float) $seriesValue->v; | |||||
} | |||||
break; | |||||
} | |||||
} | |||||
return array( | |||||
'formatCode' => $formatCode, | |||||
'pointCount' => $pointCount, | |||||
'dataValues' => $seriesVal | |||||
); | |||||
} | |||||
private static function chartDataSeriesValuesMultiLevel($seriesValueSet, $dataType = 'n') | |||||
{ | |||||
$seriesVal = array(); | |||||
$formatCode = ''; | |||||
$pointCount = 0; | |||||
foreach ($seriesValueSet->lvl as $seriesLevelIdx => $seriesLevel) { | |||||
foreach ($seriesLevel as $seriesValueIdx => $seriesValue) { | |||||
switch ($seriesValueIdx) { | |||||
case 'ptCount': | |||||
$pointCount = self::getAttribute($seriesValue, 'val', 'integer'); | |||||
break; | |||||
case 'formatCode': | |||||
$formatCode = (string) $seriesValue; | |||||
break; | |||||
case 'pt': | |||||
$pointVal = self::getAttribute($seriesValue, 'idx', 'integer'); | |||||
if ($dataType == 's') { | |||||
$seriesVal[$pointVal][] = (string) $seriesValue->v; | |||||
} else { | |||||
$seriesVal[$pointVal][] = (float) $seriesValue->v; | |||||
} | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
return array( | |||||
'formatCode' => $formatCode, | |||||
'pointCount' => $pointCount, | |||||
'dataValues' => $seriesVal | |||||
); | |||||
} | |||||
private static function parseRichText($titleDetailPart = null) | |||||
{ | |||||
$value = new PHPExcel_RichText(); | |||||
foreach ($titleDetailPart as $titleDetailElementKey => $titleDetailElement) { | |||||
if (isset($titleDetailElement->t)) { | |||||
$objText = $value->createTextRun((string) $titleDetailElement->t); | |||||
} | |||||
if (isset($titleDetailElement->rPr)) { | |||||
if (isset($titleDetailElement->rPr->rFont["val"])) { | |||||
$objText->getFont()->setName((string) $titleDetailElement->rPr->rFont["val"]); | |||||
} | |||||
$fontSize = (self::getAttribute($titleDetailElement->rPr, 'sz', 'integer')); | |||||
if (!is_null($fontSize)) { | |||||
$objText->getFont()->setSize(floor($fontSize / 100)); | |||||
} | |||||
$fontColor = (self::getAttribute($titleDetailElement->rPr, 'color', 'string')); | |||||
if (!is_null($fontColor)) { | |||||
$objText->getFont()->setColor(new PHPExcel_Style_Color(self::readColor($fontColor))); | |||||
} | |||||
$bold = self::getAttribute($titleDetailElement->rPr, 'b', 'boolean'); | |||||
if (!is_null($bold)) { | |||||
$objText->getFont()->setBold($bold); | |||||
} | |||||
$italic = self::getAttribute($titleDetailElement->rPr, 'i', 'boolean'); | |||||
if (!is_null($italic)) { | |||||
$objText->getFont()->setItalic($italic); | |||||
} | |||||
$baseline = self::getAttribute($titleDetailElement->rPr, 'baseline', 'integer'); | |||||
if (!is_null($baseline)) { | |||||
if ($baseline > 0) { | |||||
$objText->getFont()->setSuperScript(true); | |||||
} elseif ($baseline < 0) { | |||||
$objText->getFont()->setSubScript(true); | |||||
} | |||||
} | |||||
$underscore = (self::getAttribute($titleDetailElement->rPr, 'u', 'string')); | |||||
if (!is_null($underscore)) { | |||||
if ($underscore == 'sng') { | |||||
$objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); | |||||
} elseif ($underscore == 'dbl') { | |||||
$objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLE); | |||||
} else { | |||||
$objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_NONE); | |||||
} | |||||
} | |||||
$strikethrough = (self::getAttribute($titleDetailElement->rPr, 's', 'string')); | |||||
if (!is_null($strikethrough)) { | |||||
if ($strikethrough == 'noStrike') { | |||||
$objText->getFont()->setStrikethrough(false); | |||||
} else { | |||||
$objText->getFont()->setStrikethrough(true); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return $value; | |||||
} | |||||
private static function readChartAttributes($chartDetail) | |||||
{ | |||||
$plotAttributes = array(); | |||||
if (isset($chartDetail->dLbls)) { | |||||
if (isset($chartDetail->dLbls->howLegendKey)) { | |||||
$plotAttributes['showLegendKey'] = self::getAttribute($chartDetail->dLbls->showLegendKey, 'val', 'string'); | |||||
} | |||||
if (isset($chartDetail->dLbls->showVal)) { | |||||
$plotAttributes['showVal'] = self::getAttribute($chartDetail->dLbls->showVal, 'val', 'string'); | |||||
} | |||||
if (isset($chartDetail->dLbls->showCatName)) { | |||||
$plotAttributes['showCatName'] = self::getAttribute($chartDetail->dLbls->showCatName, 'val', 'string'); | |||||
} | |||||
if (isset($chartDetail->dLbls->showSerName)) { | |||||
$plotAttributes['showSerName'] = self::getAttribute($chartDetail->dLbls->showSerName, 'val', 'string'); | |||||
} | |||||
if (isset($chartDetail->dLbls->showPercent)) { | |||||
$plotAttributes['showPercent'] = self::getAttribute($chartDetail->dLbls->showPercent, 'val', 'string'); | |||||
} | |||||
if (isset($chartDetail->dLbls->showBubbleSize)) { | |||||
$plotAttributes['showBubbleSize'] = self::getAttribute($chartDetail->dLbls->showBubbleSize, 'val', 'string'); | |||||
} | |||||
if (isset($chartDetail->dLbls->showLeaderLines)) { | |||||
$plotAttributes['showLeaderLines'] = self::getAttribute($chartDetail->dLbls->showLeaderLines, 'val', 'string'); | |||||
} | |||||
} | |||||
return $plotAttributes; | |||||
} | |||||
private static function setChartAttributes($plotArea, $plotAttributes) | |||||
{ | |||||
foreach ($plotAttributes as $plotAttributeKey => $plotAttributeValue) { | |||||
switch ($plotAttributeKey) { | |||||
case 'showLegendKey': | |||||
$plotArea->setShowLegendKey($plotAttributeValue); | |||||
break; | |||||
case 'showVal': | |||||
$plotArea->setShowVal($plotAttributeValue); | |||||
break; | |||||
case 'showCatName': | |||||
$plotArea->setShowCatName($plotAttributeValue); | |||||
break; | |||||
case 'showSerName': | |||||
$plotArea->setShowSerName($plotAttributeValue); | |||||
break; | |||||
case 'showPercent': | |||||
$plotArea->setShowPercent($plotAttributeValue); | |||||
break; | |||||
case 'showBubbleSize': | |||||
$plotArea->setShowBubbleSize($plotAttributeValue); | |||||
break; | |||||
case 'showLeaderLines': | |||||
$plotArea->setShowLeaderLines($plotAttributeValue); | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,127 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel | |||||
* | |||||
* 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_Reader_Excel2007 | |||||
* @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## | |||||
*/ | |||||
/** | |||||
* PHPExcel_Reader_Excel2007_Theme | |||||
* | |||||
* @category PHPExcel | |||||
* @package PHPExcel_Reader_Excel2007 | |||||
* @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | |||||
*/ | |||||
class PHPExcel_Reader_Excel2007_Theme | |||||
{ | |||||
/** | |||||
* Theme Name | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $themeName; | |||||
/** | |||||
* Colour Scheme Name | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $colourSchemeName; | |||||
/** | |||||
* Colour Map indexed by position | |||||
* | |||||
* @var array of string | |||||
*/ | |||||
private $colourMapValues; | |||||
/** | |||||
* Colour Map | |||||
* | |||||
* @var array of string | |||||
*/ | |||||
private $colourMap; | |||||
/** | |||||
* Create a new PHPExcel_Theme | |||||
* | |||||
*/ | |||||
public function __construct($themeName, $colourSchemeName, $colourMap) | |||||
{ | |||||
// Initialise values | |||||
$this->themeName = $themeName; | |||||
$this->colourSchemeName = $colourSchemeName; | |||||
$this->colourMap = $colourMap; | |||||
} | |||||
/** | |||||
* Get Theme Name | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getThemeName() | |||||
{ | |||||
return $this->themeName; | |||||
} | |||||
/** | |||||
* Get colour Scheme Name | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getColourSchemeName() | |||||
{ | |||||
return $this->colourSchemeName; | |||||
} | |||||
/** | |||||
* Get colour Map Value by Position | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getColourByIndex($index = 0) | |||||
{ | |||||
if (isset($this->colourMap[$index])) { | |||||
return $this->colourMap[$index]; | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* Implement PHP __clone to create a deep clone, not just a shallow copy. | |||||
*/ | |||||
public function __clone() | |||||
{ | |||||
$vars = get_object_vars($this); | |||||
foreach ($vars as $key => $value) { | |||||
if ((is_object($value)) && ($key != '_parent')) { | |||||
$this->$key = clone $value; | |||||
} else { | |||||
$this->$key = $value; | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,32 @@ | |||||
<?php | |||||
class PHPExcel_Reader_Excel5_Color | |||||
{ | |||||
/** | |||||
* Read color | |||||
* | |||||
* @param int $color Indexed color | |||||
* @param array $palette Color palette | |||||
* @return array RGB color value, example: array('rgb' => 'FF0000') | |||||
*/ | |||||
public static function map($color, $palette, $version) | |||||
{ | |||||
if ($color <= 0x07 || $color >= 0x40) { | |||||
// special built-in color | |||||
return PHPExcel_Reader_Excel5_Color_BuiltIn::lookup($color); | |||||
} elseif (isset($palette) && isset($palette[$color - 8])) { | |||||
// palette color, color index 0x08 maps to pallete index 0 | |||||
return $palette[$color - 8]; | |||||
} else { | |||||
// default color table | |||||
if ($version == PHPExcel_Reader_Excel5::XLS_BIFF8) { | |||||
return PHPExcel_Reader_Excel5_Color_BIFF8::lookup($color); | |||||
} else { | |||||
// BIFF5 | |||||
return PHPExcel_Reader_Excel5_Color_BIFF5::lookup($color); | |||||
} | |||||
} | |||||
return $color; | |||||
} | |||||
} |
@ -0,0 +1,77 @@ | |||||
<?php | |||||
class PHPExcel_Reader_Excel5_Color_BIFF5 | |||||
{ | |||||
protected static $map = array( | |||||
0x08 => '000000', | |||||
0x09 => 'FFFFFF', | |||||
0x0A => 'FF0000', | |||||
0x0B => '00FF00', | |||||
0x0C => '0000FF', | |||||
0x0D => 'FFFF00', | |||||
0x0E => 'FF00FF', | |||||
0x0F => '00FFFF', | |||||
0x10 => '800000', | |||||
0x11 => '008000', | |||||
0x12 => '000080', | |||||
0x13 => '808000', | |||||
0x14 => '800080', | |||||
0x15 => '008080', | |||||
0x16 => 'C0C0C0', | |||||
0x17 => '808080', | |||||
0x18 => '8080FF', | |||||
0x19 => '802060', | |||||
0x1A => 'FFFFC0', | |||||
0x1B => 'A0E0F0', | |||||
0x1C => '600080', | |||||
0x1D => 'FF8080', | |||||
0x1E => '0080C0', | |||||
0x1F => 'C0C0FF', | |||||
0x20 => '000080', | |||||
0x21 => 'FF00FF', | |||||
0x22 => 'FFFF00', | |||||
0x23 => '00FFFF', | |||||
0x24 => '800080', | |||||
0x25 => '800000', | |||||
0x26 => '008080', | |||||
0x27 => '0000FF', | |||||
0x28 => '00CFFF', | |||||
0x29 => '69FFFF', | |||||
0x2A => 'E0FFE0', | |||||
0x2B => 'FFFF80', | |||||
0x2C => 'A6CAF0', | |||||
0x2D => 'DD9CB3', | |||||
0x2E => 'B38FEE', | |||||
0x2F => 'E3E3E3', | |||||
0x30 => '2A6FF9', | |||||
0x31 => '3FB8CD', | |||||
0x32 => '488436', | |||||
0x33 => '958C41', | |||||
0x34 => '8E5E42', | |||||
0x35 => 'A0627A', | |||||
0x36 => '624FAC', | |||||
0x37 => '969696', | |||||
0x38 => '1D2FBE', | |||||
0x39 => '286676', | |||||
0x3A => '004500', | |||||
0x3B => '453E01', | |||||
0x3C => '6A2813', | |||||
0x3D => '85396A', | |||||
0x3E => '4A3285', | |||||
0x3F => '424242', | |||||
); | |||||
/** | |||||
* Map color array from BIFF5 built-in color index | |||||
* | |||||
* @param int $color | |||||
* @return array | |||||
*/ | |||||
public static function lookup($color) | |||||
{ | |||||
if (isset(self::$map[$color])) { | |||||
return array('rgb' => self::$map[$color]); | |||||
} | |||||
return array('rgb' => '000000'); | |||||
} | |||||
} |
@ -0,0 +1,77 @@ | |||||
<?php | |||||
class PHPExcel_Reader_Excel5_Color_BIFF8 | |||||
{ | |||||
protected static $map = array( | |||||
0x08 => '000000', | |||||
0x09 => 'FFFFFF', | |||||
0x0A => 'FF0000', | |||||
0x0B => '00FF00', | |||||
0x0C => '0000FF', | |||||
0x0D => 'FFFF00', | |||||
0x0E => 'FF00FF', | |||||
0x0F => '00FFFF', | |||||
0x10 => '800000', | |||||
0x11 => '008000', | |||||
0x12 => '000080', | |||||
0x13 => '808000', | |||||
0x14 => '800080', | |||||
0x15 => '008080', | |||||
0x16 => 'C0C0C0', | |||||
0x17 => '808080', | |||||
0x18 => '9999FF', | |||||
0x19 => '993366', | |||||
0x1A => 'FFFFCC', | |||||
0x1B => 'CCFFFF', | |||||
0x1C => '660066', | |||||
0x1D => 'FF8080', | |||||
0x1E => '0066CC', | |||||
0x1F => 'CCCCFF', | |||||
0x20 => '000080', | |||||
0x21 => 'FF00FF', | |||||
0x22 => 'FFFF00', | |||||
0x23 => '00FFFF', | |||||
0x24 => '800080', | |||||
0x25 => '800000', | |||||
0x26 => '008080', | |||||
0x27 => '0000FF', | |||||
0x28 => '00CCFF', | |||||
0x29 => 'CCFFFF', | |||||
0x2A => 'CCFFCC', | |||||
0x2B => 'FFFF99', | |||||
0x2C => '99CCFF', | |||||
0x2D => 'FF99CC', | |||||
0x2E => 'CC99FF', | |||||
0x2F => 'FFCC99', | |||||
0x30 => '3366FF', | |||||
0x31 => '33CCCC', | |||||
0x32 => '99CC00', | |||||
0x33 => 'FFCC00', | |||||
0x34 => 'FF9900', | |||||
0x35 => 'FF6600', | |||||
0x36 => '666699', | |||||
0x37 => '969696', | |||||
0x38 => '003366', | |||||
0x39 => '339966', | |||||
0x3A => '003300', | |||||
0x3B => '333300', | |||||
0x3C => '993300', | |||||
0x3D => '993366', | |||||
0x3E => '333399', | |||||
0x3F => '333333', | |||||
); | |||||
/** | |||||
* Map color array from BIFF8 built-in color index | |||||
* | |||||
* @param int $color | |||||
* @return array | |||||
*/ | |||||
public static function lookup($color) | |||||
{ | |||||
if (isset(self::$map[$color])) { | |||||
return array('rgb' => self::$map[$color]); | |||||
} | |||||
return array('rgb' => '000000'); | |||||
} | |||||
} |
@ -0,0 +1,31 @@ | |||||
<?php | |||||
class PHPExcel_Reader_Excel5_Color_BuiltIn | |||||
{ | |||||
protected static $map = array( | |||||
0x00 => '000000', | |||||
0x01 => 'FFFFFF', | |||||
0x02 => 'FF0000', | |||||
0x03 => '00FF00', | |||||
0x04 => '0000FF', | |||||
0x05 => 'FFFF00', | |||||
0x06 => 'FF00FF', | |||||
0x07 => '00FFFF', | |||||
0x40 => '000000', // system window text color | |||||
0x41 => 'FFFFFF', // system window background color | |||||
); | |||||
/** | |||||
* Map built-in color to RGB value | |||||
* | |||||
* @param int $color Indexed color | |||||
* @return array | |||||
*/ | |||||
public static function lookup($color) | |||||
{ | |||||
if (isset(self::$map[$color])) { | |||||
return array('rgb' => self::$map[$color]); | |||||
} | |||||
return array('rgb' => '000000'); | |||||
} | |||||
} |
@ -0,0 +1,28 @@ | |||||
<?php | |||||
class PHPExcel_Reader_Excel5_ErrorCode | |||||
{ | |||||
protected static $map = array( | |||||
0x00 => '#NULL!', | |||||
0x07 => '#DIV/0!', | |||||
0x0F => '#VALUE!', | |||||
0x17 => '#REF!', | |||||
0x1D => '#NAME?', | |||||
0x24 => '#NUM!', | |||||
0x2A => '#N/A', | |||||
); | |||||
/** | |||||
* Map error code, e.g. '#N/A' | |||||
* | |||||
* @param int $code | |||||
* @return string | |||||
*/ | |||||
public static function lookup($code) | |||||
{ | |||||
if (isset(self::$map[$code])) { | |||||
return self::$map[$code]; | |||||
} | |||||
return false; | |||||
} | |||||
} |
@ -0,0 +1,669 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Reader_Excel5_Escher | |||||
* | |||||
* 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_Reader_Excel5 | |||||
* @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_Reader_Excel5_Escher | |||||
{ | |||||
const DGGCONTAINER = 0xF000; | |||||
const BSTORECONTAINER = 0xF001; | |||||
const DGCONTAINER = 0xF002; | |||||
const SPGRCONTAINER = 0xF003; | |||||
const SPCONTAINER = 0xF004; | |||||
const DGG = 0xF006; | |||||
const BSE = 0xF007; | |||||
const DG = 0xF008; | |||||
const SPGR = 0xF009; | |||||
const SP = 0xF00A; | |||||
const OPT = 0xF00B; | |||||
const CLIENTTEXTBOX = 0xF00D; | |||||
const CLIENTANCHOR = 0xF010; | |||||
const CLIENTDATA = 0xF011; | |||||
const BLIPJPEG = 0xF01D; | |||||
const BLIPPNG = 0xF01E; | |||||
const SPLITMENUCOLORS = 0xF11E; | |||||
const TERTIARYOPT = 0xF122; | |||||
/** | |||||
* Escher stream data (binary) | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $data; | |||||
/** | |||||
* Size in bytes of the Escher stream data | |||||
* | |||||
* @var int | |||||
*/ | |||||
private $dataSize; | |||||
/** | |||||
* Current position of stream pointer in Escher stream data | |||||
* | |||||
* @var int | |||||
*/ | |||||
private $pos; | |||||
/** | |||||
* The object to be returned by the reader. Modified during load. | |||||
* | |||||
* @var mixed | |||||
*/ | |||||
private $object; | |||||
/** | |||||
* Create a new PHPExcel_Reader_Excel5_Escher instance | |||||
* | |||||
* @param mixed $object | |||||
*/ | |||||
public function __construct($object) | |||||
{ | |||||
$this->object = $object; | |||||
} | |||||
/** | |||||
* Load Escher stream data. May be a partial Escher stream. | |||||
* | |||||
* @param string $data | |||||
*/ | |||||
public function load($data) | |||||
{ | |||||
$this->data = $data; | |||||
// total byte size of Excel data (workbook global substream + sheet substreams) | |||||
$this->dataSize = strlen($this->data); | |||||
$this->pos = 0; | |||||
// Parse Escher stream | |||||
while ($this->pos < $this->dataSize) { | |||||
// offset: 2; size: 2: Record Type | |||||
$fbt = PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos + 2); | |||||
switch ($fbt) { | |||||
case self::DGGCONTAINER: | |||||
$this->readDggContainer(); | |||||
break; | |||||
case self::DGG: | |||||
$this->readDgg(); | |||||
break; | |||||
case self::BSTORECONTAINER: | |||||
$this->readBstoreContainer(); | |||||
break; | |||||
case self::BSE: | |||||
$this->readBSE(); | |||||
break; | |||||
case self::BLIPJPEG: | |||||
$this->readBlipJPEG(); | |||||
break; | |||||
case self::BLIPPNG: | |||||
$this->readBlipPNG(); | |||||
break; | |||||
case self::OPT: | |||||
$this->readOPT(); | |||||
break; | |||||
case self::TERTIARYOPT: | |||||
$this->readTertiaryOPT(); | |||||
break; | |||||
case self::SPLITMENUCOLORS: | |||||
$this->readSplitMenuColors(); | |||||
break; | |||||
case self::DGCONTAINER: | |||||
$this->readDgContainer(); | |||||
break; | |||||
case self::DG: | |||||
$this->readDg(); | |||||
break; | |||||
case self::SPGRCONTAINER: | |||||
$this->readSpgrContainer(); | |||||
break; | |||||
case self::SPCONTAINER: | |||||
$this->readSpContainer(); | |||||
break; | |||||
case self::SPGR: | |||||
$this->readSpgr(); | |||||
break; | |||||
case self::SP: | |||||
$this->readSp(); | |||||
break; | |||||
case self::CLIENTTEXTBOX: | |||||
$this->readClientTextbox(); | |||||
break; | |||||
case self::CLIENTANCHOR: | |||||
$this->readClientAnchor(); | |||||
break; | |||||
case self::CLIENTDATA: | |||||
$this->readClientData(); | |||||
break; | |||||
default: | |||||
$this->readDefault(); | |||||
break; | |||||
} | |||||
} | |||||
return $this->object; | |||||
} | |||||
/** | |||||
* Read a generic record | |||||
*/ | |||||
private function readDefault() | |||||
{ | |||||
// offset 0; size: 2; recVer and recInstance | |||||
$verInstance = PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos); | |||||
// offset: 2; size: 2: Record Type | |||||
$fbt = PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos + 2); | |||||
// bit: 0-3; mask: 0x000F; recVer | |||||
$recVer = (0x000F & $verInstance) >> 0; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read DggContainer record (Drawing Group Container) | |||||
*/ | |||||
private function readDggContainer() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
// record is a container, read contents | |||||
$dggContainer = new PHPExcel_Shared_Escher_DggContainer(); | |||||
$this->object->setDggContainer($dggContainer); | |||||
$reader = new PHPExcel_Reader_Excel5_Escher($dggContainer); | |||||
$reader->load($recordData); | |||||
} | |||||
/** | |||||
* Read Dgg record (Drawing Group) | |||||
*/ | |||||
private function readDgg() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read BstoreContainer record (Blip Store Container) | |||||
*/ | |||||
private function readBstoreContainer() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
// record is a container, read contents | |||||
$bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer(); | |||||
$this->object->setBstoreContainer($bstoreContainer); | |||||
$reader = new PHPExcel_Reader_Excel5_Escher($bstoreContainer); | |||||
$reader->load($recordData); | |||||
} | |||||
/** | |||||
* Read BSE record | |||||
*/ | |||||
private function readBSE() | |||||
{ | |||||
// offset: 0; size: 2; recVer and recInstance | |||||
// bit: 4-15; mask: 0xFFF0; recInstance | |||||
$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
// add BSE to BstoreContainer | |||||
$BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); | |||||
$this->object->addBSE($BSE); | |||||
$BSE->setBLIPType($recInstance); | |||||
// offset: 0; size: 1; btWin32 (MSOBLIPTYPE) | |||||
$btWin32 = ord($recordData[0]); | |||||
// offset: 1; size: 1; btWin32 (MSOBLIPTYPE) | |||||
$btMacOS = ord($recordData[1]); | |||||
// offset: 2; size: 16; MD4 digest | |||||
$rgbUid = substr($recordData, 2, 16); | |||||
// offset: 18; size: 2; tag | |||||
$tag = PHPExcel_Reader_Excel5::getInt2d($recordData, 18); | |||||
// offset: 20; size: 4; size of BLIP in bytes | |||||
$size = PHPExcel_Reader_Excel5::getInt4d($recordData, 20); | |||||
// offset: 24; size: 4; number of references to this BLIP | |||||
$cRef = PHPExcel_Reader_Excel5::getInt4d($recordData, 24); | |||||
// offset: 28; size: 4; MSOFO file offset | |||||
$foDelay = PHPExcel_Reader_Excel5::getInt4d($recordData, 28); | |||||
// offset: 32; size: 1; unused1 | |||||
$unused1 = ord($recordData[32]); | |||||
// offset: 33; size: 1; size of nameData in bytes (including null terminator) | |||||
$cbName = ord($recordData[33]); | |||||
// offset: 34; size: 1; unused2 | |||||
$unused2 = ord($recordData[34]); | |||||
// offset: 35; size: 1; unused3 | |||||
$unused3 = ord($recordData[35]); | |||||
// offset: 36; size: $cbName; nameData | |||||
$nameData = substr($recordData, 36, $cbName); | |||||
// offset: 36 + $cbName, size: var; the BLIP data | |||||
$blipData = substr($recordData, 36 + $cbName); | |||||
// record is a container, read contents | |||||
$reader = new PHPExcel_Reader_Excel5_Escher($BSE); | |||||
$reader->load($blipData); | |||||
} | |||||
/** | |||||
* Read BlipJPEG record. Holds raw JPEG image data | |||||
*/ | |||||
private function readBlipJPEG() | |||||
{ | |||||
// offset: 0; size: 2; recVer and recInstance | |||||
// bit: 4-15; mask: 0xFFF0; recInstance | |||||
$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
$pos = 0; | |||||
// offset: 0; size: 16; rgbUid1 (MD4 digest of) | |||||
$rgbUid1 = substr($recordData, 0, 16); | |||||
$pos += 16; | |||||
// offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3 | |||||
if (in_array($recInstance, array(0x046B, 0x06E3))) { | |||||
$rgbUid2 = substr($recordData, 16, 16); | |||||
$pos += 16; | |||||
} | |||||
// offset: var; size: 1; tag | |||||
$tag = ord($recordData[$pos]); | |||||
$pos += 1; | |||||
// offset: var; size: var; the raw image data | |||||
$data = substr($recordData, $pos); | |||||
$blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); | |||||
$blip->setData($data); | |||||
$this->object->setBlip($blip); | |||||
} | |||||
/** | |||||
* Read BlipPNG record. Holds raw PNG image data | |||||
*/ | |||||
private function readBlipPNG() | |||||
{ | |||||
// offset: 0; size: 2; recVer and recInstance | |||||
// bit: 4-15; mask: 0xFFF0; recInstance | |||||
$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
$pos = 0; | |||||
// offset: 0; size: 16; rgbUid1 (MD4 digest of) | |||||
$rgbUid1 = substr($recordData, 0, 16); | |||||
$pos += 16; | |||||
// offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3 | |||||
if ($recInstance == 0x06E1) { | |||||
$rgbUid2 = substr($recordData, 16, 16); | |||||
$pos += 16; | |||||
} | |||||
// offset: var; size: 1; tag | |||||
$tag = ord($recordData[$pos]); | |||||
$pos += 1; | |||||
// offset: var; size: var; the raw image data | |||||
$data = substr($recordData, $pos); | |||||
$blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); | |||||
$blip->setData($data); | |||||
$this->object->setBlip($blip); | |||||
} | |||||
/** | |||||
* Read OPT record. This record may occur within DggContainer record or SpContainer | |||||
*/ | |||||
private function readOPT() | |||||
{ | |||||
// offset: 0; size: 2; recVer and recInstance | |||||
// bit: 4-15; mask: 0xFFF0; recInstance | |||||
$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
$this->readOfficeArtRGFOPTE($recordData, $recInstance); | |||||
} | |||||
/** | |||||
* Read TertiaryOPT record | |||||
*/ | |||||
private function readTertiaryOPT() | |||||
{ | |||||
// offset: 0; size: 2; recVer and recInstance | |||||
// bit: 4-15; mask: 0xFFF0; recInstance | |||||
$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read SplitMenuColors record | |||||
*/ | |||||
private function readSplitMenuColors() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read DgContainer record (Drawing Container) | |||||
*/ | |||||
private function readDgContainer() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
// record is a container, read contents | |||||
$dgContainer = new PHPExcel_Shared_Escher_DgContainer(); | |||||
$this->object->setDgContainer($dgContainer); | |||||
$reader = new PHPExcel_Reader_Excel5_Escher($dgContainer); | |||||
$escher = $reader->load($recordData); | |||||
} | |||||
/** | |||||
* Read Dg record (Drawing) | |||||
*/ | |||||
private function readDg() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read SpgrContainer record (Shape Group Container) | |||||
*/ | |||||
private function readSpgrContainer() | |||||
{ | |||||
// context is either context DgContainer or SpgrContainer | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
// record is a container, read contents | |||||
$spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer(); | |||||
if ($this->object instanceof PHPExcel_Shared_Escher_DgContainer) { | |||||
// DgContainer | |||||
$this->object->setSpgrContainer($spgrContainer); | |||||
} else { | |||||
// SpgrContainer | |||||
$this->object->addChild($spgrContainer); | |||||
} | |||||
$reader = new PHPExcel_Reader_Excel5_Escher($spgrContainer); | |||||
$escher = $reader->load($recordData); | |||||
} | |||||
/** | |||||
* Read SpContainer record (Shape Container) | |||||
*/ | |||||
private function readSpContainer() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// add spContainer to spgrContainer | |||||
$spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); | |||||
$this->object->addChild($spContainer); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
// record is a container, read contents | |||||
$reader = new PHPExcel_Reader_Excel5_Escher($spContainer); | |||||
$escher = $reader->load($recordData); | |||||
} | |||||
/** | |||||
* Read Spgr record (Shape Group) | |||||
*/ | |||||
private function readSpgr() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read Sp record (Shape) | |||||
*/ | |||||
private function readSp() | |||||
{ | |||||
// offset: 0; size: 2; recVer and recInstance | |||||
// bit: 4-15; mask: 0xFFF0; recInstance | |||||
$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read ClientTextbox record | |||||
*/ | |||||
private function readClientTextbox() | |||||
{ | |||||
// offset: 0; size: 2; recVer and recInstance | |||||
// bit: 4-15; mask: 0xFFF0; recInstance | |||||
$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read ClientAnchor record. This record holds information about where the shape is anchored in worksheet | |||||
*/ | |||||
private function readClientAnchor() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
// offset: 2; size: 2; upper-left corner column index (0-based) | |||||
$c1 = PHPExcel_Reader_Excel5::getInt2d($recordData, 2); | |||||
// offset: 4; size: 2; upper-left corner horizontal offset in 1/1024 of column width | |||||
$startOffsetX = PHPExcel_Reader_Excel5::getInt2d($recordData, 4); | |||||
// offset: 6; size: 2; upper-left corner row index (0-based) | |||||
$r1 = PHPExcel_Reader_Excel5::getInt2d($recordData, 6); | |||||
// offset: 8; size: 2; upper-left corner vertical offset in 1/256 of row height | |||||
$startOffsetY = PHPExcel_Reader_Excel5::getInt2d($recordData, 8); | |||||
// offset: 10; size: 2; bottom-right corner column index (0-based) | |||||
$c2 = PHPExcel_Reader_Excel5::getInt2d($recordData, 10); | |||||
// offset: 12; size: 2; bottom-right corner horizontal offset in 1/1024 of column width | |||||
$endOffsetX = PHPExcel_Reader_Excel5::getInt2d($recordData, 12); | |||||
// offset: 14; size: 2; bottom-right corner row index (0-based) | |||||
$r2 = PHPExcel_Reader_Excel5::getInt2d($recordData, 14); | |||||
// offset: 16; size: 2; bottom-right corner vertical offset in 1/256 of row height | |||||
$endOffsetY = PHPExcel_Reader_Excel5::getInt2d($recordData, 16); | |||||
// set the start coordinates | |||||
$this->object->setStartCoordinates(PHPExcel_Cell::stringFromColumnIndex($c1) . ($r1 + 1)); | |||||
// set the start offsetX | |||||
$this->object->setStartOffsetX($startOffsetX); | |||||
// set the start offsetY | |||||
$this->object->setStartOffsetY($startOffsetY); | |||||
// set the end coordinates | |||||
$this->object->setEndCoordinates(PHPExcel_Cell::stringFromColumnIndex($c2) . ($r2 + 1)); | |||||
// set the end offsetX | |||||
$this->object->setEndOffsetX($endOffsetX); | |||||
// set the end offsetY | |||||
$this->object->setEndOffsetY($endOffsetY); | |||||
} | |||||
/** | |||||
* Read ClientData record | |||||
*/ | |||||
private function readClientData() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read OfficeArtRGFOPTE table of property-value pairs | |||||
* | |||||
* @param string $data Binary data | |||||
* @param int $n Number of properties | |||||
*/ | |||||
private function readOfficeArtRGFOPTE($data, $n) | |||||
{ | |||||
$splicedComplexData = substr($data, 6 * $n); | |||||
// loop through property-value pairs | |||||
for ($i = 0; $i < $n; ++$i) { | |||||
// read 6 bytes at a time | |||||
$fopte = substr($data, 6 * $i, 6); | |||||
// offset: 0; size: 2; opid | |||||
$opid = PHPExcel_Reader_Excel5::getInt2d($fopte, 0); | |||||
// bit: 0-13; mask: 0x3FFF; opid.opid | |||||
$opidOpid = (0x3FFF & $opid) >> 0; | |||||
// bit: 14; mask 0x4000; 1 = value in op field is BLIP identifier | |||||
$opidFBid = (0x4000 & $opid) >> 14; | |||||
// bit: 15; mask 0x8000; 1 = this is a complex property, op field specifies size of complex data | |||||
$opidFComplex = (0x8000 & $opid) >> 15; | |||||
// offset: 2; size: 4; the value for this property | |||||
$op = PHPExcel_Reader_Excel5::getInt4d($fopte, 2); | |||||
if ($opidFComplex) { | |||||
$complexData = substr($splicedComplexData, 0, $op); | |||||
$splicedComplexData = substr($splicedComplexData, $op); | |||||
// we store string value with complex data | |||||
$value = $complexData; | |||||
} else { | |||||
// we store integer value | |||||
$value = $op; | |||||
} | |||||
$this->object->setOPT($opidOpid, $value); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,669 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Reader_Excel5_Escher | |||||
* | |||||
* 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_Reader_Excel5 | |||||
* @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_Reader_Excel5_Escher | |||||
{ | |||||
const DGGCONTAINER = 0xF000; | |||||
const BSTORECONTAINER = 0xF001; | |||||
const DGCONTAINER = 0xF002; | |||||
const SPGRCONTAINER = 0xF003; | |||||
const SPCONTAINER = 0xF004; | |||||
const DGG = 0xF006; | |||||
const BSE = 0xF007; | |||||
const DG = 0xF008; | |||||
const SPGR = 0xF009; | |||||
const SP = 0xF00A; | |||||
const OPT = 0xF00B; | |||||
const CLIENTTEXTBOX = 0xF00D; | |||||
const CLIENTANCHOR = 0xF010; | |||||
const CLIENTDATA = 0xF011; | |||||
const BLIPJPEG = 0xF01D; | |||||
const BLIPPNG = 0xF01E; | |||||
const SPLITMENUCOLORS = 0xF11E; | |||||
const TERTIARYOPT = 0xF122; | |||||
/** | |||||
* Escher stream data (binary) | |||||
* | |||||
* @var string | |||||
*/ | |||||
private $data; | |||||
/** | |||||
* Size in bytes of the Escher stream data | |||||
* | |||||
* @var int | |||||
*/ | |||||
private $dataSize; | |||||
/** | |||||
* Current position of stream pointer in Escher stream data | |||||
* | |||||
* @var int | |||||
*/ | |||||
private $pos; | |||||
/** | |||||
* The object to be returned by the reader. Modified during load. | |||||
* | |||||
* @var mixed | |||||
*/ | |||||
private $object; | |||||
/** | |||||
* Create a new PHPExcel_Reader_Excel5_Escher instance | |||||
* | |||||
* @param mixed $object | |||||
*/ | |||||
public function __construct($object) | |||||
{ | |||||
$this->object = $object; | |||||
} | |||||
/** | |||||
* Load Escher stream data. May be a partial Escher stream. | |||||
* | |||||
* @param string $data | |||||
*/ | |||||
public function load($data) | |||||
{ | |||||
$this->data = $data; | |||||
// total byte size of Excel data (workbook global substream + sheet substreams) | |||||
$this->dataSize = strlen($this->data); | |||||
$this->pos = 0; | |||||
// Parse Escher stream | |||||
while ($this->pos < $this->dataSize) { | |||||
// offset: 2; size: 2: Record Type | |||||
$fbt = PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos + 2); | |||||
switch ($fbt) { | |||||
case self::DGGCONTAINER: | |||||
$this->readDggContainer(); | |||||
break; | |||||
case self::DGG: | |||||
$this->readDgg(); | |||||
break; | |||||
case self::BSTORECONTAINER: | |||||
$this->readBstoreContainer(); | |||||
break; | |||||
case self::BSE: | |||||
$this->readBSE(); | |||||
break; | |||||
case self::BLIPJPEG: | |||||
$this->readBlipJPEG(); | |||||
break; | |||||
case self::BLIPPNG: | |||||
$this->readBlipPNG(); | |||||
break; | |||||
case self::OPT: | |||||
$this->readOPT(); | |||||
break; | |||||
case self::TERTIARYOPT: | |||||
$this->readTertiaryOPT(); | |||||
break; | |||||
case self::SPLITMENUCOLORS: | |||||
$this->readSplitMenuColors(); | |||||
break; | |||||
case self::DGCONTAINER: | |||||
$this->readDgContainer(); | |||||
break; | |||||
case self::DG: | |||||
$this->readDg(); | |||||
break; | |||||
case self::SPGRCONTAINER: | |||||
$this->readSpgrContainer(); | |||||
break; | |||||
case self::SPCONTAINER: | |||||
$this->readSpContainer(); | |||||
break; | |||||
case self::SPGR: | |||||
$this->readSpgr(); | |||||
break; | |||||
case self::SP: | |||||
$this->readSp(); | |||||
break; | |||||
case self::CLIENTTEXTBOX: | |||||
$this->readClientTextbox(); | |||||
break; | |||||
case self::CLIENTANCHOR: | |||||
$this->readClientAnchor(); | |||||
break; | |||||
case self::CLIENTDATA: | |||||
$this->readClientData(); | |||||
break; | |||||
default: | |||||
$this->readDefault(); | |||||
break; | |||||
} | |||||
} | |||||
return $this->object; | |||||
} | |||||
/** | |||||
* Read a generic record | |||||
*/ | |||||
private function readDefault() | |||||
{ | |||||
// offset 0; size: 2; recVer and recInstance | |||||
$verInstance = PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos); | |||||
// offset: 2; size: 2: Record Type | |||||
$fbt = PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos + 2); | |||||
// bit: 0-3; mask: 0x000F; recVer | |||||
$recVer = (0x000F & $verInstance) >> 0; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read DggContainer record (Drawing Group Container) | |||||
*/ | |||||
private function readDggContainer() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
// record is a container, read contents | |||||
$dggContainer = new PHPExcel_Shared_Escher_DggContainer(); | |||||
$this->object->setDggContainer($dggContainer); | |||||
$reader = new PHPExcel_Reader_Excel5_Escher($dggContainer); | |||||
$reader->load($recordData); | |||||
} | |||||
/** | |||||
* Read Dgg record (Drawing Group) | |||||
*/ | |||||
private function readDgg() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read BstoreContainer record (Blip Store Container) | |||||
*/ | |||||
private function readBstoreContainer() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
// record is a container, read contents | |||||
$bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer(); | |||||
$this->object->setBstoreContainer($bstoreContainer); | |||||
$reader = new PHPExcel_Reader_Excel5_Escher($bstoreContainer); | |||||
$reader->load($recordData); | |||||
} | |||||
/** | |||||
* Read BSE record | |||||
*/ | |||||
private function readBSE() | |||||
{ | |||||
// offset: 0; size: 2; recVer and recInstance | |||||
// bit: 4-15; mask: 0xFFF0; recInstance | |||||
$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
// add BSE to BstoreContainer | |||||
$BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); | |||||
$this->object->addBSE($BSE); | |||||
$BSE->setBLIPType($recInstance); | |||||
// offset: 0; size: 1; btWin32 (MSOBLIPTYPE) | |||||
$btWin32 = ord($recordData[0]); | |||||
// offset: 1; size: 1; btWin32 (MSOBLIPTYPE) | |||||
$btMacOS = ord($recordData[1]); | |||||
// offset: 2; size: 16; MD4 digest | |||||
$rgbUid = substr($recordData, 2, 16); | |||||
// offset: 18; size: 2; tag | |||||
$tag = PHPExcel_Reader_Excel5::getInt2d($recordData, 18); | |||||
// offset: 20; size: 4; size of BLIP in bytes | |||||
$size = PHPExcel_Reader_Excel5::getInt4d($recordData, 20); | |||||
// offset: 24; size: 4; number of references to this BLIP | |||||
$cRef = PHPExcel_Reader_Excel5::getInt4d($recordData, 24); | |||||
// offset: 28; size: 4; MSOFO file offset | |||||
$foDelay = PHPExcel_Reader_Excel5::getInt4d($recordData, 28); | |||||
// offset: 32; size: 1; unused1 | |||||
$unused1 = ord($recordData{32}); | |||||
// offset: 33; size: 1; size of nameData in bytes (including null terminator) | |||||
$cbName = ord($recordData{33}); | |||||
// offset: 34; size: 1; unused2 | |||||
$unused2 = ord($recordData{34}); | |||||
// offset: 35; size: 1; unused3 | |||||
$unused3 = ord($recordData{35}); | |||||
// offset: 36; size: $cbName; nameData | |||||
$nameData = substr($recordData, 36, $cbName); | |||||
// offset: 36 + $cbName, size: var; the BLIP data | |||||
$blipData = substr($recordData, 36 + $cbName); | |||||
// record is a container, read contents | |||||
$reader = new PHPExcel_Reader_Excel5_Escher($BSE); | |||||
$reader->load($blipData); | |||||
} | |||||
/** | |||||
* Read BlipJPEG record. Holds raw JPEG image data | |||||
*/ | |||||
private function readBlipJPEG() | |||||
{ | |||||
// offset: 0; size: 2; recVer and recInstance | |||||
// bit: 4-15; mask: 0xFFF0; recInstance | |||||
$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
$pos = 0; | |||||
// offset: 0; size: 16; rgbUid1 (MD4 digest of) | |||||
$rgbUid1 = substr($recordData, 0, 16); | |||||
$pos += 16; | |||||
// offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3 | |||||
if (in_array($recInstance, array(0x046B, 0x06E3))) { | |||||
$rgbUid2 = substr($recordData, 16, 16); | |||||
$pos += 16; | |||||
} | |||||
// offset: var; size: 1; tag | |||||
$tag = ord($recordData{$pos}); | |||||
$pos += 1; | |||||
// offset: var; size: var; the raw image data | |||||
$data = substr($recordData, $pos); | |||||
$blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); | |||||
$blip->setData($data); | |||||
$this->object->setBlip($blip); | |||||
} | |||||
/** | |||||
* Read BlipPNG record. Holds raw PNG image data | |||||
*/ | |||||
private function readBlipPNG() | |||||
{ | |||||
// offset: 0; size: 2; recVer and recInstance | |||||
// bit: 4-15; mask: 0xFFF0; recInstance | |||||
$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
$pos = 0; | |||||
// offset: 0; size: 16; rgbUid1 (MD4 digest of) | |||||
$rgbUid1 = substr($recordData, 0, 16); | |||||
$pos += 16; | |||||
// offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3 | |||||
if ($recInstance == 0x06E1) { | |||||
$rgbUid2 = substr($recordData, 16, 16); | |||||
$pos += 16; | |||||
} | |||||
// offset: var; size: 1; tag | |||||
$tag = ord($recordData{$pos}); | |||||
$pos += 1; | |||||
// offset: var; size: var; the raw image data | |||||
$data = substr($recordData, $pos); | |||||
$blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); | |||||
$blip->setData($data); | |||||
$this->object->setBlip($blip); | |||||
} | |||||
/** | |||||
* Read OPT record. This record may occur within DggContainer record or SpContainer | |||||
*/ | |||||
private function readOPT() | |||||
{ | |||||
// offset: 0; size: 2; recVer and recInstance | |||||
// bit: 4-15; mask: 0xFFF0; recInstance | |||||
$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
$this->readOfficeArtRGFOPTE($recordData, $recInstance); | |||||
} | |||||
/** | |||||
* Read TertiaryOPT record | |||||
*/ | |||||
private function readTertiaryOPT() | |||||
{ | |||||
// offset: 0; size: 2; recVer and recInstance | |||||
// bit: 4-15; mask: 0xFFF0; recInstance | |||||
$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read SplitMenuColors record | |||||
*/ | |||||
private function readSplitMenuColors() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read DgContainer record (Drawing Container) | |||||
*/ | |||||
private function readDgContainer() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
// record is a container, read contents | |||||
$dgContainer = new PHPExcel_Shared_Escher_DgContainer(); | |||||
$this->object->setDgContainer($dgContainer); | |||||
$reader = new PHPExcel_Reader_Excel5_Escher($dgContainer); | |||||
$escher = $reader->load($recordData); | |||||
} | |||||
/** | |||||
* Read Dg record (Drawing) | |||||
*/ | |||||
private function readDg() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read SpgrContainer record (Shape Group Container) | |||||
*/ | |||||
private function readSpgrContainer() | |||||
{ | |||||
// context is either context DgContainer or SpgrContainer | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
// record is a container, read contents | |||||
$spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer(); | |||||
if ($this->object instanceof PHPExcel_Shared_Escher_DgContainer) { | |||||
// DgContainer | |||||
$this->object->setSpgrContainer($spgrContainer); | |||||
} else { | |||||
// SpgrContainer | |||||
$this->object->addChild($spgrContainer); | |||||
} | |||||
$reader = new PHPExcel_Reader_Excel5_Escher($spgrContainer); | |||||
$escher = $reader->load($recordData); | |||||
} | |||||
/** | |||||
* Read SpContainer record (Shape Container) | |||||
*/ | |||||
private function readSpContainer() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// add spContainer to spgrContainer | |||||
$spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); | |||||
$this->object->addChild($spContainer); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
// record is a container, read contents | |||||
$reader = new PHPExcel_Reader_Excel5_Escher($spContainer); | |||||
$escher = $reader->load($recordData); | |||||
} | |||||
/** | |||||
* Read Spgr record (Shape Group) | |||||
*/ | |||||
private function readSpgr() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read Sp record (Shape) | |||||
*/ | |||||
private function readSp() | |||||
{ | |||||
// offset: 0; size: 2; recVer and recInstance | |||||
// bit: 4-15; mask: 0xFFF0; recInstance | |||||
$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read ClientTextbox record | |||||
*/ | |||||
private function readClientTextbox() | |||||
{ | |||||
// offset: 0; size: 2; recVer and recInstance | |||||
// bit: 4-15; mask: 0xFFF0; recInstance | |||||
$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::getInt2d($this->data, $this->pos)) >> 4; | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read ClientAnchor record. This record holds information about where the shape is anchored in worksheet | |||||
*/ | |||||
private function readClientAnchor() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
// offset: 2; size: 2; upper-left corner column index (0-based) | |||||
$c1 = PHPExcel_Reader_Excel5::getInt2d($recordData, 2); | |||||
// offset: 4; size: 2; upper-left corner horizontal offset in 1/1024 of column width | |||||
$startOffsetX = PHPExcel_Reader_Excel5::getInt2d($recordData, 4); | |||||
// offset: 6; size: 2; upper-left corner row index (0-based) | |||||
$r1 = PHPExcel_Reader_Excel5::getInt2d($recordData, 6); | |||||
// offset: 8; size: 2; upper-left corner vertical offset in 1/256 of row height | |||||
$startOffsetY = PHPExcel_Reader_Excel5::getInt2d($recordData, 8); | |||||
// offset: 10; size: 2; bottom-right corner column index (0-based) | |||||
$c2 = PHPExcel_Reader_Excel5::getInt2d($recordData, 10); | |||||
// offset: 12; size: 2; bottom-right corner horizontal offset in 1/1024 of column width | |||||
$endOffsetX = PHPExcel_Reader_Excel5::getInt2d($recordData, 12); | |||||
// offset: 14; size: 2; bottom-right corner row index (0-based) | |||||
$r2 = PHPExcel_Reader_Excel5::getInt2d($recordData, 14); | |||||
// offset: 16; size: 2; bottom-right corner vertical offset in 1/256 of row height | |||||
$endOffsetY = PHPExcel_Reader_Excel5::getInt2d($recordData, 16); | |||||
// set the start coordinates | |||||
$this->object->setStartCoordinates(PHPExcel_Cell::stringFromColumnIndex($c1) . ($r1 + 1)); | |||||
// set the start offsetX | |||||
$this->object->setStartOffsetX($startOffsetX); | |||||
// set the start offsetY | |||||
$this->object->setStartOffsetY($startOffsetY); | |||||
// set the end coordinates | |||||
$this->object->setEndCoordinates(PHPExcel_Cell::stringFromColumnIndex($c2) . ($r2 + 1)); | |||||
// set the end offsetX | |||||
$this->object->setEndOffsetX($endOffsetX); | |||||
// set the end offsetY | |||||
$this->object->setEndOffsetY($endOffsetY); | |||||
} | |||||
/** | |||||
* Read ClientData record | |||||
*/ | |||||
private function readClientData() | |||||
{ | |||||
$length = PHPExcel_Reader_Excel5::getInt4d($this->data, $this->pos + 4); | |||||
$recordData = substr($this->data, $this->pos + 8, $length); | |||||
// move stream pointer to next record | |||||
$this->pos += 8 + $length; | |||||
} | |||||
/** | |||||
* Read OfficeArtRGFOPTE table of property-value pairs | |||||
* | |||||
* @param string $data Binary data | |||||
* @param int $n Number of properties | |||||
*/ | |||||
private function readOfficeArtRGFOPTE($data, $n) | |||||
{ | |||||
$splicedComplexData = substr($data, 6 * $n); | |||||
// loop through property-value pairs | |||||
for ($i = 0; $i < $n; ++$i) { | |||||
// read 6 bytes at a time | |||||
$fopte = substr($data, 6 * $i, 6); | |||||
// offset: 0; size: 2; opid | |||||
$opid = PHPExcel_Reader_Excel5::getInt2d($fopte, 0); | |||||
// bit: 0-13; mask: 0x3FFF; opid.opid | |||||
$opidOpid = (0x3FFF & $opid) >> 0; | |||||
// bit: 14; mask 0x4000; 1 = value in op field is BLIP identifier | |||||
$opidFBid = (0x4000 & $opid) >> 14; | |||||
// bit: 15; mask 0x8000; 1 = this is a complex property, op field specifies size of complex data | |||||
$opidFComplex = (0x8000 & $opid) >> 15; | |||||
// offset: 2; size: 4; the value for this property | |||||
$op = PHPExcel_Reader_Excel5::getInt4d($fopte, 2); | |||||
if ($opidFComplex) { | |||||
$complexData = substr($splicedComplexData, 0, $op); | |||||
$splicedComplexData = substr($splicedComplexData, $op); | |||||
// we store string value with complex data | |||||
$value = $complexData; | |||||
} else { | |||||
// we store integer value | |||||
$value = $op; | |||||
} | |||||
$this->object->setOPT($opidOpid, $value); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,203 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Reader_Excel5_MD5 | |||||
* | |||||
* 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_Reader_Excel5 | |||||
* @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_Reader_Excel5_MD5 | |||||
{ | |||||
// Context | |||||
private $a; | |||||
private $b; | |||||
private $c; | |||||
private $d; | |||||
/** | |||||
* MD5 stream constructor | |||||
*/ | |||||
public function __construct() | |||||
{ | |||||
$this->reset(); | |||||
} | |||||
/** | |||||
* Reset the MD5 stream context | |||||
*/ | |||||
public function reset() | |||||
{ | |||||
$this->a = 0x67452301; | |||||
$this->b = 0xEFCDAB89; | |||||
$this->c = 0x98BADCFE; | |||||
$this->d = 0x10325476; | |||||
} | |||||
/** | |||||
* Get MD5 stream context | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function getContext() | |||||
{ | |||||
$s = ''; | |||||
foreach (array('a', 'b', 'c', 'd') as $i) { | |||||
$v = $this->{$i}; | |||||
$s .= chr($v & 0xff); | |||||
$s .= chr(($v >> 8) & 0xff); | |||||
$s .= chr(($v >> 16) & 0xff); | |||||
$s .= chr(($v >> 24) & 0xff); | |||||
} | |||||
return $s; | |||||
} | |||||
/** | |||||
* Add data to context | |||||
* | |||||
* @param string $data Data to add | |||||
*/ | |||||
public function add($data) | |||||
{ | |||||
$words = array_values(unpack('V16', $data)); | |||||
$A = $this->a; | |||||
$B = $this->b; | |||||
$C = $this->c; | |||||
$D = $this->d; | |||||
$F = array('PHPExcel_Reader_Excel5_MD5','f'); | |||||
$G = array('PHPExcel_Reader_Excel5_MD5','g'); | |||||
$H = array('PHPExcel_Reader_Excel5_MD5','h'); | |||||
$I = array('PHPExcel_Reader_Excel5_MD5','i'); | |||||
/* ROUND 1 */ | |||||
self::step($F, $A, $B, $C, $D, $words[0], 7, 0xd76aa478); | |||||
self::step($F, $D, $A, $B, $C, $words[1], 12, 0xe8c7b756); | |||||
self::step($F, $C, $D, $A, $B, $words[2], 17, 0x242070db); | |||||
self::step($F, $B, $C, $D, $A, $words[3], 22, 0xc1bdceee); | |||||
self::step($F, $A, $B, $C, $D, $words[4], 7, 0xf57c0faf); | |||||
self::step($F, $D, $A, $B, $C, $words[5], 12, 0x4787c62a); | |||||
self::step($F, $C, $D, $A, $B, $words[6], 17, 0xa8304613); | |||||
self::step($F, $B, $C, $D, $A, $words[7], 22, 0xfd469501); | |||||
self::step($F, $A, $B, $C, $D, $words[8], 7, 0x698098d8); | |||||
self::step($F, $D, $A, $B, $C, $words[9], 12, 0x8b44f7af); | |||||
self::step($F, $C, $D, $A, $B, $words[10], 17, 0xffff5bb1); | |||||
self::step($F, $B, $C, $D, $A, $words[11], 22, 0x895cd7be); | |||||
self::step($F, $A, $B, $C, $D, $words[12], 7, 0x6b901122); | |||||
self::step($F, $D, $A, $B, $C, $words[13], 12, 0xfd987193); | |||||
self::step($F, $C, $D, $A, $B, $words[14], 17, 0xa679438e); | |||||
self::step($F, $B, $C, $D, $A, $words[15], 22, 0x49b40821); | |||||
/* ROUND 2 */ | |||||
self::step($G, $A, $B, $C, $D, $words[1], 5, 0xf61e2562); | |||||
self::step($G, $D, $A, $B, $C, $words[6], 9, 0xc040b340); | |||||
self::step($G, $C, $D, $A, $B, $words[11], 14, 0x265e5a51); | |||||
self::step($G, $B, $C, $D, $A, $words[0], 20, 0xe9b6c7aa); | |||||
self::step($G, $A, $B, $C, $D, $words[5], 5, 0xd62f105d); | |||||
self::step($G, $D, $A, $B, $C, $words[10], 9, 0x02441453); | |||||
self::step($G, $C, $D, $A, $B, $words[15], 14, 0xd8a1e681); | |||||
self::step($G, $B, $C, $D, $A, $words[4], 20, 0xe7d3fbc8); | |||||
self::step($G, $A, $B, $C, $D, $words[9], 5, 0x21e1cde6); | |||||
self::step($G, $D, $A, $B, $C, $words[14], 9, 0xc33707d6); | |||||
self::step($G, $C, $D, $A, $B, $words[3], 14, 0xf4d50d87); | |||||
self::step($G, $B, $C, $D, $A, $words[8], 20, 0x455a14ed); | |||||
self::step($G, $A, $B, $C, $D, $words[13], 5, 0xa9e3e905); | |||||
self::step($G, $D, $A, $B, $C, $words[2], 9, 0xfcefa3f8); | |||||
self::step($G, $C, $D, $A, $B, $words[7], 14, 0x676f02d9); | |||||
self::step($G, $B, $C, $D, $A, $words[12], 20, 0x8d2a4c8a); | |||||
/* ROUND 3 */ | |||||
self::step($H, $A, $B, $C, $D, $words[5], 4, 0xfffa3942); | |||||
self::step($H, $D, $A, $B, $C, $words[8], 11, 0x8771f681); | |||||
self::step($H, $C, $D, $A, $B, $words[11], 16, 0x6d9d6122); | |||||
self::step($H, $B, $C, $D, $A, $words[14], 23, 0xfde5380c); | |||||
self::step($H, $A, $B, $C, $D, $words[1], 4, 0xa4beea44); | |||||
self::step($H, $D, $A, $B, $C, $words[4], 11, 0x4bdecfa9); | |||||
self::step($H, $C, $D, $A, $B, $words[7], 16, 0xf6bb4b60); | |||||
self::step($H, $B, $C, $D, $A, $words[10], 23, 0xbebfbc70); | |||||
self::step($H, $A, $B, $C, $D, $words[13], 4, 0x289b7ec6); | |||||
self::step($H, $D, $A, $B, $C, $words[0], 11, 0xeaa127fa); | |||||
self::step($H, $C, $D, $A, $B, $words[3], 16, 0xd4ef3085); | |||||
self::step($H, $B, $C, $D, $A, $words[6], 23, 0x04881d05); | |||||
self::step($H, $A, $B, $C, $D, $words[9], 4, 0xd9d4d039); | |||||
self::step($H, $D, $A, $B, $C, $words[12], 11, 0xe6db99e5); | |||||
self::step($H, $C, $D, $A, $B, $words[15], 16, 0x1fa27cf8); | |||||
self::step($H, $B, $C, $D, $A, $words[2], 23, 0xc4ac5665); | |||||
/* ROUND 4 */ | |||||
self::step($I, $A, $B, $C, $D, $words[0], 6, 0xf4292244); | |||||
self::step($I, $D, $A, $B, $C, $words[7], 10, 0x432aff97); | |||||
self::step($I, $C, $D, $A, $B, $words[14], 15, 0xab9423a7); | |||||
self::step($I, $B, $C, $D, $A, $words[5], 21, 0xfc93a039); | |||||
self::step($I, $A, $B, $C, $D, $words[12], 6, 0x655b59c3); | |||||
self::step($I, $D, $A, $B, $C, $words[3], 10, 0x8f0ccc92); | |||||
self::step($I, $C, $D, $A, $B, $words[10], 15, 0xffeff47d); | |||||
self::step($I, $B, $C, $D, $A, $words[1], 21, 0x85845dd1); | |||||
self::step($I, $A, $B, $C, $D, $words[8], 6, 0x6fa87e4f); | |||||
self::step($I, $D, $A, $B, $C, $words[15], 10, 0xfe2ce6e0); | |||||
self::step($I, $C, $D, $A, $B, $words[6], 15, 0xa3014314); | |||||
self::step($I, $B, $C, $D, $A, $words[13], 21, 0x4e0811a1); | |||||
self::step($I, $A, $B, $C, $D, $words[4], 6, 0xf7537e82); | |||||
self::step($I, $D, $A, $B, $C, $words[11], 10, 0xbd3af235); | |||||
self::step($I, $C, $D, $A, $B, $words[2], 15, 0x2ad7d2bb); | |||||
self::step($I, $B, $C, $D, $A, $words[9], 21, 0xeb86d391); | |||||
$this->a = ($this->a + $A) & 0xffffffff; | |||||
$this->b = ($this->b + $B) & 0xffffffff; | |||||
$this->c = ($this->c + $C) & 0xffffffff; | |||||
$this->d = ($this->d + $D) & 0xffffffff; | |||||
} | |||||
private static function f($X, $Y, $Z) | |||||
{ | |||||
return (($X & $Y) | ((~ $X) & $Z)); // X AND Y OR NOT X AND Z | |||||
} | |||||
private static function g($X, $Y, $Z) | |||||
{ | |||||
return (($X & $Z) | ($Y & (~ $Z))); // X AND Z OR Y AND NOT Z | |||||
} | |||||
private static function h($X, $Y, $Z) | |||||
{ | |||||
return ($X ^ $Y ^ $Z); // X XOR Y XOR Z | |||||
} | |||||
private static function i($X, $Y, $Z) | |||||
{ | |||||
return ($Y ^ ($X | (~ $Z))) ; // Y XOR (X OR NOT Z) | |||||
} | |||||
private static function step($func, &$A, $B, $C, $D, $M, $s, $t) | |||||
{ | |||||
$A = ($A + call_user_func($func, $B, $C, $D) + $M + $t) & 0xffffffff; | |||||
$A = self::rotate($A, $s); | |||||
$A = ($B + $A) & 0xffffffff; | |||||
} | |||||
private static function rotate($decimal, $bits) | |||||
{ | |||||
$binary = str_pad(decbin($decimal), 32, "0", STR_PAD_LEFT); | |||||
return bindec(substr($binary, $bits).substr($binary, 0, $bits)); | |||||
} | |||||
} |
@ -0,0 +1,81 @@ | |||||
<?php | |||||
/** | |||||
* PHPExcel_Reader_Excel5_RC4 | |||||
* | |||||
* 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_Reader_Excel5 | |||||
* @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_Reader_Excel5_RC4 | |||||
{ | |||||
// Context | |||||
protected $s = array(); | |||||
protected $i = 0; | |||||
protected $j = 0; | |||||
/** | |||||
* RC4 stream decryption/encryption constrcutor | |||||
* | |||||
* @param string $key Encryption key/passphrase | |||||
*/ | |||||
public function __construct($key) | |||||
{ | |||||
$len = strlen($key); | |||||
for ($this->i = 0; $this->i < 256; $this->i++) { | |||||
$this->s[$this->i] = $this->i; | |||||
} | |||||
$this->j = 0; | |||||
for ($this->i = 0; $this->i < 256; $this->i++) { | |||||
$this->j = ($this->j + $this->s[$this->i] + ord($key[$this->i % $len])) % 256; | |||||
$t = $this->s[$this->i]; | |||||
$this->s[$this->i] = $this->s[$this->j]; | |||||
$this->s[$this->j] = $t; | |||||
} | |||||
$this->i = $this->j = 0; | |||||
} | |||||
/** | |||||
* Symmetric decryption/encryption function | |||||
* | |||||
* @param string $data Data to encrypt/decrypt | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function RC4($data) | |||||
{ | |||||
$len = strlen($data); | |||||
for ($c = 0; $c < $len; $c++) { | |||||
$this->i = ($this->i + 1) % 256; | |||||
$this->j = ($this->j + $this->s[$this->i]) % 256; | |||||
$t = $this->s[$this->i]; | |||||
$this->s[$this->i] = $this->s[$this->j]; | |||||
$this->s[$this->j] = $t; | |||||
$t = ($this->s[$this->i] + $this->s[$this->j]) % 256; | |||||
$data[$c] = chr(ord($data[$c]) ^ $this->s[$t]); | |||||
} | |||||
return $data; | |||||
} | |||||
} |
@ -0,0 +1,36 @@ | |||||
<?php | |||||
class PHPExcel_Reader_Excel5_Style_Border | |||||
{ | |||||
protected static $map = array( | |||||
0x00 => PHPExcel_Style_Border::BORDER_NONE, | |||||
0x01 => PHPExcel_Style_Border::BORDER_THIN, | |||||
0x02 => PHPExcel_Style_Border::BORDER_MEDIUM, | |||||
0x03 => PHPExcel_Style_Border::BORDER_DASHED, | |||||
0x04 => PHPExcel_Style_Border::BORDER_DOTTED, | |||||
0x05 => PHPExcel_Style_Border::BORDER_THICK, | |||||
0x06 => PHPExcel_Style_Border::BORDER_DOUBLE, | |||||
0x07 => PHPExcel_Style_Border::BORDER_HAIR, | |||||
0x08 => PHPExcel_Style_Border::BORDER_MEDIUMDASHED, | |||||
0x09 => PHPExcel_Style_Border::BORDER_DASHDOT, | |||||
0x0A => PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT, | |||||
0x0B => PHPExcel_Style_Border::BORDER_DASHDOTDOT, | |||||
0x0C => PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT, | |||||
0x0D => PHPExcel_Style_Border::BORDER_SLANTDASHDOT, | |||||
); | |||||
/** | |||||
* Map border style | |||||
* OpenOffice documentation: 2.5.11 | |||||
* | |||||
* @param int $index | |||||
* @return string | |||||
*/ | |||||
public static function lookup($index) | |||||
{ | |||||
if (isset(self::$map[$index])) { | |||||
return self::$map[$index]; | |||||
} | |||||
return PHPExcel_Style_Border::BORDER_NONE; | |||||
} | |||||
} |
@ -0,0 +1,41 @@ | |||||
<?php | |||||
class PHPExcel_Reader_Excel5_Style_FillPattern | |||||
{ | |||||
protected static $map = array( | |||||
0x00 => PHPExcel_Style_Fill::FILL_NONE, | |||||
0x01 => PHPExcel_Style_Fill::FILL_SOLID, | |||||
0x02 => PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY, | |||||
0x03 => PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY, | |||||
0x04 => PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY, | |||||
0x05 => PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL, | |||||
0x06 => PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL, | |||||
0x07 => PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN, | |||||
0x08 => PHPExcel_Style_Fill::FILL_PATTERN_DARKUP, | |||||
0x09 => PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID, | |||||
0x0A => PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS, | |||||
0x0B => PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL, | |||||
0x0C => PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL, | |||||
0x0D => PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN, | |||||
0x0E => PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP, | |||||
0x0F => PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID, | |||||
0x10 => PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS, | |||||
0x11 => PHPExcel_Style_Fill::FILL_PATTERN_GRAY125, | |||||
0x12 => PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625, | |||||
); | |||||
/** | |||||
* Get fill pattern from index | |||||
* OpenOffice documentation: 2.5.12 | |||||
* | |||||
* @param int $index | |||||
* @return string | |||||
*/ | |||||
public static function lookup($index) | |||||
{ | |||||
if (isset(self::$map[$index])) { | |||||
return self::$map[$index]; | |||||
} | |||||
return PHPExcel_Style_Fill::FILL_NONE; | |||||
} | |||||
} |