| @ -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; | |||||
| } | |||||
| } | |||||