~ubuntu-branches/ubuntu/trusty/moodle/trusty-proposed

« back to all changes in this revision

Viewing changes to lib/phpexcel/PHPExcel/Worksheet.php

  • Committer: Package Import Robot
  • Author(s): Thijs Kinkhorst
  • Date: 2013-07-19 08:52:46 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20130719085246-yebwditc2exoap2r
Tags: 2.5.1-1
* New upstream version: 2.5.1.
  - Fixes security issues:
    CVE-2013-2242 CVE-2013-2243 CVE-2013-2244 CVE-2013-2245
    CVE-2013-2246
* Depend on apache2 instead of obsolete apache2-mpm-prefork.
* Use packaged libphp-phpmailer (closes: #429339), adodb,
  HTMLPurifier, PclZip.
* Update debconf translations, thanks Salvatore Merone, Pietro Tollot,
  Joe Hansen, Yuri Kozlov, Holger Wansing, Américo Monteiro,
  Adriano Rafael Gomes, victory, Michał Kułach.
  (closes: #716972, #716986, #717080, #717108, #717278)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * PHPExcel
 
4
 *
 
5
 * Copyright (c) 2006 - 2012 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_Worksheet
 
23
 * @copyright  Copyright (c) 2006 - 2012 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
/**
 
30
 * PHPExcel_Worksheet
 
31
 *
 
32
 * @category   PHPExcel
 
33
 * @package     PHPExcel_Worksheet
 
34
 * @copyright  Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel)
 
35
 */
 
36
class PHPExcel_Worksheet implements PHPExcel_IComparable
 
37
{
 
38
        /* Break types */
 
39
        const BREAK_NONE        = 0;
 
40
        const BREAK_ROW         = 1;
 
41
        const BREAK_COLUMN      = 2;
 
42
 
 
43
        /* Sheet state */
 
44
        const SHEETSTATE_VISIBLE        = 'visible';
 
45
        const SHEETSTATE_HIDDEN = 'hidden';
 
46
        const SHEETSTATE_VERYHIDDEN = 'veryHidden';
 
47
 
 
48
        /**
 
49
         * Invalid characters in sheet title
 
50
         *
 
51
         * @var array
 
52
         */
 
53
        private static $_invalidCharacters = array('*', ':', '/', '\\', '?', '[', ']');
 
54
 
 
55
        /**
 
56
         * Parent spreadsheet
 
57
         *
 
58
         * @var PHPExcel
 
59
         */
 
60
        private $_parent;
 
61
 
 
62
        /**
 
63
         * Cacheable collection of cells
 
64
         *
 
65
         * @var PHPExcel_CachedObjectStorage_xxx
 
66
         */
 
67
        private $_cellCollection = null;
 
68
 
 
69
        /**
 
70
         * Collection of row dimensions
 
71
         *
 
72
         * @var PHPExcel_Worksheet_RowDimension[]
 
73
         */
 
74
        private $_rowDimensions = array();
 
75
 
 
76
        /**
 
77
         * Default row dimension
 
78
         *
 
79
         * @var PHPExcel_Worksheet_RowDimension
 
80
         */
 
81
        private $_defaultRowDimension = null;
 
82
 
 
83
        /**
 
84
         * Collection of column dimensions
 
85
         *
 
86
         * @var PHPExcel_Worksheet_ColumnDimension[]
 
87
         */
 
88
        private $_columnDimensions = array();
 
89
 
 
90
        /**
 
91
         * Default column dimension
 
92
         *
 
93
         * @var PHPExcel_Worksheet_ColumnDimension
 
94
         */
 
95
        private $_defaultColumnDimension = null;
 
96
 
 
97
        /**
 
98
         * Collection of drawings
 
99
         *
 
100
         * @var PHPExcel_Worksheet_BaseDrawing[]
 
101
         */
 
102
        private $_drawingCollection = null;
 
103
 
 
104
        /**
 
105
         * Collection of Chart objects
 
106
         *
 
107
         * @var PHPExcel_Chart[]
 
108
         */
 
109
        private $_chartCollection = array();
 
110
 
 
111
        /**
 
112
         * Worksheet title
 
113
         *
 
114
         * @var string
 
115
         */
 
116
        private $_title;
 
117
 
 
118
        /**
 
119
         * Sheet state
 
120
         *
 
121
         * @var string
 
122
         */
 
123
        private $_sheetState;
 
124
 
 
125
        /**
 
126
         * Page setup
 
127
         *
 
128
         * @var PHPExcel_Worksheet_PageSetup
 
129
         */
 
130
        private $_pageSetup;
 
131
 
 
132
        /**
 
133
         * Page margins
 
134
         *
 
135
         * @var PHPExcel_Worksheet_PageMargins
 
136
         */
 
137
        private $_pageMargins;
 
138
 
 
139
        /**
 
140
         * Page header/footer
 
141
         *
 
142
         * @var PHPExcel_Worksheet_HeaderFooter
 
143
         */
 
144
        private $_headerFooter;
 
145
 
 
146
        /**
 
147
         * Sheet view
 
148
         *
 
149
         * @var PHPExcel_Worksheet_SheetView
 
150
         */
 
151
        private $_sheetView;
 
152
 
 
153
        /**
 
154
         * Protection
 
155
         *
 
156
         * @var PHPExcel_Worksheet_Protection
 
157
         */
 
158
        private $_protection;
 
159
 
 
160
        /**
 
161
         * Collection of styles
 
162
         *
 
163
         * @var PHPExcel_Style[]
 
164
         */
 
165
        private $_styles = array();
 
166
 
 
167
        /**
 
168
         * Conditional styles. Indexed by cell coordinate, e.g. 'A1'
 
169
         *
 
170
         * @var array
 
171
         */
 
172
        private $_conditionalStylesCollection = array();
 
173
 
 
174
        /**
 
175
         * Is the current cell collection sorted already?
 
176
         *
 
177
         * @var boolean
 
178
         */
 
179
        private $_cellCollectionIsSorted = false;
 
180
 
 
181
        /**
 
182
         * Collection of breaks
 
183
         *
 
184
         * @var array
 
185
         */
 
186
        private $_breaks = array();
 
187
 
 
188
        /**
 
189
         * Collection of merged cell ranges
 
190
         *
 
191
         * @var array
 
192
         */
 
193
        private $_mergeCells = array();
 
194
 
 
195
        /**
 
196
         * Collection of protected cell ranges
 
197
         *
 
198
         * @var array
 
199
         */
 
200
        private $_protectedCells = array();
 
201
 
 
202
        /**
 
203
         * Autofilter Range and selection
 
204
         *
 
205
         * @var PHPExcel_Worksheet_AutoFilter
 
206
         */
 
207
        private $_autoFilter = NULL;
 
208
 
 
209
        /**
 
210
         * Freeze pane
 
211
         *
 
212
         * @var string
 
213
         */
 
214
        private $_freezePane = '';
 
215
 
 
216
        /**
 
217
         * Show gridlines?
 
218
         *
 
219
         * @var boolean
 
220
         */
 
221
        private $_showGridlines = true;
 
222
 
 
223
        /**
 
224
        * Print gridlines?
 
225
        *
 
226
        * @var boolean
 
227
        */
 
228
        private $_printGridlines = false;
 
229
 
 
230
        /**
 
231
        * Show row and column headers?
 
232
        *
 
233
        * @var boolean
 
234
        */
 
235
        private $_showRowColHeaders = true;
 
236
 
 
237
        /**
 
238
         * Show summary below? (Row/Column outline)
 
239
         *
 
240
         * @var boolean
 
241
         */
 
242
        private $_showSummaryBelow = true;
 
243
 
 
244
        /**
 
245
         * Show summary right? (Row/Column outline)
 
246
         *
 
247
         * @var boolean
 
248
         */
 
249
        private $_showSummaryRight = true;
 
250
 
 
251
        /**
 
252
         * Collection of comments
 
253
         *
 
254
         * @var PHPExcel_Comment[]
 
255
         */
 
256
        private $_comments = array();
 
257
 
 
258
        /**
 
259
         * Active cell. (Only one!)
 
260
         *
 
261
         * @var string
 
262
         */
 
263
        private $_activeCell = 'A1';
 
264
 
 
265
        /**
 
266
         * Selected cells
 
267
         *
 
268
         * @var string
 
269
         */
 
270
        private $_selectedCells = 'A1';
 
271
 
 
272
        /**
 
273
         * Cached highest column
 
274
         *
 
275
         * @var string
 
276
         */
 
277
        private $_cachedHighestColumn = 'A';
 
278
 
 
279
        /**
 
280
         * Cached highest row
 
281
         *
 
282
         * @var int
 
283
         */
 
284
        private $_cachedHighestRow = 1;
 
285
 
 
286
        /**
 
287
         * Right-to-left?
 
288
         *
 
289
         * @var boolean
 
290
         */
 
291
        private $_rightToLeft = false;
 
292
 
 
293
        /**
 
294
         * Hyperlinks. Indexed by cell coordinate, e.g. 'A1'
 
295
         *
 
296
         * @var array
 
297
         */
 
298
        private $_hyperlinkCollection = array();
 
299
 
 
300
        /**
 
301
         * Data validation objects. Indexed by cell coordinate, e.g. 'A1'
 
302
         *
 
303
         * @var array
 
304
         */
 
305
        private $_dataValidationCollection = array();
 
306
 
 
307
        /**
 
308
         * Tab color
 
309
         *
 
310
         * @var PHPExcel_Style_Color
 
311
         */
 
312
        private $_tabColor;
 
313
 
 
314
        /**
 
315
         * Dirty flag
 
316
         *
 
317
         * @var boolean
 
318
         */
 
319
        private $_dirty = true;
 
320
 
 
321
        /**
 
322
         * Hash
 
323
         *
 
324
         * @var string
 
325
         */
 
326
        private $_hash  = null;
 
327
 
 
328
        /**
 
329
         * Create a new worksheet
 
330
         *
 
331
         * @param PHPExcel              $pParent
 
332
         * @param string                $pTitle
 
333
         */
 
334
        public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet')
 
335
        {
 
336
                // Set parent and title
 
337
                $this->_parent = $pParent;
 
338
                $this->setTitle($pTitle, FALSE);
 
339
                $this->setSheetState(PHPExcel_Worksheet::SHEETSTATE_VISIBLE);
 
340
 
 
341
                $this->_cellCollection          = PHPExcel_CachedObjectStorageFactory::getInstance($this);
 
342
 
 
343
                // Set page setup
 
344
                $this->_pageSetup                       = new PHPExcel_Worksheet_PageSetup();
 
345
 
 
346
                // Set page margins
 
347
                $this->_pageMargins                     = new PHPExcel_Worksheet_PageMargins();
 
348
 
 
349
                // Set page header/footer
 
350
                $this->_headerFooter            = new PHPExcel_Worksheet_HeaderFooter();
 
351
 
 
352
                // Set sheet view
 
353
                $this->_sheetView                       = new PHPExcel_Worksheet_SheetView();
 
354
 
 
355
                // Drawing collection
 
356
                $this->_drawingCollection       = new ArrayObject();
 
357
 
 
358
        // Chart collection
 
359
        $this->_chartCollection         = new ArrayObject();
 
360
 
 
361
                // Protection
 
362
                $this->_protection                      = new PHPExcel_Worksheet_Protection();
 
363
 
 
364
                // Default row dimension
 
365
                $this->_defaultRowDimension = new PHPExcel_Worksheet_RowDimension(NULL);
 
366
 
 
367
                // Default column dimension
 
368
                $this->_defaultColumnDimension  = new PHPExcel_Worksheet_ColumnDimension(NULL);
 
369
 
 
370
                $this->_autoFilter                      = new PHPExcel_Worksheet_AutoFilter(NULL, $this);
 
371
        }
 
372
 
 
373
 
 
374
        /**
 
375
         * Disconnect all cells from this PHPExcel_Worksheet object,
 
376
         *    typically so that the worksheet object can be unset
 
377
         *
 
378
         */
 
379
        public function disconnectCells() {
 
380
                $this->_cellCollection->unsetWorksheetCells();
 
381
                $this->_cellCollection = null;
 
382
 
 
383
                //      detach ourself from the workbook, so that it can then delete this worksheet successfully
 
384
                $this->_parent = null;
 
385
        }
 
386
 
 
387
        /**
 
388
         * Return the cache controller for the cell collection
 
389
         *
 
390
         * @return PHPExcel_CachedObjectStorage_xxx
 
391
         */
 
392
        public function getCellCacheController() {
 
393
                return $this->_cellCollection;
 
394
        }       //      function getCellCacheController()
 
395
 
 
396
 
 
397
        /**
 
398
         * Get array of invalid characters for sheet title
 
399
         *
 
400
         * @return array
 
401
         */
 
402
        public static function getInvalidCharacters()
 
403
        {
 
404
                return self::$_invalidCharacters;
 
405
        }
 
406
 
 
407
        /**
 
408
         * Check sheet title for valid Excel syntax
 
409
         *
 
410
         * @param string $pValue The string to check
 
411
         * @return string The valid string
 
412
         * @throws Exception
 
413
         */
 
414
        private static function _checkSheetTitle($pValue)
 
415
        {
 
416
                // Some of the printable ASCII characters are invalid:  * : / \ ? [ ]
 
417
                if (str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) {
 
418
                        throw new Exception('Invalid character found in sheet title');
 
419
                }
 
420
 
 
421
                // Maximum 31 characters allowed for sheet title
 
422
                if (PHPExcel_Shared_String::CountCharacters($pValue) > 31) {
 
423
                        throw new Exception('Maximum 31 characters allowed in sheet title.');
 
424
                }
 
425
 
 
426
                return $pValue;
 
427
        }
 
428
 
 
429
        /**
 
430
         * Get collection of cells
 
431
         *
 
432
         * @param boolean $pSorted Also sort the cell collection?
 
433
         * @return PHPExcel_Cell[]
 
434
         */
 
435
        public function getCellCollection($pSorted = true)
 
436
        {
 
437
                if ($pSorted) {
 
438
                        // Re-order cell collection
 
439
                        return $this->sortCellCollection();
 
440
                }
 
441
                if ($this->_cellCollection !== NULL) {
 
442
                        return $this->_cellCollection->getCellList();
 
443
                }
 
444
                return array();
 
445
        }
 
446
 
 
447
        /**
 
448
         * Sort collection of cells
 
449
         *
 
450
         * @return PHPExcel_Worksheet
 
451
         */
 
452
        public function sortCellCollection()
 
453
        {
 
454
                if ($this->_cellCollection !== NULL) {
 
455
                        return $this->_cellCollection->getSortedCellList();
 
456
                }
 
457
                return array();
 
458
        }
 
459
 
 
460
        /**
 
461
         * Get collection of row dimensions
 
462
         *
 
463
         * @return PHPExcel_Worksheet_RowDimension[]
 
464
         */
 
465
        public function getRowDimensions()
 
466
        {
 
467
                return $this->_rowDimensions;
 
468
        }
 
469
 
 
470
        /**
 
471
         * Get default row dimension
 
472
         *
 
473
         * @return PHPExcel_Worksheet_RowDimension
 
474
         */
 
475
        public function getDefaultRowDimension()
 
476
        {
 
477
                return $this->_defaultRowDimension;
 
478
        }
 
479
 
 
480
        /**
 
481
         * Get collection of column dimensions
 
482
         *
 
483
         * @return PHPExcel_Worksheet_ColumnDimension[]
 
484
         */
 
485
        public function getColumnDimensions()
 
486
        {
 
487
                return $this->_columnDimensions;
 
488
        }
 
489
 
 
490
        /**
 
491
         * Get default column dimension
 
492
         *
 
493
         * @return PHPExcel_Worksheet_ColumnDimension
 
494
         */
 
495
        public function getDefaultColumnDimension()
 
496
        {
 
497
                return $this->_defaultColumnDimension;
 
498
        }
 
499
 
 
500
        /**
 
501
         * Get collection of drawings
 
502
         *
 
503
         * @return PHPExcel_Worksheet_BaseDrawing[]
 
504
         */
 
505
        public function getDrawingCollection()
 
506
        {
 
507
                return $this->_drawingCollection;
 
508
        }
 
509
 
 
510
        /**
 
511
         * Get collection of charts
 
512
         *
 
513
         * @return PHPExcel_Chart[]
 
514
         */
 
515
        public function getChartCollection()
 
516
        {
 
517
                return $this->_chartCollection;
 
518
        }
 
519
 
 
520
        /**
 
521
         * Add chart
 
522
         *
 
523
         * @param PHPExcel_Chart $pChart
 
524
         * @param int|null $iChartIndex Index where chart should go (0,1,..., or null for last)
 
525
         * @return PHPExcel_Chart
 
526
         * @throws Exception
 
527
         */
 
528
        public function addChart(PHPExcel_Chart $pChart = null, $iChartIndex = null)
 
529
        {
 
530
                $pChart->setWorksheet($this);
 
531
                if (is_null($iChartIndex)) {
 
532
                        $this->_chartCollection[] = $pChart;
 
533
                } else {
 
534
                        // Insert the chart at the requested index
 
535
                        array_splice($this->_chartCollection, $iChartIndex, 0, array($pChart));
 
536
                }
 
537
 
 
538
                return $pChart;
 
539
        }
 
540
 
 
541
        /**
 
542
         * Return the count of charts on this worksheet
 
543
         *
 
544
         * @return int          The number of charts
 
545
         * @throws Exception
 
546
         */
 
547
        public function getChartCount()
 
548
        {
 
549
                return count($this->_chartCollection);
 
550
        }
 
551
 
 
552
        /**
 
553
         * Get a chart by its index position
 
554
         *
 
555
         * @param       string  $index                  Chart index position
 
556
         * @return      false|PHPExcel_Chart
 
557
         * @throws Exception
 
558
         */
 
559
        public function getChartByIndex($index = null)
 
560
        {
 
561
                $chartCount = count($this->_chartCollection);
 
562
                if ($chartCount == 0) {
 
563
                        return false;
 
564
                }
 
565
                if (is_null($index)) {
 
566
                        $index = --$chartCount;
 
567
                }
 
568
                if (!isset($this->_chartCollection[$index])) {
 
569
                        return false;
 
570
                }
 
571
 
 
572
                return $this->_chartCollection[$index];
 
573
        }
 
574
 
 
575
        /**
 
576
         * Return an array of the names of charts on this worksheet
 
577
         *
 
578
         * @return string[]             The names of charts
 
579
         * @throws Exception
 
580
         */
 
581
        public function getChartNames()
 
582
        {
 
583
                $chartNames = array();
 
584
                foreach($this->_chartCollection as $chart) {
 
585
                        $chartNames[] = $chart->getName();
 
586
                }
 
587
                return $chartNames;
 
588
        }
 
589
 
 
590
        /**
 
591
         * Get a chart by name
 
592
         *
 
593
         * @param       string  $chartName              Chart name
 
594
         * @return      false|PHPExcel_Chart
 
595
         * @throws Exception
 
596
         */
 
597
        public function getChartByName($chartName = '')
 
598
        {
 
599
                $chartCount = count($this->_chartCollection);
 
600
                if ($chartCount == 0) {
 
601
                        return false;
 
602
                }
 
603
                foreach($this->_chartCollection as $index => $chart) {
 
604
                        if ($chart->getName() == $chartName) {
 
605
                                return $this->_chartCollection[$index];
 
606
                        }
 
607
                }
 
608
                return false;
 
609
        }
 
610
 
 
611
        /**
 
612
         * Refresh column dimensions
 
613
         *
 
614
         * @return PHPExcel_Worksheet
 
615
         */
 
616
        public function refreshColumnDimensions()
 
617
        {
 
618
                $currentColumnDimensions = $this->getColumnDimensions();
 
619
                $newColumnDimensions = array();
 
620
 
 
621
                foreach ($currentColumnDimensions as $objColumnDimension) {
 
622
                        $newColumnDimensions[$objColumnDimension->getColumnIndex()] = $objColumnDimension;
 
623
                }
 
624
 
 
625
                $this->_columnDimensions = $newColumnDimensions;
 
626
 
 
627
                return $this;
 
628
        }
 
629
 
 
630
        /**
 
631
         * Refresh row dimensions
 
632
         *
 
633
         * @return PHPExcel_Worksheet
 
634
         */
 
635
        public function refreshRowDimensions()
 
636
        {
 
637
                $currentRowDimensions = $this->getRowDimensions();
 
638
                $newRowDimensions = array();
 
639
 
 
640
                foreach ($currentRowDimensions as $objRowDimension) {
 
641
                        $newRowDimensions[$objRowDimension->getRowIndex()] = $objRowDimension;
 
642
                }
 
643
 
 
644
                $this->_rowDimensions = $newRowDimensions;
 
645
 
 
646
                return $this;
 
647
        }
 
648
 
 
649
        /**
 
650
         * Calculate worksheet dimension
 
651
         *
 
652
         * @return string  String containing the dimension of this worksheet
 
653
         */
 
654
        public function calculateWorksheetDimension()
 
655
        {
 
656
                // Return
 
657
                return 'A1' . ':' .  $this->getHighestColumn() . $this->getHighestRow();
 
658
        }
 
659
 
 
660
        /**
 
661
         * Calculate worksheet data dimension
 
662
         *
 
663
         * @return string  String containing the dimension of this worksheet that actually contain data
 
664
         */
 
665
        public function calculateWorksheetDataDimension()
 
666
        {
 
667
                // Return
 
668
                return 'A1' . ':' .  $this->getHighestDataColumn() . $this->getHighestDataRow();
 
669
        }
 
670
 
 
671
        /**
 
672
         * Calculate widths for auto-size columns
 
673
         *
 
674
         * @param  boolean  $calculateMergeCells  Calculate merge cell width
 
675
         * @return PHPExcel_Worksheet;
 
676
         */
 
677
        public function calculateColumnWidths($calculateMergeCells = false)
 
678
        {
 
679
                // initialize $autoSizes array
 
680
                $autoSizes = array();
 
681
                foreach ($this->getColumnDimensions() as $colDimension) {
 
682
                        if ($colDimension->getAutoSize()) {
 
683
                                $autoSizes[$colDimension->getColumnIndex()] = -1;
 
684
                        }
 
685
                }
 
686
 
 
687
                // There is only something to do if there are some auto-size columns
 
688
                if (!empty($autoSizes)) {
 
689
 
 
690
                        // build list of cells references that participate in a merge
 
691
                        $isMergeCell = array();
 
692
                        foreach ($this->getMergeCells() as $cells) {
 
693
                                foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cells) as $cellReference) {
 
694
                                        $isMergeCell[$cellReference] = true;
 
695
                                }
 
696
                        }
 
697
 
 
698
                        // loop through all cells in the worksheet
 
699
                        foreach ($this->getCellCollection(false) as $cellID) {
 
700
                                $cell = $this->getCell($cellID);
 
701
                                if (isset($autoSizes[$cell->getColumn()])) {
 
702
                                        // Determine width if cell does not participate in a merge
 
703
                                        if (!isset($isMergeCell[$cell->getCoordinate()])) {
 
704
                                                // Calculated value
 
705
                                                $cellValue = $cell->getCalculatedValue();
 
706
 
 
707
                                                // To formatted string
 
708
                                                $cellValue = PHPExcel_Style_NumberFormat::toFormattedString($cellValue, $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode());
 
709
 
 
710
                                                $autoSizes[$cell->getColumn()] = max(
 
711
                                                        (float)$autoSizes[$cell->getColumn()],
 
712
                                                        (float)PHPExcel_Shared_Font::calculateColumnWidth(
 
713
                                                                $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(),
 
714
                                                                $cellValue,
 
715
                                                                $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(),
 
716
                                                                $this->getDefaultStyle()->getFont()
 
717
                                                        )
 
718
                                                );
 
719
                                        }
 
720
                                }
 
721
                        }
 
722
 
 
723
                        // adjust column widths
 
724
                        foreach ($autoSizes as $columnIndex => $width) {
 
725
                                if ($width == -1) $width = $this->getDefaultColumnDimension()->getWidth();
 
726
                                $this->getColumnDimension($columnIndex)->setWidth($width);
 
727
                        }
 
728
                }
 
729
 
 
730
                return $this;
 
731
        }
 
732
 
 
733
        /**
 
734
         * Get parent
 
735
         *
 
736
         * @return PHPExcel
 
737
         */
 
738
        public function getParent() {
 
739
                return $this->_parent;
 
740
        }
 
741
 
 
742
        /**
 
743
         * Re-bind parent
 
744
         *
 
745
         * @param PHPExcel $parent
 
746
         * @return PHPExcel_Worksheet
 
747
         */
 
748
        public function rebindParent(PHPExcel $parent) {
 
749
                $namedRanges = $this->_parent->getNamedRanges();
 
750
                foreach ($namedRanges as $namedRange) {
 
751
                        $parent->addNamedRange($namedRange);
 
752
                }
 
753
 
 
754
                $this->_parent->removeSheetByIndex(
 
755
                        $this->_parent->getIndex($this)
 
756
                );
 
757
                $this->_parent = $parent;
 
758
 
 
759
                return $this;
 
760
        }
 
761
 
 
762
        /**
 
763
         * Get title
 
764
         *
 
765
         * @return string
 
766
         */
 
767
        public function getTitle()
 
768
        {
 
769
                return $this->_title;
 
770
        }
 
771
 
 
772
        /**
 
773
         * Set title
 
774
         *
 
775
         * @param string $pValue String containing the dimension of this worksheet
 
776
         * @param string $updateFormulaCellReferences boolean Flag indicating whether cell references in formulae should
 
777
         *                                                    be updated to reflect the new sheet name.
 
778
         *                                                    This should be left as the default true, unless you are
 
779
         *                                                    certain that no formula cells on any worksheet contain
 
780
         *                                                    references to this worksheet
 
781
         * @return PHPExcel_Worksheet
 
782
         */
 
783
        public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = true)
 
784
        {
 
785
                // Is this a 'rename' or not?
 
786
                if ($this->getTitle() == $pValue) {
 
787
                        return $this;
 
788
                }
 
789
 
 
790
                // Syntax check
 
791
                self::_checkSheetTitle($pValue);
 
792
 
 
793
                // Old title
 
794
                $oldTitle = $this->getTitle();
 
795
 
 
796
        if ($this->getParent()) {
 
797
                        // Is there already such sheet name?
 
798
                        if ($this->getParent()->sheetNameExists($pValue)) {
 
799
                                // Use name, but append with lowest possible integer
 
800
 
 
801
                                if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) {
 
802
                                        $pValue = PHPExcel_Shared_String::Substring($pValue,0,29);
 
803
                                }
 
804
                                $i = 1;
 
805
                                while ($this->getParent()->sheetNameExists($pValue . ' ' . $i)) {
 
806
                                        ++$i;
 
807
                                        if ($i == 10) {
 
808
                                                if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) {
 
809
                                                        $pValue = PHPExcel_Shared_String::Substring($pValue,0,28);
 
810
                                                }
 
811
                                        } elseif ($i == 100) {
 
812
                                                if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) {
 
813
                                                        $pValue = PHPExcel_Shared_String::Substring($pValue,0,27);
 
814
                                                }
 
815
                                        }
 
816
                                }
 
817
 
 
818
                                $altTitle = $pValue . ' ' . $i;
 
819
                                return $this->setTitle($altTitle,$updateFormulaCellReferences);
 
820
                        }
 
821
                }
 
822
 
 
823
                // Set title
 
824
                $this->_title = $pValue;
 
825
                $this->_dirty = true;
 
826
 
 
827
        if ($this->getParent()) {
 
828
                        // New title
 
829
                        $newTitle = $this->getTitle();
 
830
                        if ($updateFormulaCellReferences)
 
831
                                PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->getParent(), $oldTitle, $newTitle);
 
832
                }
 
833
 
 
834
                return $this;
 
835
        }
 
836
 
 
837
        /**
 
838
         * Get sheet state
 
839
         *
 
840
         * @return string Sheet state (visible, hidden, veryHidden)
 
841
         */
 
842
        public function getSheetState() {
 
843
                return $this->_sheetState;
 
844
        }
 
845
 
 
846
        /**
 
847
         * Set sheet state
 
848
         *
 
849
         * @param string $value Sheet state (visible, hidden, veryHidden)
 
850
         * @return PHPExcel_Worksheet
 
851
         */
 
852
        public function setSheetState($value = PHPExcel_Worksheet::SHEETSTATE_VISIBLE) {
 
853
                $this->_sheetState = $value;
 
854
                return $this;
 
855
        }
 
856
 
 
857
        /**
 
858
         * Get page setup
 
859
         *
 
860
         * @return PHPExcel_Worksheet_PageSetup
 
861
         */
 
862
        public function getPageSetup()
 
863
        {
 
864
                return $this->_pageSetup;
 
865
        }
 
866
 
 
867
        /**
 
868
         * Set page setup
 
869
         *
 
870
         * @param PHPExcel_Worksheet_PageSetup  $pValue
 
871
         * @return PHPExcel_Worksheet
 
872
         */
 
873
        public function setPageSetup(PHPExcel_Worksheet_PageSetup $pValue)
 
874
        {
 
875
                $this->_pageSetup = $pValue;
 
876
                return $this;
 
877
        }
 
878
 
 
879
        /**
 
880
         * Get page margins
 
881
         *
 
882
         * @return PHPExcel_Worksheet_PageMargins
 
883
         */
 
884
        public function getPageMargins()
 
885
        {
 
886
                return $this->_pageMargins;
 
887
        }
 
888
 
 
889
        /**
 
890
         * Set page margins
 
891
         *
 
892
         * @param PHPExcel_Worksheet_PageMargins        $pValue
 
893
         * @return PHPExcel_Worksheet
 
894
         */
 
895
        public function setPageMargins(PHPExcel_Worksheet_PageMargins $pValue)
 
896
        {
 
897
                $this->_pageMargins = $pValue;
 
898
                return $this;
 
899
        }
 
900
 
 
901
        /**
 
902
         * Get page header/footer
 
903
         *
 
904
         * @return PHPExcel_Worksheet_HeaderFooter
 
905
         */
 
906
        public function getHeaderFooter()
 
907
        {
 
908
                return $this->_headerFooter;
 
909
        }
 
910
 
 
911
        /**
 
912
         * Set page header/footer
 
913
         *
 
914
         * @param PHPExcel_Worksheet_HeaderFooter       $pValue
 
915
         * @return PHPExcel_Worksheet
 
916
         */
 
917
        public function setHeaderFooter(PHPExcel_Worksheet_HeaderFooter $pValue)
 
918
        {
 
919
                $this->_headerFooter = $pValue;
 
920
                return $this;
 
921
        }
 
922
 
 
923
        /**
 
924
         * Get sheet view
 
925
         *
 
926
         * @return PHPExcel_Worksheet_HeaderFooter
 
927
         */
 
928
        public function getSheetView()
 
929
        {
 
930
                return $this->_sheetView;
 
931
        }
 
932
 
 
933
        /**
 
934
         * Set sheet view
 
935
         *
 
936
         * @param PHPExcel_Worksheet_SheetView  $pValue
 
937
         * @return PHPExcel_Worksheet
 
938
         */
 
939
        public function setSheetView(PHPExcel_Worksheet_SheetView $pValue)
 
940
        {
 
941
                $this->_sheetView = $pValue;
 
942
                return $this;
 
943
        }
 
944
 
 
945
        /**
 
946
         * Get Protection
 
947
         *
 
948
         * @return PHPExcel_Worksheet_Protection
 
949
         */
 
950
        public function getProtection()
 
951
        {
 
952
                return $this->_protection;
 
953
        }
 
954
 
 
955
        /**
 
956
         * Set Protection
 
957
         *
 
958
         * @param PHPExcel_Worksheet_Protection $pValue
 
959
         * @return PHPExcel_Worksheet
 
960
         */
 
961
        public function setProtection(PHPExcel_Worksheet_Protection $pValue)
 
962
        {
 
963
                $this->_protection = $pValue;
 
964
                $this->_dirty = true;
 
965
 
 
966
                return $this;
 
967
        }
 
968
 
 
969
        /**
 
970
         * Get highest worksheet column
 
971
         *
 
972
         * @return string Highest column name
 
973
         */
 
974
        public function getHighestColumn()
 
975
        {
 
976
                return $this->_cachedHighestColumn;
 
977
        }
 
978
 
 
979
        /**
 
980
         * Get highest worksheet column that contains data
 
981
         *
 
982
         * @return string Highest column name that contains data
 
983
         */
 
984
        public function getHighestDataColumn()
 
985
        {
 
986
                return $this->_cellCollection->getHighestColumn();
 
987
        }
 
988
 
 
989
        /**
 
990
         * Get highest worksheet row
 
991
         *
 
992
         * @return int Highest row number
 
993
         */
 
994
        public function getHighestRow()
 
995
        {
 
996
                return $this->_cachedHighestRow;
 
997
        }
 
998
 
 
999
        /**
 
1000
         * Get highest worksheet row that contains data
 
1001
         *
 
1002
         * @return string Highest row number that contains data
 
1003
         */
 
1004
        public function getHighestDataRow()
 
1005
        {
 
1006
                return $this->_cellCollection->getHighestRow();
 
1007
        }
 
1008
 
 
1009
        /**
 
1010
         * Get highest worksheet column and highest row that have cell records
 
1011
         *
 
1012
         * @return array Highest column name and highest row number
 
1013
         */
 
1014
        public function getHighestRowAndColumn()
 
1015
        {
 
1016
                return $this->_cellCollection->getHighestRowAndColumn();
 
1017
        }
 
1018
 
 
1019
        /**
 
1020
         * Set a cell value
 
1021
         *
 
1022
         * @param string        $pCoordinate    Coordinate of the cell
 
1023
         * @param mixed $pValue                 Value of the cell
 
1024
         * @param bool          $returnCell             Return the worksheet (false, default) or the cell (true)
 
1025
         * @return PHPExcel_Worksheet|PHPExcel_Cell     Depending on the last parameter being specified
 
1026
         */
 
1027
        public function setCellValue($pCoordinate = 'A1', $pValue = null, $returnCell = false)
 
1028
        {
 
1029
                $cell = $this->getCell($pCoordinate)->setValue($pValue);
 
1030
                return ($returnCell) ? $cell : $this;
 
1031
        }
 
1032
 
 
1033
        /**
 
1034
         * Set a cell value by using numeric cell coordinates
 
1035
         *
 
1036
         * @param string        $pColumn                Numeric column coordinate of the cell
 
1037
         * @param string        $pRow                   Numeric row coordinate of the cell
 
1038
         * @param mixed         $pValue                 Value of the cell
 
1039
         * @param bool          $returnCell             Return the worksheet (false, default) or the cell (true)
 
1040
         * @return PHPExcel_Worksheet|PHPExcel_Cell     Depending on the last parameter being specified
 
1041
         */
 
1042
        public function setCellValueByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $returnCell = false)
 
1043
        {
 
1044
                $cell = $this->getCell(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow)->setValue($pValue);
 
1045
                return ($returnCell) ? $cell : $this;
 
1046
        }
 
1047
 
 
1048
        /**
 
1049
         * Set a cell value
 
1050
         *
 
1051
         * @param string        $pCoordinate    Coordinate of the cell
 
1052
         * @param mixed $pValue                 Value of the cell
 
1053
         * @param string        $pDataType              Explicit data type
 
1054
         * @param bool          $returnCell             Return the worksheet (false, default) or the cell (true)
 
1055
         * @return PHPExcel_Worksheet|PHPExcel_Cell     Depending on the last parameter being specified
 
1056
         */
 
1057
        public function setCellValueExplicit($pCoordinate = 'A1', $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false)
 
1058
        {
 
1059
                // Set value
 
1060
                $cell = $this->getCell($pCoordinate)->setValueExplicit($pValue, $pDataType);
 
1061
                return ($returnCell) ? $cell : $this;
 
1062
        }
 
1063
 
 
1064
        /**
 
1065
         * Set a cell value by using numeric cell coordinates
 
1066
         *
 
1067
         * @param string        $pColumn                Numeric column coordinate of the cell
 
1068
         * @param string        $pRow                   Numeric row coordinate of the cell
 
1069
         * @param mixed         $pValue                 Value of the cell
 
1070
         * @param string        $pDataType              Explicit data type
 
1071
         * @param bool          $returnCell             Return the worksheet (false, default) or the cell (true)
 
1072
         * @return PHPExcel_Worksheet|PHPExcel_Cell     Depending on the last parameter being specified
 
1073
         */
 
1074
        public function setCellValueExplicitByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false)
 
1075
        {
 
1076
                $cell = $this->getCell(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow)->setValueExplicit($pValue, $pDataType);
 
1077
                return ($returnCell) ? $cell : $this;
 
1078
        }
 
1079
 
 
1080
        /**
 
1081
         * Get cell at a specific coordinate
 
1082
         *
 
1083
         * @param       string                  $pCoordinate    Coordinate of the cell
 
1084
         * @throws      Exception
 
1085
         * @return      PHPExcel_Cell   Cell that was found
 
1086
         */
 
1087
        public function getCell($pCoordinate = 'A1')
 
1088
        {
 
1089
                // Check cell collection
 
1090
                if ($this->_cellCollection->isDataSet($pCoordinate)) {
 
1091
                        return $this->_cellCollection->getCacheData($pCoordinate);
 
1092
                }
 
1093
 
 
1094
                // Worksheet reference?
 
1095
                if (strpos($pCoordinate, '!') !== false) {
 
1096
                        $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true);
 
1097
                        return $this->getParent()->getSheetByName($worksheetReference[0])->getCell($worksheetReference[1]);
 
1098
                }
 
1099
 
 
1100
                // Named range?
 
1101
                if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) &&
 
1102
                        (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) {
 
1103
                        $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this);
 
1104
                        if ($namedRange !== NULL) {
 
1105
                                $pCoordinate = $namedRange->getRange();
 
1106
                                return $namedRange->getWorksheet()->getCell($pCoordinate);
 
1107
                        }
 
1108
                }
 
1109
 
 
1110
                // Uppercase coordinate
 
1111
                $pCoordinate = strtoupper($pCoordinate);
 
1112
 
 
1113
                if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) {
 
1114
                        throw new Exception('Cell coordinate can not be a range of cells.');
 
1115
                } elseif (strpos($pCoordinate,'$') !== false) {
 
1116
                        throw new Exception('Cell coordinate must not be absolute.');
 
1117
                } else {
 
1118
                        // Create new cell object
 
1119
 
 
1120
                        // Coordinates
 
1121
                        $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate);
 
1122
 
 
1123
                        $cell = $this->_cellCollection->addCacheData($pCoordinate,new PHPExcel_Cell($aCoordinates[0], $aCoordinates[1], null, PHPExcel_Cell_DataType::TYPE_NULL, $this));
 
1124
                        $this->_cellCollectionIsSorted = false;
 
1125
 
 
1126
                        if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0]))
 
1127
                                $this->_cachedHighestColumn = $aCoordinates[0];
 
1128
 
 
1129
                        $this->_cachedHighestRow = max($this->_cachedHighestRow,$aCoordinates[1]);
 
1130
 
 
1131
                        // Cell needs appropriate xfIndex
 
1132
                        $rowDimensions  = $this->getRowDimensions();
 
1133
                        $columnDimensions = $this->getColumnDimensions();
 
1134
 
 
1135
                        if ( isset($rowDimensions[$aCoordinates[1]]) && $rowDimensions[$aCoordinates[1]]->getXfIndex() !== null ) {
 
1136
                                // then there is a row dimension with explicit style, assign it to the cell
 
1137
                                $cell->setXfIndex($rowDimensions[$aCoordinates[1]]->getXfIndex());
 
1138
                        } else if ( isset($columnDimensions[$aCoordinates[0]]) ) {
 
1139
                                // then there is a column dimension, assign it to the cell
 
1140
                                $cell->setXfIndex($columnDimensions[$aCoordinates[0]]->getXfIndex());
 
1141
                        } else {
 
1142
                                // set to default index
 
1143
                                $cell->setXfIndex(0);
 
1144
                        }
 
1145
 
 
1146
                        return $cell;
 
1147
                }
 
1148
        }
 
1149
 
 
1150
        /**
 
1151
         * Get cell at a specific coordinate by using numeric cell coordinates
 
1152
         *
 
1153
         * @param       string $pColumn         Numeric column coordinate of the cell
 
1154
         * @param       string $pRow            Numeric row coordinate of the cell
 
1155
         * @return      PHPExcel_Cell           Cell that was found
 
1156
         */
 
1157
        public function getCellByColumnAndRow($pColumn = 0, $pRow = 1)
 
1158
        {
 
1159
                $columnLetter = PHPExcel_Cell::stringFromColumnIndex($pColumn);
 
1160
                $coordinate = $columnLetter . $pRow;
 
1161
 
 
1162
                if (!$this->_cellCollection->isDataSet($coordinate)) {
 
1163
                        $cell = $this->_cellCollection->addCacheData($coordinate, new PHPExcel_Cell($columnLetter, $pRow, null, PHPExcel_Cell_DataType::TYPE_NULL, $this));
 
1164
                        $this->_cellCollectionIsSorted = false;
 
1165
 
 
1166
                        if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < $pColumn)
 
1167
                                $this->_cachedHighestColumn = $columnLetter;
 
1168
 
 
1169
                        $this->_cachedHighestRow = max($this->_cachedHighestRow,$pRow);
 
1170
 
 
1171
                        return $cell;
 
1172
                }
 
1173
 
 
1174
                return $this->_cellCollection->getCacheData($coordinate);
 
1175
        }
 
1176
 
 
1177
        /**
 
1178
         * Cell at a specific coordinate exists?
 
1179
         *
 
1180
         * @param       string                  $pCoordinate    Coordinate of the cell
 
1181
         * @throws      Exception
 
1182
         * @return      boolean
 
1183
         */
 
1184
        public function cellExists($pCoordinate = 'A1')
 
1185
        {
 
1186
                // Worksheet reference?
 
1187
                if (strpos($pCoordinate, '!') !== false) {
 
1188
                        $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true);
 
1189
                        return $this->getParent()->getSheetByName($worksheetReference[0])->cellExists($worksheetReference[1]);
 
1190
                }
 
1191
 
 
1192
                // Named range?
 
1193
                if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) &&
 
1194
                        (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) {
 
1195
                        $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this);
 
1196
                        if ($namedRange !== NULL) {
 
1197
                                $pCoordinate = $namedRange->getRange();
 
1198
                                if ($this->getHashCode() != $namedRange->getWorksheet()->getHashCode()) {
 
1199
                                        if (!$namedRange->getLocalOnly()) {
 
1200
                                                return $namedRange->getWorksheet()->cellExists($pCoordinate);
 
1201
                                        } else {
 
1202
                                                throw new Exception('Named range ' . $namedRange->getName() . ' is not accessible from within sheet ' . $this->getTitle());
 
1203
                                        }
 
1204
                                }
 
1205
                        }
 
1206
                }
 
1207
 
 
1208
                // Uppercase coordinate
 
1209
                $pCoordinate = strtoupper($pCoordinate);
 
1210
 
 
1211
                if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) {
 
1212
                        throw new Exception('Cell coordinate can not be a range of cells.');
 
1213
                } elseif (strpos($pCoordinate,'$') !== false) {
 
1214
                        throw new Exception('Cell coordinate must not be absolute.');
 
1215
                } else {
 
1216
                        // Coordinates
 
1217
                        $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate);
 
1218
 
 
1219
                        // Cell exists?
 
1220
                        return $this->_cellCollection->isDataSet($pCoordinate);
 
1221
                }
 
1222
        }
 
1223
 
 
1224
        /**
 
1225
         * Cell at a specific coordinate by using numeric cell coordinates exists?
 
1226
         *
 
1227
         * @param       string $pColumn         Numeric column coordinate of the cell
 
1228
         * @param       string $pRow            Numeric row coordinate of the cell
 
1229
         * @return      boolean
 
1230
         */
 
1231
        public function cellExistsByColumnAndRow($pColumn = 0, $pRow = 1)
 
1232
        {
 
1233
                return $this->cellExists(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
 
1234
        }
 
1235
 
 
1236
        /**
 
1237
         * Get row dimension at a specific row
 
1238
         *
 
1239
         * @param int $pRow     Numeric index of the row
 
1240
         * @return PHPExcel_Worksheet_RowDimension
 
1241
         */
 
1242
        public function getRowDimension($pRow = 1)
 
1243
        {
 
1244
                // Found
 
1245
                $found = null;
 
1246
 
 
1247
                // Get row dimension
 
1248
                if (!isset($this->_rowDimensions[$pRow])) {
 
1249
                        $this->_rowDimensions[$pRow] = new PHPExcel_Worksheet_RowDimension($pRow);
 
1250
 
 
1251
                        $this->_cachedHighestRow = max($this->_cachedHighestRow,$pRow);
 
1252
                }
 
1253
                return $this->_rowDimensions[$pRow];
 
1254
        }
 
1255
 
 
1256
        /**
 
1257
         * Get column dimension at a specific column
 
1258
         *
 
1259
         * @param string $pColumn       String index of the column
 
1260
         * @return PHPExcel_Worksheet_ColumnDimension
 
1261
         */
 
1262
        public function getColumnDimension($pColumn = 'A')
 
1263
        {
 
1264
                // Uppercase coordinate
 
1265
                $pColumn = strtoupper($pColumn);
 
1266
 
 
1267
                // Fetch dimensions
 
1268
                if (!isset($this->_columnDimensions[$pColumn])) {
 
1269
                        $this->_columnDimensions[$pColumn] = new PHPExcel_Worksheet_ColumnDimension($pColumn);
 
1270
 
 
1271
                        if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($pColumn))
 
1272
                                $this->_cachedHighestColumn = $pColumn;
 
1273
                }
 
1274
                return $this->_columnDimensions[$pColumn];
 
1275
        }
 
1276
 
 
1277
        /**
 
1278
         * Get column dimension at a specific column by using numeric cell coordinates
 
1279
         *
 
1280
         * @param       string $pColumn         Numeric column coordinate of the cell
 
1281
         * @return      PHPExcel_Worksheet_ColumnDimension
 
1282
         */
 
1283
        public function getColumnDimensionByColumn($pColumn = 0)
 
1284
        {
 
1285
                return $this->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($pColumn));
 
1286
        }
 
1287
 
 
1288
        /**
 
1289
         * Get styles
 
1290
         *
 
1291
         * @return PHPExcel_Style[]
 
1292
         */
 
1293
        public function getStyles()
 
1294
        {
 
1295
                return $this->_styles;
 
1296
        }
 
1297
 
 
1298
        /**
 
1299
         * Get default style of workbork.
 
1300
         *
 
1301
         * @deprecated
 
1302
         * @return      PHPExcel_Style
 
1303
         * @throws      Exception
 
1304
         */
 
1305
        public function getDefaultStyle()
 
1306
        {
 
1307
                return $this->_parent->getDefaultStyle();
 
1308
        }
 
1309
 
 
1310
        /**
 
1311
         * Set default style - should only be used by PHPExcel_IReader implementations!
 
1312
         *
 
1313
         * @deprecated
 
1314
         * @param       PHPExcel_Style  $pValue
 
1315
         * @throws      Exception
 
1316
         * @return PHPExcel_Worksheet
 
1317
         */
 
1318
        public function setDefaultStyle(PHPExcel_Style $pValue)
 
1319
        {
 
1320
                $this->_parent->getDefaultStyle()->applyFromArray(array(
 
1321
                        'font' => array(
 
1322
                                'name' => $pValue->getFont()->getName(),
 
1323
                                'size' => $pValue->getFont()->getSize(),
 
1324
                        ),
 
1325
                ));
 
1326
                return $this;
 
1327
        }
 
1328
 
 
1329
        /**
 
1330
         * Get style for cell
 
1331
         *
 
1332
         * @param       string  $pCellCoordinate        Cell coordinate to get style for
 
1333
         * @return      PHPExcel_Style
 
1334
         * @throws      Exception
 
1335
         */
 
1336
        public function getStyle($pCellCoordinate = 'A1')
 
1337
        {
 
1338
                // set this sheet as active
 
1339
                $this->_parent->setActiveSheetIndex($this->_parent->getIndex($this));
 
1340
 
 
1341
                // set cell coordinate as active
 
1342
                $this->setSelectedCells($pCellCoordinate);
 
1343
 
 
1344
                return $this->_parent->getCellXfSupervisor();
 
1345
        }
 
1346
 
 
1347
        /**
 
1348
         * Get conditional styles for a cell
 
1349
         *
 
1350
         * @param string $pCoordinate
 
1351
         * @return PHPExcel_Style_Conditional[]
 
1352
         */
 
1353
        public function getConditionalStyles($pCoordinate = 'A1')
 
1354
        {
 
1355
                if (!isset($this->_conditionalStylesCollection[$pCoordinate])) {
 
1356
                        $this->_conditionalStylesCollection[$pCoordinate] = array();
 
1357
                }
 
1358
                return $this->_conditionalStylesCollection[$pCoordinate];
 
1359
        }
 
1360
 
 
1361
        /**
 
1362
         * Do conditional styles exist for this cell?
 
1363
         *
 
1364
         * @param string $pCoordinate
 
1365
         * @return boolean
 
1366
         */
 
1367
        public function conditionalStylesExists($pCoordinate = 'A1')
 
1368
        {
 
1369
                if (isset($this->_conditionalStylesCollection[$pCoordinate])) {
 
1370
                        return true;
 
1371
                }
 
1372
                return false;
 
1373
        }
 
1374
 
 
1375
        /**
 
1376
         * Removes conditional styles for a cell
 
1377
         *
 
1378
         * @param string $pCoordinate
 
1379
         * @return PHPExcel_Worksheet
 
1380
         */
 
1381
        public function removeConditionalStyles($pCoordinate = 'A1')
 
1382
        {
 
1383
                unset($this->_conditionalStylesCollection[$pCoordinate]);
 
1384
                return $this;
 
1385
        }
 
1386
 
 
1387
        /**
 
1388
         * Get collection of conditional styles
 
1389
         *
 
1390
         * @return array
 
1391
         */
 
1392
        public function getConditionalStylesCollection()
 
1393
        {
 
1394
                return $this->_conditionalStylesCollection;
 
1395
        }
 
1396
 
 
1397
        /**
 
1398
         * Set conditional styles
 
1399
         *
 
1400
         * @param $pCoordinate string E.g. 'A1'
 
1401
         * @param $pValue PHPExcel_Style_Conditional[]
 
1402
         * @return PHPExcel_Worksheet
 
1403
         */
 
1404
        public function setConditionalStyles($pCoordinate = 'A1', $pValue)
 
1405
        {
 
1406
                $this->_conditionalStylesCollection[$pCoordinate] = $pValue;
 
1407
                return $this;
 
1408
        }
 
1409
 
 
1410
        /**
 
1411
         * Get style for cell by using numeric cell coordinates
 
1412
         *
 
1413
         * @param       int $pColumn    Numeric column coordinate of the cell
 
1414
         * @param       int $pRow               Numeric row coordinate of the cell
 
1415
         * @return      PHPExcel_Style
 
1416
         */
 
1417
        public function getStyleByColumnAndRow($pColumn = 0, $pRow = 1)
 
1418
        {
 
1419
                return $this->getStyle(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
 
1420
        }
 
1421
 
 
1422
        /**
 
1423
         * Set shared cell style to a range of cells
 
1424
         *
 
1425
         * Please note that this will overwrite existing cell styles for cells in range!
 
1426
         *
 
1427
         * @deprecated
 
1428
         * @param       PHPExcel_Style  $pSharedCellStyle       Cell style to share
 
1429
         * @param       string                  $pRange                         Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
 
1430
         * @throws      Exception
 
1431
         * @return PHPExcel_Worksheet
 
1432
         */
 
1433
        public function setSharedStyle(PHPExcel_Style $pSharedCellStyle = null, $pRange = '')
 
1434
        {
 
1435
                $this->duplicateStyle($pSharedCellStyle, $pRange);
 
1436
                return $this;
 
1437
        }
 
1438
 
 
1439
        /**
 
1440
         * Duplicate cell style to a range of cells
 
1441
         *
 
1442
         * Please note that this will overwrite existing cell styles for cells in range!
 
1443
         *
 
1444
         * @param       PHPExcel_Style  $pCellStyle     Cell style to duplicate
 
1445
         * @param       string                  $pRange         Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
 
1446
         * @throws      Exception
 
1447
         * @return PHPExcel_Worksheet
 
1448
         */
 
1449
        public function duplicateStyle(PHPExcel_Style $pCellStyle = null, $pRange = '')
 
1450
        {
 
1451
                // make sure we have a real style and not supervisor
 
1452
                $style = $pCellStyle->getIsSupervisor() ? $pCellStyle->getSharedComponent() : $pCellStyle;
 
1453
 
 
1454
                // Add the style to the workbook if necessary
 
1455
                $workbook = $this->_parent;
 
1456
                if ($existingStyle = $this->_parent->getCellXfByHashCode($pCellStyle->getHashCode())) {
 
1457
                        // there is already such cell Xf in our collection
 
1458
                        $xfIndex = $existingStyle->getIndex();
 
1459
                } else {
 
1460
                        // we don't have such a cell Xf, need to add
 
1461
                        $workbook->addCellXf($pCellStyle);
 
1462
                        $xfIndex = $pCellStyle->getIndex();
 
1463
                }
 
1464
 
 
1465
                // Uppercase coordinate
 
1466
                $pRange = strtoupper($pRange);
 
1467
 
 
1468
                // Is it a cell range or a single cell?
 
1469
                $rangeA = '';
 
1470
                $rangeB = '';
 
1471
                if (strpos($pRange, ':') === false) {
 
1472
                        $rangeA = $pRange;
 
1473
                        $rangeB = $pRange;
 
1474
                } else {
 
1475
                        list($rangeA, $rangeB) = explode(':', $pRange);
 
1476
                }
 
1477
 
 
1478
                // Calculate range outer borders
 
1479
                $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA);
 
1480
                $rangeEnd       = PHPExcel_Cell::coordinateFromString($rangeB);
 
1481
 
 
1482
                // Translate column into index
 
1483
                $rangeStart[0]  = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1;
 
1484
                $rangeEnd[0]    = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1;
 
1485
 
 
1486
                // Make sure we can loop upwards on rows and columns
 
1487
                if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {
 
1488
                        $tmp = $rangeStart;
 
1489
                        $rangeStart = $rangeEnd;
 
1490
                        $rangeEnd = $tmp;
 
1491
                }
 
1492
 
 
1493
                // Loop through cells and apply styles
 
1494
                for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
 
1495
                        for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
 
1496
                                $this->getCell(PHPExcel_Cell::stringFromColumnIndex($col) . $row)->setXfIndex($xfIndex);
 
1497
                        }
 
1498
                }
 
1499
 
 
1500
                return $this;
 
1501
        }
 
1502
 
 
1503
        /**
 
1504
         * Duplicate conditional style to a range of cells
 
1505
         *
 
1506
         * Please note that this will overwrite existing cell styles for cells in range!
 
1507
         *
 
1508
         * @param       array of PHPExcel_Style_Conditional     $pCellStyle     Cell style to duplicate
 
1509
         * @param       string                                                          $pRange         Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
 
1510
         * @throws      Exception
 
1511
         * @return PHPExcel_Worksheet
 
1512
         */
 
1513
        public function duplicateConditionalStyle(array $pCellStyle = null, $pRange = '')
 
1514
        {
 
1515
                foreach($pCellStyle as $cellStyle) {
 
1516
                        if (!is_a($cellStyle,'PHPExcel_Style_Conditional')) {
 
1517
                                throw new Exception('Style is not a conditional style');
 
1518
                        }
 
1519
                }
 
1520
 
 
1521
                // Uppercase coordinate
 
1522
                $pRange = strtoupper($pRange);
 
1523
 
 
1524
                // Is it a cell range or a single cell?
 
1525
                $rangeA = '';
 
1526
                $rangeB = '';
 
1527
                if (strpos($pRange, ':') === false) {
 
1528
                        $rangeA = $pRange;
 
1529
                        $rangeB = $pRange;
 
1530
                } else {
 
1531
                        list($rangeA, $rangeB) = explode(':', $pRange);
 
1532
                }
 
1533
 
 
1534
                // Calculate range outer borders
 
1535
                $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA);
 
1536
                $rangeEnd       = PHPExcel_Cell::coordinateFromString($rangeB);
 
1537
 
 
1538
                // Translate column into index
 
1539
                $rangeStart[0]  = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1;
 
1540
                $rangeEnd[0]    = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1;
 
1541
 
 
1542
                // Make sure we can loop upwards on rows and columns
 
1543
                if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {
 
1544
                        $tmp = $rangeStart;
 
1545
                        $rangeStart = $rangeEnd;
 
1546
                        $rangeEnd = $tmp;
 
1547
                }
 
1548
 
 
1549
                // Loop through cells and apply styles
 
1550
                for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
 
1551
                        for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
 
1552
                                $this->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($col) . $row, $pCellStyle);
 
1553
                        }
 
1554
                }
 
1555
 
 
1556
                return $this;
 
1557
        }
 
1558
 
 
1559
        /**
 
1560
         * Duplicate cell style array to a range of cells
 
1561
         *
 
1562
         * Please note that this will overwrite existing cell styles for cells in range,
 
1563
         * if they are in the styles array. For example, if you decide to set a range of
 
1564
         * cells to font bold, only include font bold in the styles array.
 
1565
         *
 
1566
         * @deprecated
 
1567
         * @param       array                   $pStyles        Array containing style information
 
1568
         * @param       string                  $pRange         Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
 
1569
         * @param       boolean                 $pAdvanced      Advanced mode for setting borders.
 
1570
         * @throws      Exception
 
1571
         * @return PHPExcel_Worksheet
 
1572
         */
 
1573
        public function duplicateStyleArray($pStyles = null, $pRange = '', $pAdvanced = true)
 
1574
        {
 
1575
                $this->getStyle($pRange)->applyFromArray($pStyles, $pAdvanced);
 
1576
                return $this;
 
1577
        }
 
1578
 
 
1579
        /**
 
1580
         * Set break on a cell
 
1581
         *
 
1582
         * @param       string                  $pCell          Cell coordinate (e.g. A1)
 
1583
         * @param       int                             $pBreak         Break type (type of PHPExcel_Worksheet::BREAK_*)
 
1584
         * @throws      Exception
 
1585
         * @return PHPExcel_Worksheet
 
1586
         */
 
1587
        public function setBreak($pCell = 'A1', $pBreak = PHPExcel_Worksheet::BREAK_NONE)
 
1588
        {
 
1589
                // Uppercase coordinate
 
1590
                $pCell = strtoupper($pCell);
 
1591
 
 
1592
                if ($pCell != '') {
 
1593
                        $this->_breaks[$pCell] = $pBreak;
 
1594
                } else {
 
1595
                        throw new Exception('No cell coordinate specified.');
 
1596
                }
 
1597
 
 
1598
                return $this;
 
1599
        }
 
1600
 
 
1601
        /**
 
1602
         * Set break on a cell by using numeric cell coordinates
 
1603
         *
 
1604
         * @param       integer $pColumn        Numeric column coordinate of the cell
 
1605
         * @param       integer $pRow           Numeric row coordinate of the cell
 
1606
         * @param       integer $pBreak         Break type (type of PHPExcel_Worksheet::BREAK_*)
 
1607
         * @throws      Exception
 
1608
         * @return PHPExcel_Worksheet
 
1609
         */
 
1610
        public function setBreakByColumnAndRow($pColumn = 0, $pRow = 1, $pBreak = PHPExcel_Worksheet::BREAK_NONE)
 
1611
        {
 
1612
                return $this->setBreak(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow, $pBreak);
 
1613
        }
 
1614
 
 
1615
        /**
 
1616
         * Get breaks
 
1617
         *
 
1618
         * @return array[]
 
1619
         */
 
1620
        public function getBreaks()
 
1621
        {
 
1622
                return $this->_breaks;
 
1623
        }
 
1624
 
 
1625
        /**
 
1626
         * Set merge on a cell range
 
1627
         *
 
1628
         * @param       string                  $pRange         Cell range (e.g. A1:E1)
 
1629
         * @throws      Exception
 
1630
         * @return PHPExcel_Worksheet
 
1631
         */
 
1632
        public function mergeCells($pRange = 'A1:A1')
 
1633
        {
 
1634
                // Uppercase coordinate
 
1635
                $pRange = strtoupper($pRange);
 
1636
 
 
1637
                if (strpos($pRange,':') !== false) {
 
1638
                        $this->_mergeCells[$pRange] = $pRange;
 
1639
 
 
1640
                        // make sure cells are created
 
1641
 
 
1642
                        // get the cells in the range
 
1643
                        $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange);
 
1644
 
 
1645
                        // create upper left cell if it does not already exist
 
1646
                        $upperLeft = $aReferences[0];
 
1647
                        if (!$this->cellExists($upperLeft)) {
 
1648
                                $this->getCell($upperLeft)->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL);
 
1649
                        }
 
1650
 
 
1651
                        // create or blank out the rest of the cells in the range
 
1652
                        $count = count($aReferences);
 
1653
                        for ($i = 1; $i < $count; $i++) {
 
1654
                                $this->getCell($aReferences[$i])->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL);
 
1655
                        }
 
1656
 
 
1657
                } else {
 
1658
                        throw new Exception('Merge must be set on a range of cells.');
 
1659
                }
 
1660
 
 
1661
                return $this;
 
1662
        }
 
1663
 
 
1664
        /**
 
1665
         * Set merge on a cell range by using numeric cell coordinates
 
1666
         *
 
1667
         * @param       int $pColumn1   Numeric column coordinate of the first cell
 
1668
         * @param       int $pRow1              Numeric row coordinate of the first cell
 
1669
         * @param       int $pColumn2   Numeric column coordinate of the last cell
 
1670
         * @param       int $pRow2              Numeric row coordinate of the last cell
 
1671
         * @throws      Exception
 
1672
         * @return PHPExcel_Worksheet
 
1673
         */
 
1674
        public function mergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1)
 
1675
        {
 
1676
                $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;
 
1677
                return $this->mergeCells($cellRange);
 
1678
        }
 
1679
 
 
1680
        /**
 
1681
         * Remove merge on a cell range
 
1682
         *
 
1683
         * @param       string                  $pRange         Cell range (e.g. A1:E1)
 
1684
         * @throws      Exception
 
1685
         * @return PHPExcel_Worksheet
 
1686
         */
 
1687
        public function unmergeCells($pRange = 'A1:A1')
 
1688
        {
 
1689
                // Uppercase coordinate
 
1690
                $pRange = strtoupper($pRange);
 
1691
 
 
1692
                if (strpos($pRange,':') !== false) {
 
1693
                        if (isset($this->_mergeCells[$pRange])) {
 
1694
                                unset($this->_mergeCells[$pRange]);
 
1695
                        } else {
 
1696
                                throw new Exception('Cell range ' . $pRange . ' not known as merged.');
 
1697
                        }
 
1698
                } else {
 
1699
                        throw new Exception('Merge can only be removed from a range of cells.');
 
1700
                }
 
1701
 
 
1702
                return $this;
 
1703
        }
 
1704
 
 
1705
        /**
 
1706
         * Remove merge on a cell range by using numeric cell coordinates
 
1707
         *
 
1708
         * @param       int $pColumn1   Numeric column coordinate of the first cell
 
1709
         * @param       int $pRow1              Numeric row coordinate of the first cell
 
1710
         * @param       int $pColumn2   Numeric column coordinate of the last cell
 
1711
         * @param       int $pRow2              Numeric row coordinate of the last cell
 
1712
         * @throws      Exception
 
1713
         * @return PHPExcel_Worksheet
 
1714
         */
 
1715
        public function unmergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1)
 
1716
        {
 
1717
                $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;
 
1718
                return $this->unmergeCells($cellRange);
 
1719
        }
 
1720
 
 
1721
        /**
 
1722
         * Get merge cells array.
 
1723
         *
 
1724
         * @return array[]
 
1725
         */
 
1726
        public function getMergeCells()
 
1727
        {
 
1728
                return $this->_mergeCells;
 
1729
        }
 
1730
 
 
1731
        /**
 
1732
         * Set merge cells array for the entire sheet. Use instead mergeCells() to merge
 
1733
         * a single cell range.
 
1734
         *
 
1735
         * @param array
 
1736
         */
 
1737
        public function setMergeCells($pValue = array())
 
1738
        {
 
1739
                $this->_mergeCells = $pValue;
 
1740
 
 
1741
                return $this;
 
1742
        }
 
1743
 
 
1744
        /**
 
1745
         * Set protection on a cell range
 
1746
         *
 
1747
         * @param       string                  $pRange                         Cell (e.g. A1) or cell range (e.g. A1:E1)
 
1748
         * @param       string                  $pPassword                      Password to unlock the protection
 
1749
         * @param       boolean         $pAlreadyHashed If the password has already been hashed, set this to true
 
1750
         * @throws      Exception
 
1751
         * @return PHPExcel_Worksheet
 
1752
         */
 
1753
        public function protectCells($pRange = 'A1', $pPassword = '', $pAlreadyHashed = false)
 
1754
        {
 
1755
                // Uppercase coordinate
 
1756
                $pRange = strtoupper($pRange);
 
1757
 
 
1758
                if (!$pAlreadyHashed) {
 
1759
                        $pPassword = PHPExcel_Shared_PasswordHasher::hashPassword($pPassword);
 
1760
                }
 
1761
                $this->_protectedCells[$pRange] = $pPassword;
 
1762
 
 
1763
                return $this;
 
1764
        }
 
1765
 
 
1766
        /**
 
1767
         * Set protection on a cell range by using numeric cell coordinates
 
1768
         *
 
1769
         * @param       int     $pColumn1                       Numeric column coordinate of the first cell
 
1770
         * @param       int     $pRow1                          Numeric row coordinate of the first cell
 
1771
         * @param       int     $pColumn2                       Numeric column coordinate of the last cell
 
1772
         * @param       int     $pRow2                          Numeric row coordinate of the last cell
 
1773
         * @param       string  $pPassword                      Password to unlock the protection
 
1774
         * @param       boolean $pAlreadyHashed If the password has already been hashed, set this to true
 
1775
         * @throws      Exception
 
1776
         * @return PHPExcel_Worksheet
 
1777
         */
 
1778
        public function protectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false)
 
1779
        {
 
1780
                $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;
 
1781
                return $this->protectCells($cellRange, $pPassword, $pAlreadyHashed);
 
1782
        }
 
1783
 
 
1784
        /**
 
1785
         * Remove protection on a cell range
 
1786
         *
 
1787
         * @param       string                  $pRange         Cell (e.g. A1) or cell range (e.g. A1:E1)
 
1788
         * @throws      Exception
 
1789
         * @return PHPExcel_Worksheet
 
1790
         */
 
1791
        public function unprotectCells($pRange = 'A1')
 
1792
        {
 
1793
                // Uppercase coordinate
 
1794
                $pRange = strtoupper($pRange);
 
1795
 
 
1796
                if (isset($this->_protectedCells[$pRange])) {
 
1797
                        unset($this->_protectedCells[$pRange]);
 
1798
                } else {
 
1799
                        throw new Exception('Cell range ' . $pRange . ' not known as protected.');
 
1800
                }
 
1801
                return $this;
 
1802
        }
 
1803
 
 
1804
        /**
 
1805
         * Remove protection on a cell range by using numeric cell coordinates
 
1806
         *
 
1807
         * @param       int     $pColumn1                       Numeric column coordinate of the first cell
 
1808
         * @param       int     $pRow1                          Numeric row coordinate of the first cell
 
1809
         * @param       int     $pColumn2                       Numeric column coordinate of the last cell
 
1810
         * @param       int     $pRow2                          Numeric row coordinate of the last cell
 
1811
         * @param       string  $pPassword                      Password to unlock the protection
 
1812
         * @param       boolean $pAlreadyHashed If the password has already been hashed, set this to true
 
1813
         * @throws      Exception
 
1814
         * @return PHPExcel_Worksheet
 
1815
         */
 
1816
        public function unprotectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false)
 
1817
        {
 
1818
                $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;
 
1819
                return $this->unprotectCells($cellRange, $pPassword, $pAlreadyHashed);
 
1820
        }
 
1821
 
 
1822
        /**
 
1823
         * Get protected cells
 
1824
         *
 
1825
         * @return array[]
 
1826
         */
 
1827
        public function getProtectedCells()
 
1828
        {
 
1829
                return $this->_protectedCells;
 
1830
        }
 
1831
 
 
1832
        /**
 
1833
         *      Get Autofilter
 
1834
         *
 
1835
         *      @return PHPExcel_Worksheet_AutoFilter
 
1836
         */
 
1837
        public function getAutoFilter()
 
1838
        {
 
1839
                return $this->_autoFilter;
 
1840
        }
 
1841
 
 
1842
        /**
 
1843
         *      Set AutoFilter
 
1844
         *
 
1845
         *      @param  PHPExcel_Worksheet_AutoFilter|string    $pValue
 
1846
         *                      A simple string containing a Cell range like 'A1:E10' is permitted for backward compatibility
 
1847
         *      @throws Exception
 
1848
         *      @return PHPExcel_Worksheet
 
1849
         */
 
1850
        public function setAutoFilter($pValue)
 
1851
        {
 
1852
                if (is_string($pValue)) {
 
1853
                        $this->_autoFilter->setRange($pValue);
 
1854
                } elseif(is_object($pValue) && ($pValue instanceof PHPExcel_Worksheet_AutoFilter)) {
 
1855
                        $this->_autoFilter = $pValue;
 
1856
                }
 
1857
                return $this;
 
1858
        }
 
1859
 
 
1860
        /**
 
1861
         *      Set Autofilter Range by using numeric cell coordinates
 
1862
         *
 
1863
         *      @param  int     $pColumn1       Numeric column coordinate of the first cell
 
1864
         *      @param  int     $pRow1          Numeric row coordinate of the first cell
 
1865
         *      @param  int     $pColumn2       Numeric column coordinate of the second cell
 
1866
         *      @param  int     $pRow2          Numeric row coordinate of the second cell
 
1867
         *      @throws Exception
 
1868
         *      @return PHPExcel_Worksheet
 
1869
         */
 
1870
        public function setAutoFilterByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1)
 
1871
        {
 
1872
                return $this->setAutoFilter(
 
1873
                        PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1
 
1874
                        . ':' .
 
1875
                        PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2
 
1876
                );
 
1877
        }
 
1878
 
 
1879
    /**
 
1880
     * Remove autofilter
 
1881
     *
 
1882
     * @return PHPExcel_Worksheet
 
1883
     */
 
1884
    public function removeAutoFilter()
 
1885
    {
 
1886
        $this->_autoFilter->setRange(NULL);
 
1887
        return $this;
 
1888
    }
 
1889
 
 
1890
        /**
 
1891
         * Get Freeze Pane
 
1892
         *
 
1893
         * @return string
 
1894
         */
 
1895
        public function getFreezePane()
 
1896
        {
 
1897
                return $this->_freezePane;
 
1898
        }
 
1899
 
 
1900
        /**
 
1901
         * Freeze Pane
 
1902
         *
 
1903
         * @param       string          $pCell          Cell (i.e. A2)
 
1904
         *                                                                      Examples:
 
1905
         *                                                                              A2 will freeze the rows above cell A2 (i.e row 1)
 
1906
         *                                                                              B1 will freeze the columns to the left of cell B1 (i.e column A)
 
1907
         *                                                                              B2 will freeze the rows above and to the left of cell A2
 
1908
         *                                                                                      (i.e row 1 and column A)
 
1909
         * @throws      Exception
 
1910
         * @return PHPExcel_Worksheet
 
1911
         */
 
1912
        public function freezePane($pCell = '')
 
1913
        {
 
1914
                // Uppercase coordinate
 
1915
                $pCell = strtoupper($pCell);
 
1916
 
 
1917
                if (strpos($pCell,':') === false && strpos($pCell,',') === false) {
 
1918
                        $this->_freezePane = $pCell;
 
1919
                } else {
 
1920
                        throw new Exception('Freeze pane can not be set on a range of cells.');
 
1921
                }
 
1922
                return $this;
 
1923
        }
 
1924
 
 
1925
        /**
 
1926
         * Freeze Pane by using numeric cell coordinates
 
1927
         *
 
1928
         * @param       int     $pColumn        Numeric column coordinate of the cell
 
1929
         * @param       int     $pRow           Numeric row coordinate of the cell
 
1930
         * @throws      Exception
 
1931
         * @return PHPExcel_Worksheet
 
1932
         */
 
1933
        public function freezePaneByColumnAndRow($pColumn = 0, $pRow = 1)
 
1934
        {
 
1935
                return $this->freezePane(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
 
1936
        }
 
1937
 
 
1938
        /**
 
1939
         * Unfreeze Pane
 
1940
         *
 
1941
         * @return PHPExcel_Worksheet
 
1942
         */
 
1943
        public function unfreezePane()
 
1944
        {
 
1945
                return $this->freezePane('');
 
1946
        }
 
1947
 
 
1948
        /**
 
1949
         * Insert a new row, updating all possible related data
 
1950
         *
 
1951
         * @param       int     $pBefore        Insert before this one
 
1952
         * @param       int     $pNumRows       Number of rows to insert
 
1953
         * @throws      Exception
 
1954
         * @return PHPExcel_Worksheet
 
1955
         */
 
1956
        public function insertNewRowBefore($pBefore = 1, $pNumRows = 1) {
 
1957
                if ($pBefore >= 1) {
 
1958
                        $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();
 
1959
                        $objReferenceHelper->insertNewBefore('A' . $pBefore, 0, $pNumRows, $this);
 
1960
                } else {
 
1961
                        throw new Exception("Rows can only be inserted before at least row 1.");
 
1962
                }
 
1963
                return $this;
 
1964
        }
 
1965
 
 
1966
        /**
 
1967
         * Insert a new column, updating all possible related data
 
1968
         *
 
1969
         * @param       int     $pBefore        Insert before this one
 
1970
         * @param       int     $pNumCols       Number of columns to insert
 
1971
         * @throws      Exception
 
1972
         * @return PHPExcel_Worksheet
 
1973
         */
 
1974
        public function insertNewColumnBefore($pBefore = 'A', $pNumCols = 1) {
 
1975
                if (!is_numeric($pBefore)) {
 
1976
                        $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();
 
1977
                        $objReferenceHelper->insertNewBefore($pBefore . '1', $pNumCols, 0, $this);
 
1978
                } else {
 
1979
                        throw new Exception("Column references should not be numeric.");
 
1980
                }
 
1981
                return $this;
 
1982
        }
 
1983
 
 
1984
        /**
 
1985
         * Insert a new column, updating all possible related data
 
1986
         *
 
1987
         * @param       int     $pBefore        Insert before this one (numeric column coordinate of the cell)
 
1988
         * @param       int     $pNumCols       Number of columns to insert
 
1989
         * @throws      Exception
 
1990
         * @return PHPExcel_Worksheet
 
1991
         */
 
1992
        public function insertNewColumnBeforeByIndex($pBefore = 0, $pNumCols = 1) {
 
1993
                if ($pBefore >= 0) {
 
1994
                        return $this->insertNewColumnBefore(PHPExcel_Cell::stringFromColumnIndex($pBefore), $pNumCols);
 
1995
                } else {
 
1996
                        throw new Exception("Columns can only be inserted before at least column A (0).");
 
1997
                }
 
1998
        }
 
1999
 
 
2000
        /**
 
2001
         * Delete a row, updating all possible related data
 
2002
         *
 
2003
         * @param       int     $pRow           Remove starting with this one
 
2004
         * @param       int     $pNumRows       Number of rows to remove
 
2005
         * @throws      Exception
 
2006
         * @return PHPExcel_Worksheet
 
2007
         */
 
2008
        public function removeRow($pRow = 1, $pNumRows = 1) {
 
2009
                if ($pRow >= 1) {
 
2010
                        $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();
 
2011
                        $objReferenceHelper->insertNewBefore('A' . ($pRow + $pNumRows), 0, -$pNumRows, $this);
 
2012
                } else {
 
2013
                        throw new Exception("Rows to be deleted should at least start from row 1.");
 
2014
                }
 
2015
                return $this;
 
2016
        }
 
2017
 
 
2018
        /**
 
2019
         * Remove a column, updating all possible related data
 
2020
         *
 
2021
         * @param       int     $pColumn        Remove starting with this one
 
2022
         * @param       int     $pNumCols       Number of columns to remove
 
2023
         * @throws      Exception
 
2024
         * @return PHPExcel_Worksheet
 
2025
         */
 
2026
        public function removeColumn($pColumn = 'A', $pNumCols = 1) {
 
2027
                if (!is_numeric($pColumn)) {
 
2028
                        $pColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($pColumn) - 1 + $pNumCols);
 
2029
                        $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();
 
2030
                        $objReferenceHelper->insertNewBefore($pColumn . '1', -$pNumCols, 0, $this);
 
2031
                } else {
 
2032
                        throw new Exception("Column references should not be numeric.");
 
2033
                }
 
2034
                return $this;
 
2035
        }
 
2036
 
 
2037
        /**
 
2038
         * Remove a column, updating all possible related data
 
2039
         *
 
2040
         * @param       int     $pColumn        Remove starting with this one (numeric column coordinate of the cell)
 
2041
         * @param       int     $pNumCols       Number of columns to remove
 
2042
         * @throws      Exception
 
2043
         * @return PHPExcel_Worksheet
 
2044
         */
 
2045
        public function removeColumnByIndex($pColumn = 0, $pNumCols = 1) {
 
2046
                if ($pColumn >= 0) {
 
2047
                        return $this->removeColumn(PHPExcel_Cell::stringFromColumnIndex($pColumn), $pNumCols);
 
2048
                } else {
 
2049
                        throw new Exception("Columns to be deleted should at least start from column 0");
 
2050
                }
 
2051
        }
 
2052
 
 
2053
        /**
 
2054
         * Show gridlines?
 
2055
         *
 
2056
         * @return boolean
 
2057
         */
 
2058
        public function getShowGridlines() {
 
2059
                return $this->_showGridlines;
 
2060
        }
 
2061
 
 
2062
        /**
 
2063
         * Set show gridlines
 
2064
         *
 
2065
         * @param boolean $pValue       Show gridlines (true/false)
 
2066
         * @return PHPExcel_Worksheet
 
2067
         */
 
2068
        public function setShowGridlines($pValue = false) {
 
2069
                $this->_showGridlines = $pValue;
 
2070
                return $this;
 
2071
        }
 
2072
 
 
2073
        /**
 
2074
        * Print gridlines?
 
2075
        *
 
2076
        * @return boolean
 
2077
        */
 
2078
        public function getPrintGridlines() {
 
2079
                return $this->_printGridlines;
 
2080
        }
 
2081
 
 
2082
        /**
 
2083
        * Set print gridlines
 
2084
        *
 
2085
        * @param boolean $pValue Print gridlines (true/false)
 
2086
        * @return PHPExcel_Worksheet
 
2087
        */
 
2088
        public function setPrintGridlines($pValue = false) {
 
2089
                $this->_printGridlines = $pValue;
 
2090
                return $this;
 
2091
        }
 
2092
 
 
2093
        /**
 
2094
        * Show row and column headers?
 
2095
        *
 
2096
        * @return boolean
 
2097
        */
 
2098
        public function getShowRowColHeaders() {
 
2099
                return $this->_showRowColHeaders;
 
2100
        }
 
2101
 
 
2102
        /**
 
2103
        * Set show row and column headers
 
2104
        *
 
2105
        * @param boolean $pValue Show row and column headers (true/false)
 
2106
        * @return PHPExcel_Worksheet
 
2107
        */
 
2108
        public function setShowRowColHeaders($pValue = false) {
 
2109
                $this->_showRowColHeaders = $pValue;
 
2110
                return $this;
 
2111
        }
 
2112
 
 
2113
        /**
 
2114
         * Show summary below? (Row/Column outlining)
 
2115
         *
 
2116
         * @return boolean
 
2117
         */
 
2118
        public function getShowSummaryBelow() {
 
2119
                return $this->_showSummaryBelow;
 
2120
        }
 
2121
 
 
2122
        /**
 
2123
         * Set show summary below
 
2124
         *
 
2125
         * @param boolean $pValue       Show summary below (true/false)
 
2126
         * @return PHPExcel_Worksheet
 
2127
         */
 
2128
        public function setShowSummaryBelow($pValue = true) {
 
2129
                $this->_showSummaryBelow = $pValue;
 
2130
                return $this;
 
2131
        }
 
2132
 
 
2133
        /**
 
2134
         * Show summary right? (Row/Column outlining)
 
2135
         *
 
2136
         * @return boolean
 
2137
         */
 
2138
        public function getShowSummaryRight() {
 
2139
                return $this->_showSummaryRight;
 
2140
        }
 
2141
 
 
2142
        /**
 
2143
         * Set show summary right
 
2144
         *
 
2145
         * @param boolean $pValue       Show summary right (true/false)
 
2146
         * @return PHPExcel_Worksheet
 
2147
         */
 
2148
        public function setShowSummaryRight($pValue = true) {
 
2149
                $this->_showSummaryRight = $pValue;
 
2150
                return $this;
 
2151
        }
 
2152
 
 
2153
        /**
 
2154
         * Get comments
 
2155
         *
 
2156
         * @return PHPExcel_Comment[]
 
2157
         */
 
2158
        public function getComments()
 
2159
        {
 
2160
                return $this->_comments;
 
2161
        }
 
2162
 
 
2163
        /**
 
2164
         * Set comments array for the entire sheet.
 
2165
         *
 
2166
         * @param array of PHPExcel_Comment
 
2167
         * @return PHPExcel_Worksheet
 
2168
         */
 
2169
        public function setComments($pValue = array())
 
2170
        {
 
2171
                $this->_comments = $pValue;
 
2172
 
 
2173
                return $this;
 
2174
        }
 
2175
 
 
2176
        /**
 
2177
         * Get comment for cell
 
2178
         *
 
2179
         * @param       string  $pCellCoordinate        Cell coordinate to get comment for
 
2180
         * @return      PHPExcel_Comment
 
2181
         * @throws      Exception
 
2182
         */
 
2183
        public function getComment($pCellCoordinate = 'A1')
 
2184
        {
 
2185
                // Uppercase coordinate
 
2186
                $pCellCoordinate = strtoupper($pCellCoordinate);
 
2187
 
 
2188
                if (strpos($pCellCoordinate,':') !== false || strpos($pCellCoordinate,',') !== false) {
 
2189
                        throw new Exception('Cell coordinate string can not be a range of cells.');
 
2190
                } else if (strpos($pCellCoordinate,'$') !== false) {
 
2191
                        throw new Exception('Cell coordinate string must not be absolute.');
 
2192
                } else if ($pCellCoordinate == '') {
 
2193
                        throw new Exception('Cell coordinate can not be zero-length string.');
 
2194
                } else {
 
2195
                        // Check if we already have a comment for this cell.
 
2196
                        // If not, create a new comment.
 
2197
                        if (isset($this->_comments[$pCellCoordinate])) {
 
2198
                                return $this->_comments[$pCellCoordinate];
 
2199
                        } else {
 
2200
                                $newComment = new PHPExcel_Comment();
 
2201
                                $this->_comments[$pCellCoordinate] = $newComment;
 
2202
                                return $newComment;
 
2203
                        }
 
2204
                }
 
2205
        }
 
2206
 
 
2207
        /**
 
2208
         * Get comment for cell by using numeric cell coordinates
 
2209
         *
 
2210
         * @param       int $pColumn    Numeric column coordinate of the cell
 
2211
         * @param       int $pRow               Numeric row coordinate of the cell
 
2212
         * @return      PHPExcel_Comment
 
2213
         */
 
2214
        public function getCommentByColumnAndRow($pColumn = 0, $pRow = 1)
 
2215
        {
 
2216
                return $this->getComment(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
 
2217
        }
 
2218
 
 
2219
        /**
 
2220
         * Get selected cell
 
2221
         *
 
2222
         * @deprecated
 
2223
         * @return string
 
2224
         */
 
2225
        public function getSelectedCell()
 
2226
        {
 
2227
                return $this->getSelectedCells();
 
2228
        }
 
2229
 
 
2230
        /**
 
2231
         * Get active cell
 
2232
         *
 
2233
         * @return string Example: 'A1'
 
2234
         */
 
2235
        public function getActiveCell()
 
2236
        {
 
2237
                return $this->_activeCell;
 
2238
        }
 
2239
 
 
2240
        /**
 
2241
         * Get selected cells
 
2242
         *
 
2243
         * @return string
 
2244
         */
 
2245
        public function getSelectedCells()
 
2246
        {
 
2247
                return $this->_selectedCells;
 
2248
        }
 
2249
 
 
2250
        /**
 
2251
         * Selected cell
 
2252
         *
 
2253
         * @param       string          $pCoordinate    Cell (i.e. A1)
 
2254
         * @return PHPExcel_Worksheet
 
2255
         */
 
2256
        public function setSelectedCell($pCoordinate = 'A1')
 
2257
        {
 
2258
                return $this->setSelectedCells($pCoordinate);
 
2259
        }
 
2260
 
 
2261
        /**
 
2262
         * Select a range of cells.
 
2263
         *
 
2264
         * @param       string          $pCoordinate    Cell range, examples: 'A1', 'B2:G5', 'A:C', '3:6'
 
2265
         * @throws      Exception
 
2266
         * @return PHPExcel_Worksheet
 
2267
         */
 
2268
        public function setSelectedCells($pCoordinate = 'A1')
 
2269
        {
 
2270
                // Uppercase coordinate
 
2271
                $pCoordinate = strtoupper($pCoordinate);
 
2272
 
 
2273
                // Convert 'A' to 'A:A'
 
2274
                $pCoordinate = preg_replace('/^([A-Z]+)$/', '${1}:${1}', $pCoordinate);
 
2275
 
 
2276
                // Convert '1' to '1:1'
 
2277
                $pCoordinate = preg_replace('/^([0-9]+)$/', '${1}:${1}', $pCoordinate);
 
2278
 
 
2279
                // Convert 'A:C' to 'A1:C1048576'
 
2280
                $pCoordinate = preg_replace('/^([A-Z]+):([A-Z]+)$/', '${1}1:${2}1048576', $pCoordinate);
 
2281
 
 
2282
                // Convert '1:3' to 'A1:XFD3'
 
2283
                $pCoordinate = preg_replace('/^([0-9]+):([0-9]+)$/', 'A${1}:XFD${2}', $pCoordinate);
 
2284
 
 
2285
                if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) {
 
2286
                        list($first, ) = PHPExcel_Cell::splitRange($pCoordinate);
 
2287
                        $this->_activeCell = $first[0];
 
2288
                } else {
 
2289
                        $this->_activeCell = $pCoordinate;
 
2290
                }
 
2291
                $this->_selectedCells = $pCoordinate;
 
2292
                return $this;
 
2293
        }
 
2294
 
 
2295
        /**
 
2296
         * Selected cell by using numeric cell coordinates
 
2297
         *
 
2298
         * @param       int     $pColumn        Numeric column coordinate of the cell
 
2299
         * @param       int     $pRow           Numeric row coordinate of the cell
 
2300
         * @throws      Exception
 
2301
         * @return PHPExcel_Worksheet
 
2302
         */
 
2303
        public function setSelectedCellByColumnAndRow($pColumn = 0, $pRow = 1)
 
2304
        {
 
2305
                return $this->setSelectedCells(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);
 
2306
        }
 
2307
 
 
2308
        /**
 
2309
         * Get right-to-left
 
2310
         *
 
2311
         * @return boolean
 
2312
         */
 
2313
        public function getRightToLeft() {
 
2314
                return $this->_rightToLeft;
 
2315
        }
 
2316
 
 
2317
        /**
 
2318
         * Set right-to-left
 
2319
         *
 
2320
         * @param       boolean $value  Right-to-left true/false
 
2321
         * @return PHPExcel_Worksheet
 
2322
         */
 
2323
        public function setRightToLeft($value = false) {
 
2324
                $this->_rightToLeft = $value;
 
2325
                return $this;
 
2326
        }
 
2327
 
 
2328
        /**
 
2329
         * Fill worksheet from values in array
 
2330
         *
 
2331
         * @param       array   $source                                 Source array
 
2332
         * @param       mixed   $nullValue                              Value in source array that stands for blank cell
 
2333
         * @param       string  $startCell                              Insert array starting from this cell address as the top left coordinate
 
2334
         * @param       boolean $strictNullComparison   Apply strict comparison when testing for null values in the array
 
2335
         * @throws Exception
 
2336
         * @return PHPExcel_Worksheet
 
2337
         */
 
2338
        public function fromArray($source = null, $nullValue = null, $startCell = 'A1', $strictNullComparison = false) {
 
2339
                if (is_array($source)) {
 
2340
                        //      Convert a 1-D array to 2-D (for ease of looping)
 
2341
                        if (!is_array(end($source))) {
 
2342
                                $source = array($source);
 
2343
                        }
 
2344
 
 
2345
                        // start coordinate
 
2346
                        list ($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($startCell);
 
2347
 
 
2348
                        // Loop through $source
 
2349
                        foreach ($source as $rowData) {
 
2350
                                $currentColumn = $startColumn;
 
2351
                                foreach($rowData as $cellValue) {
 
2352
                                        if ($strictNullComparison) {
 
2353
                                                if ($cellValue !== $nullValue) {
 
2354
                                                        // Set cell value
 
2355
                                                        $this->getCell($currentColumn . $startRow)->setValue($cellValue);
 
2356
                                                }
 
2357
                                        } else {
 
2358
                                                if ($cellValue != $nullValue) {
 
2359
                                                        // Set cell value
 
2360
                                                        $this->getCell($currentColumn . $startRow)->setValue($cellValue);
 
2361
                                                }
 
2362
                                        }
 
2363
                                        ++$currentColumn;
 
2364
                                }
 
2365
                                ++$startRow;
 
2366
                        }
 
2367
                } else {
 
2368
                        throw new Exception("Parameter \$source should be an array.");
 
2369
                }
 
2370
                return $this;
 
2371
        }
 
2372
 
 
2373
        /**
 
2374
         * Create array from a range of cells
 
2375
         *
 
2376
         * @param       string  $pRange                                 Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
 
2377
         * @param       mixed   $nullValue                              Value returned in the array entry if a cell doesn't exist
 
2378
         * @param       boolean $calculateFormulas              Should formulas be calculated?
 
2379
         * @param       boolean $formatData                             Should formatting be applied to cell values?
 
2380
         * @param       boolean $returnCellRef                  False - Return a simple array of rows and columns indexed by number counting from zero
 
2381
         *                                                                                      True - Return rows and columns indexed by their actual row and column IDs
 
2382
         * @return array
 
2383
         */
 
2384
        public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) {
 
2385
                // Returnvalue
 
2386
                $returnValue = array();
 
2387
 
 
2388
                //      Identify the range that we need to extract from the worksheet
 
2389
                list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange);
 
2390
                $minCol = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] -1);
 
2391
                $minRow = $rangeStart[1];
 
2392
                $maxCol = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] -1);
 
2393
                $maxRow = $rangeEnd[1];
 
2394
 
 
2395
                $maxCol++;
 
2396
 
 
2397
                // Loop through rows
 
2398
                $r = -1;
 
2399
                for ($row = $minRow; $row <= $maxRow; ++$row) {
 
2400
                        $rRef = ($returnCellRef) ? $row : ++$r;
 
2401
                        $c = -1;
 
2402
                        // Loop through columns in the current row
 
2403
                        for ($col = $minCol; $col != $maxCol; ++$col) {
 
2404
                                $cRef = ($returnCellRef) ? $col : ++$c;
 
2405
                                //      Using getCell() will create a new cell if it doesn't already exist. We don't want that to happen
 
2406
                                //              so we test and retrieve directly against _cellCollection
 
2407
                                if ($this->_cellCollection->isDataSet($col.$row)) {
 
2408
                                        // Cell exists
 
2409
                                        $cell = $this->_cellCollection->getCacheData($col.$row);
 
2410
                                        if ($cell->getValue() !== null) {
 
2411
                                                if ($cell->getValue() instanceof PHPExcel_RichText) {
 
2412
                                                        $returnValue[$rRef][$cRef] = $cell->getValue()->getPlainText();
 
2413
                                                } else {
 
2414
                                                        if ($calculateFormulas) {
 
2415
                                                                $returnValue[$rRef][$cRef] = $cell->getCalculatedValue();
 
2416
                                                        } else {
 
2417
                                                                $returnValue[$rRef][$cRef] = $cell->getValue();
 
2418
                                                        }
 
2419
                                                }
 
2420
 
 
2421
                                                if ($formatData) {
 
2422
                                                        $style = $this->_parent->getCellXfByIndex($cell->getXfIndex());
 
2423
                                                        $returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString($returnValue[$rRef][$cRef], $style->getNumberFormat()->getFormatCode());
 
2424
                                                }
 
2425
                                        } else {
 
2426
                                                // Cell holds a NULL
 
2427
                                                $returnValue[$rRef][$cRef] = $nullValue;
 
2428
                                        }
 
2429
                                } else {
 
2430
                                        // Cell doesn't exist
 
2431
                                        $returnValue[$rRef][$cRef] = $nullValue;
 
2432
                                }
 
2433
                        }
 
2434
                }
 
2435
 
 
2436
                // Return
 
2437
                return $returnValue;
 
2438
        }
 
2439
 
 
2440
 
 
2441
        /**
 
2442
         * Create array from a range of cells
 
2443
         *
 
2444
         * @param       string  $pNamedRange                    Name of the Named Range
 
2445
         * @param       mixed   $nullValue                              Value returned in the array entry if a cell doesn't exist
 
2446
         * @param       boolean $calculateFormulas              Should formulas be calculated?
 
2447
         * @param       boolean $formatData                             Should formatting be applied to cell values?
 
2448
         * @param       boolean $returnCellRef                  False - Return a simple array of rows and columns indexed by number counting from zero
 
2449
         *                                                                                      True - Return rows and columns indexed by their actual row and column IDs
 
2450
         * @return array
 
2451
         * @throws Exception
 
2452
         */
 
2453
        public function namedRangeToArray($pNamedRange = '', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) {
 
2454
                $namedRange = PHPExcel_NamedRange::resolveRange($pNamedRange, $this);
 
2455
                if ($namedRange !== NULL) {
 
2456
                        $pWorkSheet = $namedRange->getWorksheet();
 
2457
                        $pCellRange = $namedRange->getRange();
 
2458
 
 
2459
                        return $pWorkSheet->rangeToArray(       $pCellRange,
 
2460
                                                                                                $nullValue, $calculateFormulas, $formatData, $returnCellRef);
 
2461
                }
 
2462
 
 
2463
                throw new Exception('Named Range '.$pNamedRange.' does not exist.');
 
2464
        }
 
2465
 
 
2466
 
 
2467
        /**
 
2468
         * Create array from worksheet
 
2469
         *
 
2470
         * @param       mixed   $nullValue                              Value returned in the array entry if a cell doesn't exist
 
2471
         * @param       boolean $calculateFormulas              Should formulas be calculated?
 
2472
         * @param       boolean $formatData                             Should formatting be applied to cell values?
 
2473
         * @param       boolean $returnCellRef                  False - Return a simple array of rows and columns indexed by number counting from zero
 
2474
         *                                                                                      True - Return rows and columns indexed by their actual row and column IDs
 
2475
         * @return array
 
2476
         */
 
2477
        public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) {
 
2478
                // Garbage collect...
 
2479
                $this->garbageCollect();
 
2480
 
 
2481
                //      Identify the range that we need to extract from the worksheet
 
2482
                $maxCol = $this->getHighestColumn();
 
2483
                $maxRow = $this->getHighestRow();
 
2484
                // Return
 
2485
                return $this->rangeToArray(     'A1:'.$maxCol.$maxRow,
 
2486
                                                                        $nullValue, $calculateFormulas, $formatData, $returnCellRef);
 
2487
        }
 
2488
 
 
2489
        /**
 
2490
         * Get row iterator
 
2491
         *
 
2492
     * @param  integer                           $startRow    The row number at which to start iterating
 
2493
         * @return PHPExcel_Worksheet_RowIterator
 
2494
         */
 
2495
        public function getRowIterator($startRow = 1) {
 
2496
                return new PHPExcel_Worksheet_RowIterator($this,$startRow);
 
2497
        }
 
2498
 
 
2499
        /**
 
2500
         * Run PHPExcel garabage collector.
 
2501
         *
 
2502
         * @return PHPExcel_Worksheet
 
2503
         */
 
2504
        public function garbageCollect() {
 
2505
                // Build a reference table from images
 
2506
//              $imageCoordinates = array();
 
2507
//              $iterator = $this->getDrawingCollection()->getIterator();
 
2508
//              while ($iterator->valid()) {
 
2509
//                      $imageCoordinates[$iterator->current()->getCoordinates()] = true;
 
2510
//
 
2511
//                      $iterator->next();
 
2512
//              }
 
2513
//
 
2514
                // Lookup highest column and highest row if cells are cleaned
 
2515
                $colRow = $this->_cellCollection->getHighestRowAndColumn();
 
2516
                $highestRow = $colRow['row'];
 
2517
                $highestColumn = PHPExcel_Cell::columnIndexFromString($colRow['column']);
 
2518
 
 
2519
                // Loop through column dimensions
 
2520
                foreach ($this->_columnDimensions as $dimension) {
 
2521
                        $highestColumn = max($highestColumn,PHPExcel_Cell::columnIndexFromString($dimension->getColumnIndex()));
 
2522
                }
 
2523
 
 
2524
                // Loop through row dimensions
 
2525
                foreach ($this->_rowDimensions as $dimension) {
 
2526
                        $highestRow = max($highestRow,$dimension->getRowIndex());
 
2527
                }
 
2528
 
 
2529
                // Cache values
 
2530
                if ($highestColumn < 0) {
 
2531
                        $this->_cachedHighestColumn = 'A';
 
2532
                } else {
 
2533
                        $this->_cachedHighestColumn = PHPExcel_Cell::stringFromColumnIndex(--$highestColumn);
 
2534
                }
 
2535
                $this->_cachedHighestRow = $highestRow;
 
2536
 
 
2537
                // Return
 
2538
                return $this;
 
2539
        }
 
2540
 
 
2541
        /**
 
2542
         * Get hash code
 
2543
         *
 
2544
         * @return string       Hash code
 
2545
         */
 
2546
        public function getHashCode() {
 
2547
                if ($this->_dirty) {
 
2548
                        $this->_hash = md5( $this->_title .
 
2549
                                                                $this->_autoFilter .
 
2550
                                                                ($this->_protection->isProtectionEnabled() ? 't' : 'f') .
 
2551
                                                                __CLASS__
 
2552
                                                          );
 
2553
                        $this->_dirty = false;
 
2554
                }
 
2555
                return $this->_hash;
 
2556
        }
 
2557
 
 
2558
        /**
 
2559
         * Extract worksheet title from range.
 
2560
         *
 
2561
         * Example: extractSheetTitle("testSheet!A1") ==> 'A1'
 
2562
         * Example: extractSheetTitle("'testSheet 1'!A1", true) ==> array('testSheet 1', 'A1');
 
2563
         *
 
2564
         * @param string $pRange        Range to extract title from
 
2565
         * @param bool $returnRange     Return range? (see example)
 
2566
         * @return mixed
 
2567
         */
 
2568
        public static function extractSheetTitle($pRange, $returnRange = false) {
 
2569
                // Sheet title included?
 
2570
                if (($sep = strpos($pRange, '!')) === false) {
 
2571
                        return '';
 
2572
                }
 
2573
 
 
2574
                if ($returnRange) {
 
2575
                        return array( trim(substr($pRange, 0, $sep),"'"),
 
2576
                                                  substr($pRange, $sep + 1)
 
2577
                                                );
 
2578
                }
 
2579
 
 
2580
                return substr($pRange, $sep + 1);
 
2581
        }
 
2582
 
 
2583
        /**
 
2584
         * Get hyperlink
 
2585
         *
 
2586
         * @param string $pCellCoordinate       Cell coordinate to get hyperlink for
 
2587
         */
 
2588
        public function getHyperlink($pCellCoordinate = 'A1')
 
2589
        {
 
2590
                // return hyperlink if we already have one
 
2591
                if (isset($this->_hyperlinkCollection[$pCellCoordinate])) {
 
2592
                        return $this->_hyperlinkCollection[$pCellCoordinate];
 
2593
                }
 
2594
 
 
2595
                // else create hyperlink
 
2596
                $this->_hyperlinkCollection[$pCellCoordinate] = new PHPExcel_Cell_Hyperlink();
 
2597
                return $this->_hyperlinkCollection[$pCellCoordinate];
 
2598
        }
 
2599
 
 
2600
        /**
 
2601
         * Set hyperlnk
 
2602
         *
 
2603
         * @param string $pCellCoordinate       Cell coordinate to insert hyperlink
 
2604
         * @param       PHPExcel_Cell_Hyperlink $pHyperlink
 
2605
         * @return PHPExcel_Worksheet
 
2606
         */
 
2607
        public function setHyperlink($pCellCoordinate = 'A1', PHPExcel_Cell_Hyperlink $pHyperlink = null)
 
2608
        {
 
2609
                if ($pHyperlink === null) {
 
2610
                        unset($this->_hyperlinkCollection[$pCellCoordinate]);
 
2611
                } else {
 
2612
                        $this->_hyperlinkCollection[$pCellCoordinate] = $pHyperlink;
 
2613
                }
 
2614
                return $this;
 
2615
        }
 
2616
 
 
2617
        /**
 
2618
         * Hyperlink at a specific coordinate exists?
 
2619
         *
 
2620
         * @param string $pCoordinate
 
2621
         * @return boolean
 
2622
         */
 
2623
        public function hyperlinkExists($pCoordinate = 'A1')
 
2624
        {
 
2625
                return isset($this->_hyperlinkCollection[$pCoordinate]);
 
2626
        }
 
2627
 
 
2628
        /**
 
2629
         * Get collection of hyperlinks
 
2630
         *
 
2631
         * @return PHPExcel_Cell_Hyperlink[]
 
2632
         */
 
2633
        public function getHyperlinkCollection()
 
2634
        {
 
2635
                return $this->_hyperlinkCollection;
 
2636
        }
 
2637
 
 
2638
        /**
 
2639
         * Get data validation
 
2640
         *
 
2641
         * @param string $pCellCoordinate       Cell coordinate to get data validation for
 
2642
         */
 
2643
        public function getDataValidation($pCellCoordinate = 'A1')
 
2644
        {
 
2645
                // return data validation if we already have one
 
2646
                if (isset($this->_dataValidationCollection[$pCellCoordinate])) {
 
2647
                        return $this->_dataValidationCollection[$pCellCoordinate];
 
2648
                }
 
2649
 
 
2650
                // else create data validation
 
2651
                $this->_dataValidationCollection[$pCellCoordinate] = new PHPExcel_Cell_DataValidation();
 
2652
                return $this->_dataValidationCollection[$pCellCoordinate];
 
2653
        }
 
2654
 
 
2655
        /**
 
2656
         * Set data validation
 
2657
         *
 
2658
         * @param string $pCellCoordinate       Cell coordinate to insert data validation
 
2659
         * @param       PHPExcel_Cell_DataValidation    $pDataValidation
 
2660
         * @return PHPExcel_Worksheet
 
2661
         */
 
2662
        public function setDataValidation($pCellCoordinate = 'A1', PHPExcel_Cell_DataValidation $pDataValidation = null)
 
2663
        {
 
2664
                if ($pDataValidation === null) {
 
2665
                        unset($this->_dataValidationCollection[$pCellCoordinate]);
 
2666
                } else {
 
2667
                        $this->_dataValidationCollection[$pCellCoordinate] = $pDataValidation;
 
2668
                }
 
2669
                return $this;
 
2670
        }
 
2671
 
 
2672
        /**
 
2673
         * Data validation at a specific coordinate exists?
 
2674
         *
 
2675
         * @param string $pCoordinate
 
2676
         * @return boolean
 
2677
         */
 
2678
        public function dataValidationExists($pCoordinate = 'A1')
 
2679
        {
 
2680
                return isset($this->_dataValidationCollection[$pCoordinate]);
 
2681
        }
 
2682
 
 
2683
        /**
 
2684
         * Get collection of data validations
 
2685
         *
 
2686
         * @return PHPExcel_Cell_DataValidation[]
 
2687
         */
 
2688
        public function getDataValidationCollection()
 
2689
        {
 
2690
                return $this->_dataValidationCollection;
 
2691
        }
 
2692
 
 
2693
        /**
 
2694
         * Accepts a range, returning it as a range that falls within the current highest row and column of the worksheet
 
2695
         *
 
2696
         * @param       string  $range
 
2697
         * @return      string  Adjusted range value
 
2698
         */
 
2699
        public function shrinkRangeToFit($range) {
 
2700
                $maxCol = $this->getHighestColumn();
 
2701
                $maxRow = $this->getHighestRow();
 
2702
                $maxCol = PHPExcel_Cell::columnIndexFromString($maxCol);
 
2703
 
 
2704
                $rangeBlocks = explode(' ',$range);
 
2705
                foreach ($rangeBlocks as &$rangeSet) {
 
2706
                        $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($rangeSet);
 
2707
 
 
2708
                        if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[0][0]) > $maxCol) { $rangeBoundaries[0][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); }
 
2709
                        if ($rangeBoundaries[0][1] > $maxRow) { $rangeBoundaries[0][1] = $maxRow; }
 
2710
                        if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[1][0]) > $maxCol) { $rangeBoundaries[1][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); }
 
2711
                        if ($rangeBoundaries[1][1] > $maxRow) { $rangeBoundaries[1][1] = $maxRow; }
 
2712
                        $rangeSet = $rangeBoundaries[0][0].$rangeBoundaries[0][1].':'.$rangeBoundaries[1][0].$rangeBoundaries[1][1];
 
2713
                }
 
2714
                unset($rangeSet);
 
2715
                $stRange = implode(' ',$rangeBlocks);
 
2716
 
 
2717
                return $stRange;
 
2718
        }
 
2719
 
 
2720
 
 
2721
        /**
 
2722
         * Get tab color
 
2723
         *
 
2724
         * @return PHPExcel_Style_Color
 
2725
         */
 
2726
        public function getTabColor()
 
2727
        {
 
2728
                if ($this->_tabColor === NULL)
 
2729
                        $this->_tabColor = new PHPExcel_Style_Color();
 
2730
 
 
2731
                return $this->_tabColor;
 
2732
        }
 
2733
 
 
2734
        /**
 
2735
         * Reset tab color
 
2736
         *
 
2737
         * @return PHPExcel_Worksheet
 
2738
         */
 
2739
        public function resetTabColor()
 
2740
        {
 
2741
                $this->_tabColor = null;
 
2742
                unset($this->_tabColor);
 
2743
 
 
2744
                return $this;
 
2745
        }
 
2746
 
 
2747
        /**
 
2748
         * Tab color set?
 
2749
         *
 
2750
         * @return boolean
 
2751
         */
 
2752
        public function isTabColorSet()
 
2753
        {
 
2754
                return ($this->_tabColor !== NULL);
 
2755
        }
 
2756
 
 
2757
        /**
 
2758
         * Copy worksheet (!= clone!)
 
2759
         *
 
2760
         * @return PHPExcel_Worksheet
 
2761
         */
 
2762
        public function copy() {
 
2763
                $copied = clone $this;
 
2764
 
 
2765
                return $copied;
 
2766
        }
 
2767
 
 
2768
        /**
 
2769
         * Implement PHP __clone to create a deep clone, not just a shallow copy.
 
2770
         */
 
2771
        public function __clone() {
 
2772
                foreach ($this as $key => $val) {
 
2773
                        if ($key == '_parent') {
 
2774
                                continue;
 
2775
                        }
 
2776
 
 
2777
                        if (is_object($val) || (is_array($val))) {
 
2778
                                if ($key == '_cellCollection') {
 
2779
                                        $newCollection = clone $this->_cellCollection;
 
2780
                                        $newCollection->copyCellCollection($this);
 
2781
                                        $this->_cellCollection = $newCollection;
 
2782
                                } elseif ($key == '_drawingCollection') {
 
2783
                                        $newCollection = clone $this->_drawingCollection;
 
2784
                                        $this->_drawingCollection = $newCollection;
 
2785
                                } elseif (($key == '_autoFilter') && (is_a($this->_autoFilter,'PHPExcel_Worksheet_AutoFilter'))) {
 
2786
                                        $newAutoFilter = clone $this->_autoFilter;
 
2787
                                        $this->_autoFilter = $newAutoFilter;
 
2788
                                        $this->_autoFilter->setParent($this);
 
2789
                                } else {
 
2790
                                        $this->{$key} = unserialize(serialize($val));
 
2791
                                }
 
2792
                        }
 
2793
                }
 
2794
        }
 
2795
}