Subversion Repositories eFlore/Applications.cel

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2388 jpm 1
<?php
2
/**
3
 * PHPExcel
4
 *
5
 * Copyright (c) 2006 - 2013 PHPExcel
6
 *
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.
11
 *
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.
16
 *
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
20
 *
21
 * @category   PHPExcel
22
 * @package    PHPExcel
23
 * @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)
24
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
25
 * @version    ##VERSION##, ##DATE##
26
 */
27
 
28
 
29
/** PHPExcel root directory */
30
if (!defined('PHPEXCEL_ROOT')) {
31
    define('PHPEXCEL_ROOT', dirname(__FILE__) . '/');
32
    require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
33
}
34
 
35
 
36
/**
37
 * PHPExcel
38
 *
39
 * @category   PHPExcel
40
 * @package    PHPExcel
41
 * @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)
42
 */
43
class PHPExcel
44
{
45
    /**
46
     * Unique ID
47
     *
48
     * @var string
49
     */
50
    private $_uniqueID;
51
 
52
    /**
53
     * Document properties
54
     *
55
     * @var PHPExcel_DocumentProperties
56
     */
57
    private $_properties;
58
 
59
    /**
60
     * Document security
61
     *
62
     * @var PHPExcel_DocumentSecurity
63
     */
64
    private $_security;
65
 
66
    /**
67
     * Collection of Worksheet objects
68
     *
69
     * @var PHPExcel_Worksheet[]
70
     */
71
    private $_workSheetCollection = array();
72
 
73
    /**
74
	 * Calculation Engine
75
	 *
76
	 * @var PHPExcel_Calculation
77
	 */
78
	private $_calculationEngine = NULL;
79
 
80
    /**
81
     * Active sheet index
82
     *
83
     * @var int
84
     */
85
    private $_activeSheetIndex = 0;
86
 
87
    /**
88
     * Named ranges
89
     *
90
     * @var PHPExcel_NamedRange[]
91
     */
92
    private $_namedRanges = array();
93
 
94
    /**
95
     * CellXf supervisor
96
     *
97
     * @var PHPExcel_Style
98
     */
99
    private $_cellXfSupervisor;
100
 
101
    /**
102
     * CellXf collection
103
     *
104
     * @var PHPExcel_Style[]
105
     */
106
    private $_cellXfCollection = array();
107
 
108
    /**
109
     * CellStyleXf collection
110
     *
111
     * @var PHPExcel_Style[]
112
     */
113
    private $_cellStyleXfCollection = array();
114
 
115
    /**
116
     * Create a new PHPExcel with one Worksheet
117
     */
118
    public function __construct()
119
    {
120
		$this->_uniqueID = uniqid();
121
		$this->_calculationEngine	= PHPExcel_Calculation::getInstance($this);
122
 
123
        // Initialise worksheet collection and add one worksheet
124
        $this->_workSheetCollection = array();
125
        $this->_workSheetCollection[] = new PHPExcel_Worksheet($this);
126
        $this->_activeSheetIndex = 0;
127
 
128
        // Create document properties
129
        $this->_properties = new PHPExcel_DocumentProperties();
130
 
131
        // Create document security
132
        $this->_security = new PHPExcel_DocumentSecurity();
133
 
134
        // Set named ranges
135
        $this->_namedRanges = array();
136
 
137
        // Create the cellXf supervisor
138
        $this->_cellXfSupervisor = new PHPExcel_Style(true);
139
        $this->_cellXfSupervisor->bindParent($this);
140
 
141
        // Create the default style
142
        $this->addCellXf(new PHPExcel_Style);
143
        $this->addCellStyleXf(new PHPExcel_Style);
144
    }
145
 
146
    /**
147
     * Code to execute when this worksheet is unset()
148
     *
149
     */
150
    public function __destruct() {
151
        PHPExcel_Calculation::unsetInstance($this);
152
        $this->disconnectWorksheets();
153
    }    //    function __destruct()
154
 
155
    /**
156
     * Disconnect all worksheets from this PHPExcel workbook object,
157
     *    typically so that the PHPExcel object can be unset
158
     *
159
     */
160
    public function disconnectWorksheets()
161
    {
162
    	$worksheet = NULL;
163
        foreach($this->_workSheetCollection as $k => &$worksheet) {
164
            $worksheet->disconnectCells();
165
            $this->_workSheetCollection[$k] = null;
166
        }
167
        unset($worksheet);
168
        $this->_workSheetCollection = array();
169
    }
170
 
171
	/**
172
	 * Return the calculation engine for this worksheet
173
	 *
174
	 * @return PHPExcel_Calculation
175
	 */
176
	public function getCalculationEngine()
177
	{
178
		return $this->_calculationEngine;
179
	}	//	function getCellCacheController()
180
 
181
    /**
182
     * Get properties
183
     *
184
     * @return PHPExcel_DocumentProperties
185
     */
186
    public function getProperties()
187
    {
188
        return $this->_properties;
189
    }
190
 
191
    /**
192
     * Set properties
193
     *
194
     * @param PHPExcel_DocumentProperties    $pValue
195
     */
196
    public function setProperties(PHPExcel_DocumentProperties $pValue)
197
    {
198
        $this->_properties = $pValue;
199
    }
200
 
201
    /**
202
     * Get security
203
     *
204
     * @return PHPExcel_DocumentSecurity
205
     */
206
    public function getSecurity()
207
    {
208
        return $this->_security;
209
    }
210
 
211
    /**
212
     * Set security
213
     *
214
     * @param PHPExcel_DocumentSecurity    $pValue
215
     */
216
    public function setSecurity(PHPExcel_DocumentSecurity $pValue)
217
    {
218
        $this->_security = $pValue;
219
    }
220
 
221
    /**
222
     * Get active sheet
223
     *
224
     * @return PHPExcel_Worksheet
225
     */
226
    public function getActiveSheet()
227
    {
228
        return $this->_workSheetCollection[$this->_activeSheetIndex];
229
    }
230
 
231
    /**
232
     * Create sheet and add it to this workbook
233
     *
234
     * @param  int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last)
235
     * @return PHPExcel_Worksheet
236
     * @throws PHPExcel_Exception
237
     */
238
    public function createSheet($iSheetIndex = NULL)
239
    {
240
        $newSheet = new PHPExcel_Worksheet($this);
241
        $this->addSheet($newSheet, $iSheetIndex);
242
        return $newSheet;
243
    }
244
 
245
    /**
246
     * Check if a sheet with a specified name already exists
247
     *
248
     * @param  string $pSheetName  Name of the worksheet to check
249
     * @return boolean
250
     */
251
    public function sheetNameExists($pSheetName)
252
    {
253
        return ($this->getSheetByName($pSheetName) !== NULL);
254
    }
255
 
256
    /**
257
     * Add sheet
258
     *
259
     * @param  PHPExcel_Worksheet $pSheet
260
     * @param  int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last)
261
     * @return PHPExcel_Worksheet
262
     * @throws PHPExcel_Exception
263
     */
264
    public function addSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = NULL)
265
    {
266
        if ($this->sheetNameExists($pSheet->getTitle())) {
267
            throw new PHPExcel_Exception(
268
            	"Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename this worksheet first."
269
            );
270
        }
271
 
272
        if($iSheetIndex === NULL) {
273
            if ($this->_activeSheetIndex < 0) {
274
                $this->_activeSheetIndex = 0;
275
            }
276
            $this->_workSheetCollection[] = $pSheet;
277
        } else {
278
            // Insert the sheet at the requested index
279
            array_splice(
280
                $this->_workSheetCollection,
281
                $iSheetIndex,
282
                0,
283
                array($pSheet)
284
                );
285
 
286
            // Adjust active sheet index if necessary
287
            if ($this->_activeSheetIndex >= $iSheetIndex) {
288
                ++$this->_activeSheetIndex;
289
            }
290
        }
291
        return $pSheet;
292
    }
293
 
294
    /**
295
     * Remove sheet by index
296
     *
297
     * @param  int $pIndex Active sheet index
298
     * @throws PHPExcel_Exception
299
     */
300
    public function removeSheetByIndex($pIndex = 0)
301
    {
302
 
303
        $numSheets = count($this->_workSheetCollection);
304
 
305
        if ($pIndex > $numSheets - 1) {
306
            throw new PHPExcel_Exception(
307
            	"You tried to remove a sheet by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}."
308
            );
309
        } else {
310
            array_splice($this->_workSheetCollection, $pIndex, 1);
311
        }
312
        // Adjust active sheet index if necessary
313
        if (($this->_activeSheetIndex >= $pIndex) &&
314
            ($pIndex > count($this->_workSheetCollection) - 1)) {
315
            --$this->_activeSheetIndex;
316
        }
317
 
318
    }
319
 
320
    /**
321
     * Get sheet by index
322
     *
323
     * @param  int $pIndex Sheet index
324
     * @return PHPExcel_Worksheet
325
     * @throws PHPExcel_Exception
326
     */
327
    public function getSheet($pIndex = 0)
328
    {
329
 
330
        $numSheets = count($this->_workSheetCollection);
331
 
332
        if ($pIndex > $numSheets - 1) {
333
            throw new PHPExcel_Exception(
334
            	"Your requested sheet index: {$pIndex} is out of bounds. The actual number of sheets is {$numSheets}."
335
           	);
336
        } else {
337
            return $this->_workSheetCollection[$pIndex];
338
        }
339
    }
340
 
341
    /**
342
     * Get all sheets
343
     *
344
     * @return PHPExcel_Worksheet[]
345
     */
346
    public function getAllSheets()
347
    {
348
        return $this->_workSheetCollection;
349
    }
350
 
351
    /**
352
     * Get sheet by name
353
     *
354
     * @param  string $pName Sheet name
355
     * @return PHPExcel_Worksheet
356
     */
357
    public function getSheetByName($pName = '')
358
    {
359
        $worksheetCount = count($this->_workSheetCollection);
360
        for ($i = 0; $i < $worksheetCount; ++$i) {
361
            if ($this->_workSheetCollection[$i]->getTitle() === $pName) {
362
                return $this->_workSheetCollection[$i];
363
            }
364
        }
365
 
366
        return NULL;
367
    }
368
 
369
    /**
370
     * Get index for sheet
371
     *
372
     * @param  PHPExcel_Worksheet $pSheet
373
     * @return Sheet index
374
     * @throws PHPExcel_Exception
375
     */
376
    public function getIndex(PHPExcel_Worksheet $pSheet)
377
    {
378
        foreach ($this->_workSheetCollection as $key => $value) {
379
            if ($value->getHashCode() == $pSheet->getHashCode()) {
380
                return $key;
381
            }
382
        }
383
 
384
        throw new PHPExcel_Exception("Sheet does not exist.");
385
    }
386
 
387
    /**
388
     * Set index for sheet by sheet name.
389
     *
390
     * @param  string $sheetName Sheet name to modify index for
391
     * @param  int $newIndex New index for the sheet
392
     * @return New sheet index
393
     * @throws PHPExcel_Exception
394
     */
395
    public function setIndexByName($sheetName, $newIndex)
396
    {
397
        $oldIndex = $this->getIndex($this->getSheetByName($sheetName));
398
        $pSheet = array_splice(
399
            $this->_workSheetCollection,
400
            $oldIndex,
401
            1
402
        );
403
        array_splice(
404
            $this->_workSheetCollection,
405
            $newIndex,
406
            0,
407
            $pSheet
408
        );
409
        return $newIndex;
410
    }
411
 
412
    /**
413
     * Get sheet count
414
     *
415
     * @return int
416
     */
417
    public function getSheetCount()
418
    {
419
        return count($this->_workSheetCollection);
420
    }
421
 
422
    /**
423
     * Get active sheet index
424
     *
425
     * @return int Active sheet index
426
     */
427
    public function getActiveSheetIndex()
428
    {
429
        return $this->_activeSheetIndex;
430
    }
431
 
432
    /**
433
     * Set active sheet index
434
     *
435
     * @param  int $pIndex Active sheet index
436
     * @throws PHPExcel_Exception
437
     * @return PHPExcel_Worksheet
438
     */
439
    public function setActiveSheetIndex($pIndex = 0)
440
    {
441
    		$numSheets = count($this->_workSheetCollection);
442
 
443
        if ($pIndex > $numSheets - 1) {
444
            throw new PHPExcel_Exception(
445
            	"You tried to set a sheet active by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}."
446
            );
447
        } else {
448
            $this->_activeSheetIndex = $pIndex;
449
        }
450
        return $this->getActiveSheet();
451
    }
452
 
453
    /**
454
     * Set active sheet index by name
455
     *
456
     * @param  string $pValue Sheet title
457
     * @return PHPExcel_Worksheet
458
     * @throws PHPExcel_Exception
459
     */
460
    public function setActiveSheetIndexByName($pValue = '')
461
    {
462
        if (($worksheet = $this->getSheetByName($pValue)) instanceof PHPExcel_Worksheet) {
463
            $this->setActiveSheetIndex($this->getIndex($worksheet));
464
            return $worksheet;
465
        }
466
 
467
        throw new PHPExcel_Exception('Workbook does not contain sheet:' . $pValue);
468
    }
469
 
470
    /**
471
     * Get sheet names
472
     *
473
     * @return string[]
474
     */
475
    public function getSheetNames()
476
    {
477
        $returnValue = array();
478
        $worksheetCount = $this->getSheetCount();
479
        for ($i = 0; $i < $worksheetCount; ++$i) {
480
            $returnValue[] = $this->getSheet($i)->getTitle();
481
        }
482
 
483
        return $returnValue;
484
    }
485
 
486
    /**
487
     * Add external sheet
488
     *
489
     * @param  PHPExcel_Worksheet $pSheet External sheet to add
490
     * @param  int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last)
491
     * @throws PHPExcel_Exception
492
     * @return PHPExcel_Worksheet
493
     */
494
    public function addExternalSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = null) {
495
        if ($this->sheetNameExists($pSheet->getTitle())) {
496
            throw new PHPExcel_Exception("Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename the external sheet first.");
497
        }
498
 
499
        // count how many cellXfs there are in this workbook currently, we will need this below
500
        $countCellXfs = count($this->_cellXfCollection);
501
 
502
        // copy all the shared cellXfs from the external workbook and append them to the current
503
        foreach ($pSheet->getParent()->getCellXfCollection() as $cellXf) {
504
            $this->addCellXf(clone $cellXf);
505
        }
506
 
507
        // move sheet to this workbook
508
        $pSheet->rebindParent($this);
509
 
510
        // update the cellXfs
511
        foreach ($pSheet->getCellCollection(false) as $cellID) {
512
            $cell = $pSheet->getCell($cellID);
513
            $cell->setXfIndex( $cell->getXfIndex() + $countCellXfs );
514
        }
515
 
516
        return $this->addSheet($pSheet, $iSheetIndex);
517
    }
518
 
519
    /**
520
     * Get named ranges
521
     *
522
     * @return PHPExcel_NamedRange[]
523
     */
524
    public function getNamedRanges() {
525
        return $this->_namedRanges;
526
    }
527
 
528
    /**
529
     * Add named range
530
     *
531
     * @param  PHPExcel_NamedRange $namedRange
532
     * @return PHPExcel
533
     */
534
    public function addNamedRange(PHPExcel_NamedRange $namedRange) {
535
        if ($namedRange->getScope() == null) {
536
            // global scope
537
            $this->_namedRanges[$namedRange->getName()] = $namedRange;
538
        } else {
539
            // local scope
540
            $this->_namedRanges[$namedRange->getScope()->getTitle().'!'.$namedRange->getName()] = $namedRange;
541
        }
542
        return true;
543
    }
544
 
545
    /**
546
     * Get named range
547
     *
548
     * @param  string $namedRange
549
     * @param  PHPExcel_Worksheet|null $pSheet Scope. Use null for global scope
550
     * @return PHPExcel_NamedRange|null
551
     */
552
    public function getNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) {
553
        $returnValue = null;
554
 
555
        if ($namedRange != '' && ($namedRange !== NULL)) {
556
            // first look for global defined name
557
            if (isset($this->_namedRanges[$namedRange])) {
558
                $returnValue = $this->_namedRanges[$namedRange];
559
            }
560
 
561
            // then look for local defined name (has priority over global defined name if both names exist)
562
            if (($pSheet !== NULL) && isset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange])) {
563
                $returnValue = $this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange];
564
            }
565
        }
566
 
567
        return $returnValue;
568
    }
569
 
570
    /**
571
     * Remove named range
572
     *
573
     * @param  string  $namedRange
574
     * @param  PHPExcel_Worksheet|null  $pSheet  Scope: use null for global scope.
575
     * @return PHPExcel
576
     */
577
    public function removeNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) {
578
        if ($pSheet === NULL) {
579
            if (isset($this->_namedRanges[$namedRange])) {
580
                unset($this->_namedRanges[$namedRange]);
581
            }
582
        } else {
583
            if (isset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange])) {
584
                unset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange]);
585
            }
586
        }
587
        return $this;
588
    }
589
 
590
    /**
591
     * Get worksheet iterator
592
     *
593
     * @return PHPExcel_WorksheetIterator
594
     */
595
    public function getWorksheetIterator() {
596
        return new PHPExcel_WorksheetIterator($this);
597
    }
598
 
599
    /**
600
     * Copy workbook (!= clone!)
601
     *
602
     * @return PHPExcel
603
     */
604
    public function copy() {
605
        $copied = clone $this;
606
 
607
        $worksheetCount = count($this->_workSheetCollection);
608
        for ($i = 0; $i < $worksheetCount; ++$i) {
609
            $this->_workSheetCollection[$i] = $this->_workSheetCollection[$i]->copy();
610
            $this->_workSheetCollection[$i]->rebindParent($this);
611
        }
612
 
613
        return $copied;
614
    }
615
 
616
    /**
617
     * Implement PHP __clone to create a deep clone, not just a shallow copy.
618
     */
619
    public function __clone() {
620
        foreach($this as $key => $val) {
621
            if (is_object($val) || (is_array($val))) {
622
                $this->{$key} = unserialize(serialize($val));
623
            }
624
        }
625
    }
626
 
627
    /**
628
     * Get the workbook collection of cellXfs
629
     *
630
     * @return PHPExcel_Style[]
631
     */
632
    public function getCellXfCollection()
633
    {
634
        return $this->_cellXfCollection;
635
    }
636
 
637
    /**
638
     * Get cellXf by index
639
     *
640
     * @param  int $pIndex
641
     * @return PHPExcel_Style
642
     */
643
    public function getCellXfByIndex($pIndex = 0)
644
    {
645
        return $this->_cellXfCollection[$pIndex];
646
    }
647
 
648
    /**
649
     * Get cellXf by hash code
650
     *
651
     * @param  string $pValue
652
     * @return PHPExcel_Style|false
653
     */
654
    public function getCellXfByHashCode($pValue = '')
655
    {
656
        foreach ($this->_cellXfCollection as $cellXf) {
657
            if ($cellXf->getHashCode() == $pValue) {
658
                return $cellXf;
659
            }
660
        }
661
        return false;
662
    }
663
 
664
    /**
665
     * Check if style exists in style collection
666
     *
667
     * @param  PHPExcel_Style $pCellStyle
668
     * @return boolean
669
     */
670
    public function cellXfExists($pCellStyle = null)
671
    {
672
        return in_array($pCellStyle, $this->_cellXfCollection, true);
673
    }
674
 
675
    /**
676
     * Get default style
677
     *
678
     * @return PHPExcel_Style
679
     * @throws PHPExcel_Exception
680
     */
681
    public function getDefaultStyle()
682
    {
683
        if (isset($this->_cellXfCollection[0])) {
684
            return $this->_cellXfCollection[0];
685
        }
686
        throw new PHPExcel_Exception('No default style found for this workbook');
687
    }
688
 
689
    /**
690
     * Add a cellXf to the workbook
691
     *
692
     * @param PHPExcel_Style $style
693
     */
694
    public function addCellXf(PHPExcel_Style $style)
695
    {
696
        $this->_cellXfCollection[] = $style;
697
        $style->setIndex(count($this->_cellXfCollection) - 1);
698
    }
699
 
700
    /**
701
     * Remove cellXf by index. It is ensured that all cells get their xf index updated.
702
     *
703
     * @param  int $pIndex Index to cellXf
704
     * @throws PHPExcel_Exception
705
     */
706
    public function removeCellXfByIndex($pIndex = 0)
707
    {
708
        if ($pIndex > count($this->_cellXfCollection) - 1) {
709
            throw new PHPExcel_Exception("CellXf index is out of bounds.");
710
        } else {
711
            // first remove the cellXf
712
            array_splice($this->_cellXfCollection, $pIndex, 1);
713
 
714
            // then update cellXf indexes for cells
715
            foreach ($this->_workSheetCollection as $worksheet) {
716
                foreach ($worksheet->getCellCollection(false) as $cellID) {
717
                    $cell = $worksheet->getCell($cellID);
718
                    $xfIndex = $cell->getXfIndex();
719
                    if ($xfIndex > $pIndex ) {
720
                        // decrease xf index by 1
721
                        $cell->setXfIndex($xfIndex - 1);
722
                    } else if ($xfIndex == $pIndex) {
723
                        // set to default xf index 0
724
                        $cell->setXfIndex(0);
725
                    }
726
                }
727
            }
728
        }
729
    }
730
 
731
    /**
732
     * Get the cellXf supervisor
733
     *
734
     * @return PHPExcel_Style
735
     */
736
    public function getCellXfSupervisor()
737
    {
738
        return $this->_cellXfSupervisor;
739
    }
740
 
741
    /**
742
     * Get the workbook collection of cellStyleXfs
743
     *
744
     * @return PHPExcel_Style[]
745
     */
746
    public function getCellStyleXfCollection()
747
    {
748
        return $this->_cellStyleXfCollection;
749
    }
750
 
751
    /**
752
     * Get cellStyleXf by index
753
     *
754
     * @param  int $pIndex
755
     * @return PHPExcel_Style
756
     */
757
    public function getCellStyleXfByIndex($pIndex = 0)
758
    {
759
        return $this->_cellStyleXfCollection[$pIndex];
760
    }
761
 
762
    /**
763
     * Get cellStyleXf by hash code
764
     *
765
     * @param  string $pValue
766
     * @return PHPExcel_Style|false
767
     */
768
    public function getCellStyleXfByHashCode($pValue = '')
769
    {
770
        foreach ($this->_cellXfStyleCollection as $cellStyleXf) {
771
            if ($cellStyleXf->getHashCode() == $pValue) {
772
                return $cellStyleXf;
773
            }
774
        }
775
        return false;
776
    }
777
 
778
    /**
779
     * Add a cellStyleXf to the workbook
780
     *
781
     * @param PHPExcel_Style $pStyle
782
     */
783
    public function addCellStyleXf(PHPExcel_Style $pStyle)
784
    {
785
        $this->_cellStyleXfCollection[] = $pStyle;
786
        $pStyle->setIndex(count($this->_cellStyleXfCollection) - 1);
787
    }
788
 
789
    /**
790
     * Remove cellStyleXf by index
791
     *
792
     * @param int $pIndex
793
     * @throws PHPExcel_Exception
794
     */
795
    public function removeCellStyleXfByIndex($pIndex = 0)
796
    {
797
        if ($pIndex > count($this->_cellStyleXfCollection) - 1) {
798
            throw new PHPExcel_Exception("CellStyleXf index is out of bounds.");
799
        } else {
800
            array_splice($this->_cellStyleXfCollection, $pIndex, 1);
801
        }
802
    }
803
 
804
    /**
805
     * Eliminate all unneeded cellXf and afterwards update the xfIndex for all cells
806
     * and columns in the workbook
807
     */
808
    public function garbageCollect()
809
    {
810
        // how many references are there to each cellXf ?
811
        $countReferencesCellXf = array();
812
        foreach ($this->_cellXfCollection as $index => $cellXf) {
813
            $countReferencesCellXf[$index] = 0;
814
        }
815
 
816
        foreach ($this->getWorksheetIterator() as $sheet) {
817
 
818
            // from cells
819
            foreach ($sheet->getCellCollection(false) as $cellID) {
820
                $cell = $sheet->getCell($cellID);
821
                ++$countReferencesCellXf[$cell->getXfIndex()];
822
            }
823
 
824
            // from row dimensions
825
            foreach ($sheet->getRowDimensions() as $rowDimension) {
826
                if ($rowDimension->getXfIndex() !== null) {
827
                    ++$countReferencesCellXf[$rowDimension->getXfIndex()];
828
                }
829
            }
830
 
831
            // from column dimensions
832
            foreach ($sheet->getColumnDimensions() as $columnDimension) {
833
                ++$countReferencesCellXf[$columnDimension->getXfIndex()];
834
            }
835
        }
836
 
837
        // remove cellXfs without references and create mapping so we can update xfIndex
838
        // for all cells and columns
839
        $countNeededCellXfs = 0;
840
        foreach ($this->_cellXfCollection as $index => $cellXf) {
841
            if ($countReferencesCellXf[$index] > 0 || $index == 0) { // we must never remove the first cellXf
842
                ++$countNeededCellXfs;
843
            } else {
844
                unset($this->_cellXfCollection[$index]);
845
            }
846
            $map[$index] = $countNeededCellXfs - 1;
847
        }
848
        $this->_cellXfCollection = array_values($this->_cellXfCollection);
849
 
850
        // update the index for all cellXfs
851
        foreach ($this->_cellXfCollection as $i => $cellXf) {
852
            $cellXf->setIndex($i);
853
        }
854
 
855
        // make sure there is always at least one cellXf (there should be)
856
        if (empty($this->_cellXfCollection)) {
857
            $this->_cellXfCollection[] = new PHPExcel_Style();
858
        }
859
 
860
        // update the xfIndex for all cells, row dimensions, column dimensions
861
        foreach ($this->getWorksheetIterator() as $sheet) {
862
 
863
            // for all cells
864
            foreach ($sheet->getCellCollection(false) as $cellID) {
865
                $cell = $sheet->getCell($cellID);
866
                $cell->setXfIndex( $map[$cell->getXfIndex()] );
867
            }
868
 
869
            // for all row dimensions
870
            foreach ($sheet->getRowDimensions() as $rowDimension) {
871
                if ($rowDimension->getXfIndex() !== null) {
872
                    $rowDimension->setXfIndex( $map[$rowDimension->getXfIndex()] );
873
                }
874
            }
875
 
876
            // for all column dimensions
877
            foreach ($sheet->getColumnDimensions() as $columnDimension) {
878
                $columnDimension->setXfIndex( $map[$columnDimension->getXfIndex()] );
879
            }
880
 
881
			// also do garbage collection for all the sheets
882
            $sheet->garbageCollect();
883
        }
884
    }
885
 
886
    /**
887
     * Return the unique ID value assigned to this spreadsheet workbook
888
     *
889
     * @return string
890
     */
891
    public function getID() {
892
        return $this->_uniqueID;
893
    }
894
 
895
}