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