Changelog entry for patch #3313326
[phpmyadmin/ammaryasirr.git] / libraries / PHPExcel / PHPExcel.php
blobcdb4ab95012f230a09e6ed629db2660b0a462485
1 <?php
2 /**
3 * PHPExcel
5 * Copyright (c) 2006 - 2011 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 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
24 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
25 * @version 1.7.6, 2011-02-27
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 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
43 class PHPExcel
45 /**
46 * Document properties
48 * @var PHPExcel_DocumentProperties
50 private $_properties;
52 /**
53 * Document security
55 * @var PHPExcel_DocumentSecurity
57 private $_security;
59 /**
60 * Collection of Worksheet objects
62 * @var PHPExcel_Worksheet[]
64 private $_workSheetCollection = array();
66 /**
67 * Active sheet index
69 * @var int
71 private $_activeSheetIndex = 0;
73 /**
74 * Named ranges
76 * @var PHPExcel_NamedRange[]
78 private $_namedRanges = array();
80 /**
81 * CellXf supervisor
83 * @var PHPExcel_Style
85 private $_cellXfSupervisor;
87 /**
88 * CellXf collection
90 * @var PHPExcel_Style[]
92 private $_cellXfCollection = array();
94 /**
95 * CellStyleXf collection
97 * @var PHPExcel_Style[]
99 private $_cellStyleXfCollection = array();
102 * Create a new PHPExcel with one Worksheet
104 public function __construct()
106 // Initialise worksheet collection and add one worksheet
107 $this->_workSheetCollection = array();
108 $this->_workSheetCollection[] = new PHPExcel_Worksheet($this);
109 $this->_activeSheetIndex = 0;
111 // Create document properties
112 $this->_properties = new PHPExcel_DocumentProperties();
114 // Create document security
115 $this->_security = new PHPExcel_DocumentSecurity();
117 // Set named ranges
118 $this->_namedRanges = array();
120 // Create the cellXf supervisor
121 $this->_cellXfSupervisor = new PHPExcel_Style(true);
122 $this->_cellXfSupervisor->bindParent($this);
124 // Create the default style
125 $this->addCellXf(new PHPExcel_Style);
126 $this->addCellStyleXf(new PHPExcel_Style);
130 public function disconnectWorksheets() {
131 foreach($this->_workSheetCollection as $k => &$worksheet) {
132 $worksheet->disconnectCells();
133 $this->_workSheetCollection[$k] = null;
135 unset($worksheet);
136 $this->_workSheetCollection = array();
140 * Get properties
142 * @return PHPExcel_DocumentProperties
144 public function getProperties()
146 return $this->_properties;
150 * Set properties
152 * @param PHPExcel_DocumentProperties $pValue
154 public function setProperties(PHPExcel_DocumentProperties $pValue)
156 $this->_properties = $pValue;
160 * Get security
162 * @return PHPExcel_DocumentSecurity
164 public function getSecurity()
166 return $this->_security;
170 * Set security
172 * @param PHPExcel_DocumentSecurity $pValue
174 public function setSecurity(PHPExcel_DocumentSecurity $pValue)
176 $this->_security = $pValue;
180 * Get active sheet
182 * @return PHPExcel_Worksheet
184 public function getActiveSheet()
186 return $this->_workSheetCollection[$this->_activeSheetIndex];
190 * Create sheet and add it to this workbook
192 * @return PHPExcel_Worksheet
194 public function createSheet($iSheetIndex = null)
196 $newSheet = new PHPExcel_Worksheet($this);
197 $this->addSheet($newSheet, $iSheetIndex);
198 return $newSheet;
202 * Add sheet
204 * @param PHPExcel_Worksheet $pSheet
205 * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last)
206 * @return PHPExcel_Worksheet
207 * @throws Exception
209 public function addSheet(PHPExcel_Worksheet $pSheet = null, $iSheetIndex = null)
211 if(is_null($iSheetIndex))
213 $this->_workSheetCollection[] = $pSheet;
215 else
217 // Insert the sheet at the requested index
218 array_splice(
219 $this->_workSheetCollection,
220 $iSheetIndex,
222 array($pSheet)
225 // Adjust active sheet index if necessary
226 if ($this->_activeSheetIndex >= $iSheetIndex) {
227 ++$this->_activeSheetIndex;
231 return $pSheet;
235 * Remove sheet by index
237 * @param int $pIndex Active sheet index
238 * @throws Exception
240 public function removeSheetByIndex($pIndex = 0)
242 if ($pIndex > count($this->_workSheetCollection) - 1) {
243 throw new Exception("Sheet index is out of bounds.");
244 } else {
245 array_splice($this->_workSheetCollection, $pIndex, 1);
250 * Get sheet by index
252 * @param int $pIndex Sheet index
253 * @return PHPExcel_Worksheet
254 * @throws Exception
256 public function getSheet($pIndex = 0)
258 if ($pIndex > count($this->_workSheetCollection) - 1) {
259 throw new Exception("Sheet index is out of bounds.");
260 } else {
261 return $this->_workSheetCollection[$pIndex];
266 * Get all sheets
268 * @return PHPExcel_Worksheet[]
270 public function getAllSheets()
272 return $this->_workSheetCollection;
276 * Get sheet by name
278 * @param string $pName Sheet name
279 * @return PHPExcel_Worksheet
280 * @throws Exception
282 public function getSheetByName($pName = '')
284 $worksheetCount = count($this->_workSheetCollection);
285 for ($i = 0; $i < $worksheetCount; ++$i) {
286 if ($this->_workSheetCollection[$i]->getTitle() == $pName) {
287 return $this->_workSheetCollection[$i];
291 return null;
295 * Get index for sheet
297 * @param PHPExcel_Worksheet $pSheet
298 * @return Sheet index
299 * @throws Exception
301 public function getIndex(PHPExcel_Worksheet $pSheet)
303 foreach ($this->_workSheetCollection as $key => $value) {
304 if ($value->getHashCode() == $pSheet->getHashCode()) {
305 return $key;
311 * Set index for sheet by sheet name.
313 * @param string $sheetName Sheet name to modify index for
314 * @param int $newIndex New index for the sheet
315 * @return New sheet index
316 * @throws Exception
318 public function setIndexByName($sheetName, $newIndex)
320 $oldIndex = $this->getIndex($this->getSheetByName($sheetName));
321 $pSheet = array_splice(
322 $this->_workSheetCollection,
323 $oldIndex,
326 array_splice(
327 $this->_workSheetCollection,
328 $newIndex,
330 $pSheet
332 return $newIndex;
336 * Get sheet count
338 * @return int
340 public function getSheetCount()
342 return count($this->_workSheetCollection);
346 * Get active sheet index
348 * @return int Active sheet index
350 public function getActiveSheetIndex()
352 return $this->_activeSheetIndex;
356 * Set active sheet index
358 * @param int $pIndex Active sheet index
359 * @throws Exception
360 * @return PHPExcel_Worksheet
362 public function setActiveSheetIndex($pIndex = 0)
364 if ($pIndex > count($this->_workSheetCollection) - 1) {
365 throw new Exception("Active sheet index is out of bounds.");
366 } else {
367 $this->_activeSheetIndex = $pIndex;
369 return $this->getActiveSheet();
373 * Set active sheet index by name
375 * @param string $pValue Sheet title
376 * @return PHPExcel_Worksheet
377 * @throws Exception
379 public function setActiveSheetIndexByName($pValue = '')
381 if (($worksheet = $this->getSheetByName($pValue)) instanceof PHPExcel_Worksheet) {
382 $this->setActiveSheetIndex($worksheet->getParent()->getIndex($worksheet));
383 return $worksheet;
386 throw new Exception('Workbook does not contain sheet:' . $pValue);
390 * Get sheet names
392 * @return string[]
394 public function getSheetNames()
396 $returnValue = array();
397 $worksheetCount = $this->getSheetCount();
398 for ($i = 0; $i < $worksheetCount; ++$i) {
399 array_push($returnValue, $this->getSheet($i)->getTitle());
402 return $returnValue;
406 * Add external sheet
408 * @param PHPExcel_Worksheet $pSheet External sheet to add
409 * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last)
410 * @throws Exception
411 * @return PHPExcel_Worksheet
413 public function addExternalSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = null) {
414 if (!is_null($this->getSheetByName($pSheet->getTitle()))) {
415 throw new Exception("Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename the external sheet first.");
418 // count how many cellXfs there are in this workbook currently, we will need this below
419 $countCellXfs = count($this->_cellXfCollection);
421 // copy all the shared cellXfs from the external workbook and append them to the current
422 foreach ($pSheet->getParent()->getCellXfCollection() as $cellXf) {
423 $this->addCellXf(clone $cellXf);
426 // move sheet to this workbook
427 $pSheet->rebindParent($this);
429 // update the cellXfs
430 foreach ($pSheet->getCellCollection(false) as $cellID) {
431 $cell = $pSheet->getCell($cellID);
432 $cell->setXfIndex( $cell->getXfIndex() + $countCellXfs );
435 return $this->addSheet($pSheet, $iSheetIndex);
439 * Get named ranges
441 * @return PHPExcel_NamedRange[]
443 public function getNamedRanges() {
444 return $this->_namedRanges;
448 * Add named range
450 * @param PHPExcel_NamedRange $namedRange
451 * @return PHPExcel
453 public function addNamedRange(PHPExcel_NamedRange $namedRange) {
454 if ($namedRange->getScope() == null) {
455 // global scope
456 $this->_namedRanges[$namedRange->getName()] = $namedRange;
457 } else {
458 // local scope
459 $this->_namedRanges[$namedRange->getScope()->getTitle().'!'.$namedRange->getName()] = $namedRange;
461 return true;
465 * Get named range
467 * @param string $namedRange
468 * @param PHPExcel_Worksheet|null $pSheet Scope. Use null for global scope
469 * @return PHPExcel_NamedRange|null
471 public function getNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) {
472 $returnValue = null;
474 if ($namedRange != '' && !is_null($namedRange)) {
475 // first look for global defined name
476 if (isset($this->_namedRanges[$namedRange])) {
477 $returnValue = $this->_namedRanges[$namedRange];
480 // then look for local defined name (has priority over global defined name if both names exist)
481 if (!is_null($pSheet) && isset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange])) {
482 $returnValue = $this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange];
486 return $returnValue;
490 * Remove named range
492 * @param string $namedRange
493 * @param PHPExcel_Worksheet|null $pSheet. Scope. Use null for global scope.
494 * @return PHPExcel
496 public function removeNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) {
497 if (is_null($pSheet)) {
498 if (isset($this->_namedRanges[$namedRange])) {
499 unset($this->_namedRanges[$namedRange]);
501 } else {
502 if (isset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange])) {
503 unset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange]);
506 return $this;
510 * Get worksheet iterator
512 * @return PHPExcel_WorksheetIterator
514 public function getWorksheetIterator() {
515 return new PHPExcel_WorksheetIterator($this);
519 * Copy workbook (!= clone!)
521 * @return PHPExcel
523 public function copy() {
524 $copied = clone $this;
526 $worksheetCount = count($this->_workSheetCollection);
527 for ($i = 0; $i < $worksheetCount; ++$i) {
528 $this->_workSheetCollection[$i] = $this->_workSheetCollection[$i]->copy();
529 $this->_workSheetCollection[$i]->rebindParent($this);
532 return $copied;
536 * Implement PHP __clone to create a deep clone, not just a shallow copy.
538 public function __clone() {
539 foreach($this as $key => $val) {
540 if (is_object($val) || (is_array($val))) {
541 $this->{$key} = unserialize(serialize($val));
547 * Get the workbook collection of cellXfs
549 * @return PHPExcel_Style[]
551 public function getCellXfCollection()
553 return $this->_cellXfCollection;
557 * Get cellXf by index
559 * @param int $index
560 * @return PHPExcel_Style
562 public function getCellXfByIndex($pIndex = 0)
564 return $this->_cellXfCollection[$pIndex];
568 * Get cellXf by hash code
570 * @param string $pValue
571 * @return PHPExcel_Style|false
573 public function getCellXfByHashCode($pValue = '')
575 foreach ($this->_cellXfCollection as $cellXf) {
576 if ($cellXf->getHashCode() == $pValue) {
577 return $cellXf;
580 return false;
584 * Get default style
586 * @return PHPExcel_Style
587 * @throws Exception
589 public function getDefaultStyle()
591 if (isset($this->_cellXfCollection[0])) {
592 return $this->_cellXfCollection[0];
594 throw new Exception('No default style found for this workbook');
598 * Add a cellXf to the workbook
600 * @param PHPExcel_Style
602 public function addCellXf(PHPExcel_Style $style)
604 $this->_cellXfCollection[] = $style;
605 $style->setIndex(count($this->_cellXfCollection) - 1);
609 * Remove cellXf by index. It is ensured that all cells get their xf index updated.
611 * @param int $pIndex Index to cellXf
612 * @throws Exception
614 public function removeCellXfByIndex($pIndex = 0)
616 if ($pIndex > count($this->_cellXfCollection) - 1) {
617 throw new Exception("CellXf index is out of bounds.");
618 } else {
619 // first remove the cellXf
620 array_splice($this->_cellXfCollection, $pIndex, 1);
622 // then update cellXf indexes for cells
623 foreach ($this->_workSheetCollection as $worksheet) {
624 foreach ($worksheet->getCellCollection(false) as $cellID) {
625 $cell = $worksheet->getCell($cellID);
626 $xfIndex = $cell->getXfIndex();
627 if ($xfIndex > $pIndex ) {
628 // decrease xf index by 1
629 $cell->setXfIndex($xfIndex - 1);
630 } else if ($xfIndex == $pIndex) {
631 // set to default xf index 0
632 $cell->setXfIndex(0);
640 * Get the cellXf supervisor
642 * @return PHPExcel_Style
644 public function getCellXfSupervisor()
646 return $this->_cellXfSupervisor;
650 * Get the workbook collection of cellStyleXfs
652 * @return PHPExcel_Style[]
654 public function getCellStyleXfCollection()
656 return $this->_cellStyleXfCollection;
660 * Get cellStyleXf by index
662 * @param int $pIndex
663 * @return PHPExcel_Style
665 public function getCellStyleXfByIndex($pIndex = 0)
667 return $this->_cellStyleXfCollection[$pIndex];
671 * Get cellStyleXf by hash code
673 * @param string $pValue
674 * @return PHPExcel_Style|false
676 public function getCellStyleXfByHashCode($pValue = '')
678 foreach ($this->_cellXfStyleCollection as $cellStyleXf) {
679 if ($cellStyleXf->getHashCode() == $pValue) {
680 return $cellStyleXf;
683 return false;
687 * Add a cellStyleXf to the workbook
689 * @param PHPExcel_Style $pStyle
691 public function addCellStyleXf(PHPExcel_Style $pStyle)
693 $this->_cellStyleXfCollection[] = $pStyle;
694 $pStyle->setIndex(count($this->_cellStyleXfCollection) - 1);
698 * Remove cellStyleXf by index
700 * @param int $pIndex
701 * @throws Exception
703 public function removeCellStyleXfByIndex($pIndex = 0)
705 if ($pIndex > count($this->_cellStyleXfCollection) - 1) {
706 throw new Exception("CellStyleXf index is out of bounds.");
707 } else {
708 array_splice($this->_cellStyleXfCollection, $pIndex, 1);
713 * Eliminate all unneeded cellXf and afterwards update the xfIndex for all cells
714 * and columns in the workbook
716 public function garbageCollect()
718 // how many references are there to each cellXf ?
719 $countReferencesCellXf = array();
720 foreach ($this->_cellXfCollection as $index => $cellXf) {
721 $countReferencesCellXf[$index] = 0;
724 foreach ($this->getWorksheetIterator() as $sheet) {
726 // from cells
727 foreach ($sheet->getCellCollection(false) as $cellID) {
728 $cell = $sheet->getCell($cellID);
729 ++$countReferencesCellXf[$cell->getXfIndex()];
732 // from row dimensions
733 foreach ($sheet->getRowDimensions() as $rowDimension) {
734 if ($rowDimension->getXfIndex() !== null) {
735 ++$countReferencesCellXf[$rowDimension->getXfIndex()];
739 // from column dimensions
740 foreach ($sheet->getColumnDimensions() as $columnDimension) {
741 ++$countReferencesCellXf[$columnDimension->getXfIndex()];
745 // remove cellXfs without references and create mapping so we can update xfIndex
746 // for all cells and columns
747 $countNeededCellXfs = 0;
748 foreach ($this->_cellXfCollection as $index => $cellXf) {
749 if ($countReferencesCellXf[$index] > 0 || $index == 0) { // we must never remove the first cellXf
750 ++$countNeededCellXfs;
751 } else {
752 unset($this->_cellXfCollection[$index]);
754 $map[$index] = $countNeededCellXfs - 1;
756 $this->_cellXfCollection = array_values($this->_cellXfCollection);
758 // update the index for all cellXfs
759 foreach ($this->_cellXfCollection as $i => $cellXf) {
760 $cellXf->setIndex($i);
763 // make sure there is always at least one cellXf (there should be)
764 if (count($this->_cellXfCollection) == 0) {
765 $this->_cellXfCollection[] = new PHPExcel_Style();
768 // update the xfIndex for all cells, row dimensions, column dimensions
769 foreach ($this->getWorksheetIterator() as $sheet) {
771 // for all cells
772 foreach ($sheet->getCellCollection(false) as $cellID) {
773 $cell = $sheet->getCell($cellID);
774 $cell->setXfIndex( $map[$cell->getXfIndex()] );
777 // for all row dimensions
778 foreach ($sheet->getRowDimensions() as $rowDimension) {
779 if ($rowDimension->getXfIndex() !== null) {
780 $rowDimension->setXfIndex( $map[$rowDimension->getXfIndex()] );
784 // for all column dimensions
785 foreach ($sheet->getColumnDimensions() as $columnDimension) {
786 $columnDimension->setXfIndex( $map[$columnDimension->getXfIndex()] );
790 // also do garbage collection for all the sheets
791 foreach ($this->getWorksheetIterator() as $sheet) {
792 $sheet->garbageCollect();