MDL-45893 user_menu: revised based on action_menu
[moodle.git] / lib / phpexcel / PHPExcel.php
blobe01581a243d8ddb5028f5e3e7ec6462b851df649
1 <?php
2 /**
3 * PHPExcel
5 * Copyright (c) 2006 - 2014 PHPExcel
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * @category PHPExcel
22 * @package PHPExcel
23 * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
24 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
25 * @version ##VERSION##, ##DATE##
29 /** PHPExcel root directory */
30 if (!defined('PHPEXCEL_ROOT')) {
31 define('PHPEXCEL_ROOT', dirname(__FILE__) . '/');
32 require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
36 /**
37 * PHPExcel
39 * @category PHPExcel
40 * @package PHPExcel
41 * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
43 class PHPExcel
45 /**
46 * Unique ID
48 * @var string
50 private $_uniqueID;
52 /**
53 * Document properties
55 * @var PHPExcel_DocumentProperties
57 private $_properties;
59 /**
60 * Document security
62 * @var PHPExcel_DocumentSecurity
64 private $_security;
66 /**
67 * Collection of Worksheet objects
69 * @var PHPExcel_Worksheet[]
71 private $_workSheetCollection = array();
73 /**
74 * Calculation Engine
76 * @var PHPExcel_Calculation
78 private $_calculationEngine = NULL;
80 /**
81 * Active sheet index
83 * @var int
85 private $_activeSheetIndex = 0;
87 /**
88 * Named ranges
90 * @var PHPExcel_NamedRange[]
92 private $_namedRanges = array();
94 /**
95 * CellXf supervisor
97 * @var PHPExcel_Style
99 private $_cellXfSupervisor;
102 * CellXf collection
104 * @var PHPExcel_Style[]
106 private $_cellXfCollection = array();
109 * CellStyleXf collection
111 * @var PHPExcel_Style[]
113 private $_cellStyleXfCollection = array();
116 * _hasMacros : this workbook have macros ?
118 * @var bool
120 private $_hasMacros = FALSE;
123 * _macrosCode : all macros code (the vbaProject.bin file, this include form, code, etc.), NULL if no macro
125 * @var binary
127 private $_macrosCode=NULL;
129 * _macrosCertificate : if macros are signed, contains vbaProjectSignature.bin file, NULL if not signed
131 * @var binary
133 private $_macrosCertificate=NULL;
136 * _ribbonXMLData : NULL if workbook is'nt Excel 2007 or not contain a customized UI
138 * @var NULL|string
140 private $_ribbonXMLData=NULL;
143 * _ribbonBinObjects : NULL if workbook is'nt Excel 2007 or not contain embedded objects (picture(s)) for Ribbon Elements
144 * ignored if $_ribbonXMLData is null
146 * @var NULL|array
148 private $_ribbonBinObjects=NULL;
151 * The workbook has macros ?
153 * @return true if workbook has macros, false if not
155 public function hasMacros(){
156 return $this->_hasMacros;
160 * Define if a workbook has macros
162 * @param true|false
164 public function setHasMacros($hasMacros=false){
165 $this->_hasMacros=(bool)$hasMacros;
169 * Set the macros code
171 * @param binary string|null
173 public function setMacrosCode($MacrosCode){
174 $this->_macrosCode=$MacrosCode;
175 $this->setHasMacros(!is_null($MacrosCode));
179 * Return the macros code
181 * @return binary|null
183 public function getMacrosCode(){
184 return $this->_macrosCode;
188 * Set the macros certificate
190 * @param binary|null
192 public function setMacrosCertificate($Certificate=NULL){
193 $this->_macrosCertificate=$Certificate;
197 * Is the project signed ?
199 * @return true|false
201 public function hasMacrosCertificate(){
202 return !is_null($this->_macrosCertificate);
206 * Return the macros certificate
208 * @return binary|null
210 public function getMacrosCertificate(){
211 return $this->_macrosCertificate;
215 * Remove all macros, certificate from spreadsheet
217 * @param none
218 * @return void
220 public function discardMacros(){
221 $this->_hasMacros=false;
222 $this->_macrosCode=NULL;
223 $this->_macrosCertificate=NULL;
227 * set ribbon XML data
230 public function setRibbonXMLData($Target=NULL, $XMLData=NULL){
231 if(!is_null($Target) && !is_null($XMLData)){
232 $this->_ribbonXMLData=array('target'=>$Target, 'data'=>$XMLData);
233 }else{
234 $this->_ribbonXMLData=NULL;
239 * retrieve ribbon XML Data
241 * return string|null|array
243 public function getRibbonXMLData($What='all'){//we need some constants here...
244 $ReturnData=NULL;
245 $What=strtolower($What);
246 switch($What){
247 case 'all':
248 $ReturnData=$this->_ribbonXMLData;
249 break;
250 case 'target':
251 case 'data':
252 if(is_array($this->_ribbonXMLData) && array_key_exists($What,$this->_ribbonXMLData)){
253 $ReturnData=$this->_ribbonXMLData[$What];
254 }//else $ReturnData stay at null
255 break;
256 }//default: $ReturnData at null
257 return $ReturnData;
261 * store binaries ribbon objects (pictures)
264 public function setRibbonBinObjects($BinObjectsNames=NULL, $BinObjectsData=NULL){
265 if(!is_null($BinObjectsNames) && !is_null($BinObjectsData)){
266 $this->_ribbonBinObjects=array('names'=>$BinObjectsNames, 'data'=>$BinObjectsData);
267 }else{
268 $this->_ribbonBinObjects=NULL;
272 * return the extension of a filename. Internal use for a array_map callback (php<5.3 don't like lambda function)
275 private function _getExtensionOnly($ThePath){
276 return pathinfo($ThePath, PATHINFO_EXTENSION);
280 * retrieve Binaries Ribbon Objects
283 public function getRibbonBinObjects($What='all'){
284 $ReturnData=NULL;
285 $What=strtolower($What);
286 switch($What){
287 case 'all':
288 return $this->_ribbonBinObjects;
289 break;
290 case 'names':
291 case 'data':
292 if(is_array($this->_ribbonBinObjects) && array_key_exists($What, $this->_ribbonBinObjects)){
293 $ReturnData=$this->_ribbonBinObjects[$What];
295 break;
296 case 'types':
297 if(is_array($this->_ribbonBinObjects) && array_key_exists('data', $this->_ribbonBinObjects) && is_array($this->_ribbonBinObjects['data'])){
298 $tmpTypes=array_keys($this->_ribbonBinObjects['data']);
299 $ReturnData=array_unique(array_map(array($this,'_getExtensionOnly'), $tmpTypes));
300 }else
301 $ReturnData=array();//the caller want an array... not null if empty
302 break;
304 return $ReturnData;
308 * This workbook have a custom UI ?
310 * @return true|false
312 public function hasRibbon(){
313 return !is_null($this->_ribbonXMLData);
317 * This workbook have additionnal object for the ribbon ?
319 * @return true|false
321 public function hasRibbonBinObjects(){
322 return !is_null($this->_ribbonBinObjects);
326 * Check if a sheet with a specified code name already exists
328 * @param string $pSheetCodeName Name of the worksheet to check
329 * @return boolean
331 public function sheetCodeNameExists($pSheetCodeName)
333 return ($this->getSheetByCodeName($pSheetCodeName) !== NULL);
337 * Get sheet by code name. Warning : sheet don't have always a code name !
339 * @param string $pName Sheet name
340 * @return PHPExcel_Worksheet
342 public function getSheetByCodeName($pName = '')
344 $worksheetCount = count($this->_workSheetCollection);
345 for ($i = 0; $i < $worksheetCount; ++$i) {
346 if ($this->_workSheetCollection[$i]->getCodeName() == $pName) {
347 return $this->_workSheetCollection[$i];
351 return null;
355 * Create a new PHPExcel with one Worksheet
357 public function __construct()
359 $this->_uniqueID = uniqid();
360 $this->_calculationEngine = PHPExcel_Calculation::getInstance($this);
362 // Initialise worksheet collection and add one worksheet
363 $this->_workSheetCollection = array();
364 $this->_workSheetCollection[] = new PHPExcel_Worksheet($this);
365 $this->_activeSheetIndex = 0;
367 // Create document properties
368 $this->_properties = new PHPExcel_DocumentProperties();
370 // Create document security
371 $this->_security = new PHPExcel_DocumentSecurity();
373 // Set named ranges
374 $this->_namedRanges = array();
376 // Create the cellXf supervisor
377 $this->_cellXfSupervisor = new PHPExcel_Style(true);
378 $this->_cellXfSupervisor->bindParent($this);
380 // Create the default style
381 $this->addCellXf(new PHPExcel_Style);
382 $this->addCellStyleXf(new PHPExcel_Style);
386 * Code to execute when this worksheet is unset()
389 public function __destruct() {
390 PHPExcel_Calculation::unsetInstance($this);
391 $this->disconnectWorksheets();
392 } // function __destruct()
395 * Disconnect all worksheets from this PHPExcel workbook object,
396 * typically so that the PHPExcel object can be unset
399 public function disconnectWorksheets()
401 $worksheet = NULL;
402 foreach($this->_workSheetCollection as $k => &$worksheet) {
403 $worksheet->disconnectCells();
404 $this->_workSheetCollection[$k] = null;
406 unset($worksheet);
407 $this->_workSheetCollection = array();
411 * Return the calculation engine for this worksheet
413 * @return PHPExcel_Calculation
415 public function getCalculationEngine()
417 return $this->_calculationEngine;
418 } // function getCellCacheController()
421 * Get properties
423 * @return PHPExcel_DocumentProperties
425 public function getProperties()
427 return $this->_properties;
431 * Set properties
433 * @param PHPExcel_DocumentProperties $pValue
435 public function setProperties(PHPExcel_DocumentProperties $pValue)
437 $this->_properties = $pValue;
441 * Get security
443 * @return PHPExcel_DocumentSecurity
445 public function getSecurity()
447 return $this->_security;
451 * Set security
453 * @param PHPExcel_DocumentSecurity $pValue
455 public function setSecurity(PHPExcel_DocumentSecurity $pValue)
457 $this->_security = $pValue;
461 * Get active sheet
463 * @return PHPExcel_Worksheet
465 public function getActiveSheet()
467 return $this->_workSheetCollection[$this->_activeSheetIndex];
471 * Create sheet and add it to this workbook
473 * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last)
474 * @return PHPExcel_Worksheet
475 * @throws PHPExcel_Exception
477 public function createSheet($iSheetIndex = NULL)
479 $newSheet = new PHPExcel_Worksheet($this);
480 $this->addSheet($newSheet, $iSheetIndex);
481 return $newSheet;
485 * Check if a sheet with a specified name already exists
487 * @param string $pSheetName Name of the worksheet to check
488 * @return boolean
490 public function sheetNameExists($pSheetName)
492 return ($this->getSheetByName($pSheetName) !== NULL);
496 * Add sheet
498 * @param PHPExcel_Worksheet $pSheet
499 * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last)
500 * @return PHPExcel_Worksheet
501 * @throws PHPExcel_Exception
503 public function addSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = NULL)
505 if ($this->sheetNameExists($pSheet->getTitle())) {
506 throw new PHPExcel_Exception(
507 "Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename this worksheet first."
511 if($iSheetIndex === NULL) {
512 if ($this->_activeSheetIndex < 0) {
513 $this->_activeSheetIndex = 0;
515 $this->_workSheetCollection[] = $pSheet;
516 } else {
517 // Insert the sheet at the requested index
518 array_splice(
519 $this->_workSheetCollection,
520 $iSheetIndex,
522 array($pSheet)
525 // Adjust active sheet index if necessary
526 if ($this->_activeSheetIndex >= $iSheetIndex) {
527 ++$this->_activeSheetIndex;
531 if ($pSheet->getParent() === null) {
532 $pSheet->rebindParent($this);
535 return $pSheet;
539 * Remove sheet by index
541 * @param int $pIndex Active sheet index
542 * @throws PHPExcel_Exception
544 public function removeSheetByIndex($pIndex = 0)
547 $numSheets = count($this->_workSheetCollection);
549 if ($pIndex > $numSheets - 1) {
550 throw new PHPExcel_Exception(
551 "You tried to remove a sheet by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}."
553 } else {
554 array_splice($this->_workSheetCollection, $pIndex, 1);
556 // Adjust active sheet index if necessary
557 if (($this->_activeSheetIndex >= $pIndex) &&
558 ($pIndex > count($this->_workSheetCollection) - 1)) {
559 --$this->_activeSheetIndex;
565 * Get sheet by index
567 * @param int $pIndex Sheet index
568 * @return PHPExcel_Worksheet
569 * @throws PHPExcel_Exception
571 public function getSheet($pIndex = 0)
574 $numSheets = count($this->_workSheetCollection);
576 if ($pIndex > $numSheets - 1) {
577 throw new PHPExcel_Exception(
578 "Your requested sheet index: {$pIndex} is out of bounds. The actual number of sheets is {$numSheets}."
580 } else {
581 return $this->_workSheetCollection[$pIndex];
586 * Get all sheets
588 * @return PHPExcel_Worksheet[]
590 public function getAllSheets()
592 return $this->_workSheetCollection;
596 * Get sheet by name
598 * @param string $pName Sheet name
599 * @return PHPExcel_Worksheet
601 public function getSheetByName($pName = '')
603 $worksheetCount = count($this->_workSheetCollection);
604 for ($i = 0; $i < $worksheetCount; ++$i) {
605 if ($this->_workSheetCollection[$i]->getTitle() === $pName) {
606 return $this->_workSheetCollection[$i];
610 return NULL;
614 * Get index for sheet
616 * @param PHPExcel_Worksheet $pSheet
617 * @return Sheet index
618 * @throws PHPExcel_Exception
620 public function getIndex(PHPExcel_Worksheet $pSheet)
622 foreach ($this->_workSheetCollection as $key => $value) {
623 if ($value->getHashCode() == $pSheet->getHashCode()) {
624 return $key;
628 throw new PHPExcel_Exception("Sheet does not exist.");
632 * Set index for sheet by sheet name.
634 * @param string $sheetName Sheet name to modify index for
635 * @param int $newIndex New index for the sheet
636 * @return New sheet index
637 * @throws PHPExcel_Exception
639 public function setIndexByName($sheetName, $newIndex)
641 $oldIndex = $this->getIndex($this->getSheetByName($sheetName));
642 $pSheet = array_splice(
643 $this->_workSheetCollection,
644 $oldIndex,
647 array_splice(
648 $this->_workSheetCollection,
649 $newIndex,
651 $pSheet
653 return $newIndex;
657 * Get sheet count
659 * @return int
661 public function getSheetCount()
663 return count($this->_workSheetCollection);
667 * Get active sheet index
669 * @return int Active sheet index
671 public function getActiveSheetIndex()
673 return $this->_activeSheetIndex;
677 * Set active sheet index
679 * @param int $pIndex Active sheet index
680 * @throws PHPExcel_Exception
681 * @return PHPExcel_Worksheet
683 public function setActiveSheetIndex($pIndex = 0)
685 $numSheets = count($this->_workSheetCollection);
687 if ($pIndex > $numSheets - 1) {
688 throw new PHPExcel_Exception(
689 "You tried to set a sheet active by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}."
691 } else {
692 $this->_activeSheetIndex = $pIndex;
694 return $this->getActiveSheet();
698 * Set active sheet index by name
700 * @param string $pValue Sheet title
701 * @return PHPExcel_Worksheet
702 * @throws PHPExcel_Exception
704 public function setActiveSheetIndexByName($pValue = '')
706 if (($worksheet = $this->getSheetByName($pValue)) instanceof PHPExcel_Worksheet) {
707 $this->setActiveSheetIndex($this->getIndex($worksheet));
708 return $worksheet;
711 throw new PHPExcel_Exception('Workbook does not contain sheet:' . $pValue);
715 * Get sheet names
717 * @return string[]
719 public function getSheetNames()
721 $returnValue = array();
722 $worksheetCount = $this->getSheetCount();
723 for ($i = 0; $i < $worksheetCount; ++$i) {
724 $returnValue[] = $this->getSheet($i)->getTitle();
727 return $returnValue;
731 * Add external sheet
733 * @param PHPExcel_Worksheet $pSheet External sheet to add
734 * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last)
735 * @throws PHPExcel_Exception
736 * @return PHPExcel_Worksheet
738 public function addExternalSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = null) {
739 if ($this->sheetNameExists($pSheet->getTitle())) {
740 throw new PHPExcel_Exception("Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename the external sheet first.");
743 // count how many cellXfs there are in this workbook currently, we will need this below
744 $countCellXfs = count($this->_cellXfCollection);
746 // copy all the shared cellXfs from the external workbook and append them to the current
747 foreach ($pSheet->getParent()->getCellXfCollection() as $cellXf) {
748 $this->addCellXf(clone $cellXf);
751 // move sheet to this workbook
752 $pSheet->rebindParent($this);
754 // update the cellXfs
755 foreach ($pSheet->getCellCollection(false) as $cellID) {
756 $cell = $pSheet->getCell($cellID);
757 $cell->setXfIndex( $cell->getXfIndex() + $countCellXfs );
760 return $this->addSheet($pSheet, $iSheetIndex);
764 * Get named ranges
766 * @return PHPExcel_NamedRange[]
768 public function getNamedRanges() {
769 return $this->_namedRanges;
773 * Add named range
775 * @param PHPExcel_NamedRange $namedRange
776 * @return PHPExcel
778 public function addNamedRange(PHPExcel_NamedRange $namedRange) {
779 if ($namedRange->getScope() == null) {
780 // global scope
781 $this->_namedRanges[$namedRange->getName()] = $namedRange;
782 } else {
783 // local scope
784 $this->_namedRanges[$namedRange->getScope()->getTitle().'!'.$namedRange->getName()] = $namedRange;
786 return true;
790 * Get named range
792 * @param string $namedRange
793 * @param PHPExcel_Worksheet|null $pSheet Scope. Use null for global scope
794 * @return PHPExcel_NamedRange|null
796 public function getNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) {
797 $returnValue = null;
799 if ($namedRange != '' && ($namedRange !== NULL)) {
800 // first look for global defined name
801 if (isset($this->_namedRanges[$namedRange])) {
802 $returnValue = $this->_namedRanges[$namedRange];
805 // then look for local defined name (has priority over global defined name if both names exist)
806 if (($pSheet !== NULL) && isset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange])) {
807 $returnValue = $this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange];
811 return $returnValue;
815 * Remove named range
817 * @param string $namedRange
818 * @param PHPExcel_Worksheet|null $pSheet Scope: use null for global scope.
819 * @return PHPExcel
821 public function removeNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) {
822 if ($pSheet === NULL) {
823 if (isset($this->_namedRanges[$namedRange])) {
824 unset($this->_namedRanges[$namedRange]);
826 } else {
827 if (isset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange])) {
828 unset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange]);
831 return $this;
835 * Get worksheet iterator
837 * @return PHPExcel_WorksheetIterator
839 public function getWorksheetIterator() {
840 return new PHPExcel_WorksheetIterator($this);
844 * Copy workbook (!= clone!)
846 * @return PHPExcel
848 public function copy() {
849 $copied = clone $this;
851 $worksheetCount = count($this->_workSheetCollection);
852 for ($i = 0; $i < $worksheetCount; ++$i) {
853 $this->_workSheetCollection[$i] = $this->_workSheetCollection[$i]->copy();
854 $this->_workSheetCollection[$i]->rebindParent($this);
857 return $copied;
861 * Implement PHP __clone to create a deep clone, not just a shallow copy.
863 public function __clone() {
864 foreach($this as $key => $val) {
865 if (is_object($val) || (is_array($val))) {
866 $this->{$key} = unserialize(serialize($val));
872 * Get the workbook collection of cellXfs
874 * @return PHPExcel_Style[]
876 public function getCellXfCollection()
878 return $this->_cellXfCollection;
882 * Get cellXf by index
884 * @param int $pIndex
885 * @return PHPExcel_Style
887 public function getCellXfByIndex($pIndex = 0)
889 return $this->_cellXfCollection[$pIndex];
893 * Get cellXf by hash code
895 * @param string $pValue
896 * @return PHPExcel_Style|false
898 public function getCellXfByHashCode($pValue = '')
900 foreach ($this->_cellXfCollection as $cellXf) {
901 if ($cellXf->getHashCode() == $pValue) {
902 return $cellXf;
905 return false;
909 * Check if style exists in style collection
911 * @param PHPExcel_Style $pCellStyle
912 * @return boolean
914 public function cellXfExists($pCellStyle = null)
916 return in_array($pCellStyle, $this->_cellXfCollection, true);
920 * Get default style
922 * @return PHPExcel_Style
923 * @throws PHPExcel_Exception
925 public function getDefaultStyle()
927 if (isset($this->_cellXfCollection[0])) {
928 return $this->_cellXfCollection[0];
930 throw new PHPExcel_Exception('No default style found for this workbook');
934 * Add a cellXf to the workbook
936 * @param PHPExcel_Style $style
938 public function addCellXf(PHPExcel_Style $style)
940 $this->_cellXfCollection[] = $style;
941 $style->setIndex(count($this->_cellXfCollection) - 1);
945 * Remove cellXf by index. It is ensured that all cells get their xf index updated.
947 * @param int $pIndex Index to cellXf
948 * @throws PHPExcel_Exception
950 public function removeCellXfByIndex($pIndex = 0)
952 if ($pIndex > count($this->_cellXfCollection) - 1) {
953 throw new PHPExcel_Exception("CellXf index is out of bounds.");
954 } else {
955 // first remove the cellXf
956 array_splice($this->_cellXfCollection, $pIndex, 1);
958 // then update cellXf indexes for cells
959 foreach ($this->_workSheetCollection as $worksheet) {
960 foreach ($worksheet->getCellCollection(false) as $cellID) {
961 $cell = $worksheet->getCell($cellID);
962 $xfIndex = $cell->getXfIndex();
963 if ($xfIndex > $pIndex ) {
964 // decrease xf index by 1
965 $cell->setXfIndex($xfIndex - 1);
966 } else if ($xfIndex == $pIndex) {
967 // set to default xf index 0
968 $cell->setXfIndex(0);
976 * Get the cellXf supervisor
978 * @return PHPExcel_Style
980 public function getCellXfSupervisor()
982 return $this->_cellXfSupervisor;
986 * Get the workbook collection of cellStyleXfs
988 * @return PHPExcel_Style[]
990 public function getCellStyleXfCollection()
992 return $this->_cellStyleXfCollection;
996 * Get cellStyleXf by index
998 * @param int $pIndex
999 * @return PHPExcel_Style
1001 public function getCellStyleXfByIndex($pIndex = 0)
1003 return $this->_cellStyleXfCollection[$pIndex];
1007 * Get cellStyleXf by hash code
1009 * @param string $pValue
1010 * @return PHPExcel_Style|false
1012 public function getCellStyleXfByHashCode($pValue = '')
1014 foreach ($this->_cellXfStyleCollection as $cellStyleXf) {
1015 if ($cellStyleXf->getHashCode() == $pValue) {
1016 return $cellStyleXf;
1019 return false;
1023 * Add a cellStyleXf to the workbook
1025 * @param PHPExcel_Style $pStyle
1027 public function addCellStyleXf(PHPExcel_Style $pStyle)
1029 $this->_cellStyleXfCollection[] = $pStyle;
1030 $pStyle->setIndex(count($this->_cellStyleXfCollection) - 1);
1034 * Remove cellStyleXf by index
1036 * @param int $pIndex
1037 * @throws PHPExcel_Exception
1039 public function removeCellStyleXfByIndex($pIndex = 0)
1041 if ($pIndex > count($this->_cellStyleXfCollection) - 1) {
1042 throw new PHPExcel_Exception("CellStyleXf index is out of bounds.");
1043 } else {
1044 array_splice($this->_cellStyleXfCollection, $pIndex, 1);
1049 * Eliminate all unneeded cellXf and afterwards update the xfIndex for all cells
1050 * and columns in the workbook
1052 public function garbageCollect()
1054 // how many references are there to each cellXf ?
1055 $countReferencesCellXf = array();
1056 foreach ($this->_cellXfCollection as $index => $cellXf) {
1057 $countReferencesCellXf[$index] = 0;
1060 foreach ($this->getWorksheetIterator() as $sheet) {
1062 // from cells
1063 foreach ($sheet->getCellCollection(false) as $cellID) {
1064 $cell = $sheet->getCell($cellID);
1065 ++$countReferencesCellXf[$cell->getXfIndex()];
1068 // from row dimensions
1069 foreach ($sheet->getRowDimensions() as $rowDimension) {
1070 if ($rowDimension->getXfIndex() !== null) {
1071 ++$countReferencesCellXf[$rowDimension->getXfIndex()];
1075 // from column dimensions
1076 foreach ($sheet->getColumnDimensions() as $columnDimension) {
1077 ++$countReferencesCellXf[$columnDimension->getXfIndex()];
1081 // remove cellXfs without references and create mapping so we can update xfIndex
1082 // for all cells and columns
1083 $countNeededCellXfs = 0;
1084 foreach ($this->_cellXfCollection as $index => $cellXf) {
1085 if ($countReferencesCellXf[$index] > 0 || $index == 0) { // we must never remove the first cellXf
1086 ++$countNeededCellXfs;
1087 } else {
1088 unset($this->_cellXfCollection[$index]);
1090 $map[$index] = $countNeededCellXfs - 1;
1092 $this->_cellXfCollection = array_values($this->_cellXfCollection);
1094 // update the index for all cellXfs
1095 foreach ($this->_cellXfCollection as $i => $cellXf) {
1096 $cellXf->setIndex($i);
1099 // make sure there is always at least one cellXf (there should be)
1100 if (empty($this->_cellXfCollection)) {
1101 $this->_cellXfCollection[] = new PHPExcel_Style();
1104 // update the xfIndex for all cells, row dimensions, column dimensions
1105 foreach ($this->getWorksheetIterator() as $sheet) {
1107 // for all cells
1108 foreach ($sheet->getCellCollection(false) as $cellID) {
1109 $cell = $sheet->getCell($cellID);
1110 $cell->setXfIndex( $map[$cell->getXfIndex()] );
1113 // for all row dimensions
1114 foreach ($sheet->getRowDimensions() as $rowDimension) {
1115 if ($rowDimension->getXfIndex() !== null) {
1116 $rowDimension->setXfIndex( $map[$rowDimension->getXfIndex()] );
1120 // for all column dimensions
1121 foreach ($sheet->getColumnDimensions() as $columnDimension) {
1122 $columnDimension->setXfIndex( $map[$columnDimension->getXfIndex()] );
1125 // also do garbage collection for all the sheets
1126 $sheet->garbageCollect();
1131 * Return the unique ID value assigned to this spreadsheet workbook
1133 * @return string
1135 public function getID() {
1136 return $this->_uniqueID;