Completed
Branch development (b1b115)
by Johannes
10:28
created

LaravelExcelWorksheet   F

Complexity

Total Complexity 148

Size/Duplication

Total Lines 1262
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 148
c 0
b 0
f 0
dl 0
loc 1262
rs 0.8

How to fix   Complexity   

Complex Class

Complex classes like LaravelExcelWorksheet often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use LaravelExcelWorksheet, and based on these observations, apply Extract Interface, too.

1
<?php namespace Maatwebsite\Excel\Classes;
2
3
use Closure;
4
use PHPExcel_Cell;
5
use PHPExcel_Exception;
6
use PHPExcel_Worksheet;
7
use Illuminate\Support\Collection;
8
use Maatwebsite\Excel\Writers\CellWriter;
9
use Maatwebsite\Excel\Exceptions\LaravelExcelException;
10
use PHPExcel_Worksheet_PageSetup;
11
12
/**
13
 *
14
 * Laravel wrapper for PHPExcel_Worksheet
15
 *
16
 * @category   Laravel Excel
17
 * @version    1.0.0
18
 * @package    maatwebsite/excel
19
 * @copyright  Copyright (c) 2013 - 2014 Maatwebsite (http://www.maatwebsite.nl)
20
 * @copyright  Original Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
21
 * @author     Maatwebsite <[email protected]>
22
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
23
 */
24
class LaravelExcelWorksheet extends PHPExcel_Worksheet {
25
26
    /**
27
     * Parent
28
     * @var PHPExcel
29
     */
30
    public $_parent;
31
32
    /**
33
     * Parser
34
     * @var ViewParser
35
     */
36
    protected $parser;
37
38
    /**
39
     * View
40
     * @var string
41
     */
42
    public $view;
43
44
    /**
45
     * Data
46
     * @var array
47
     */
48
    public $data = [];
49
50
    /**
51
     * Merge data
52
     * @var array
53
     */
54
    public $mergeData = [];
55
56
    /**
57
     * Allowed page setup
58
     * @var array
59
     */
60
    public $allowedPageSetup = [
61
        'orientation',
62
        'paperSize',
63
        'scale',
64
        'fitToPage',
65
        'fitToHeight',
66
        'fitToWidth',
67
        'columnsToRepeatAtLeft',
68
        'rowsToRepeatAtTop',
69
        'horizontalCentered',
70
        'verticalCentered',
71
        'printArea',
72
        'firstPageNumber'
73
    ];
74
75
    /**
76
     * Allowed page setup
77
     * @var array
78
     */
79
    public $allowedStyles = [
80
        'fontFamily',
81
        'fontSize',
82
        'fontBold'
83
    ];
84
85
    /**
86
     * Check if the file was autosized
87
     * @var boolean
88
     */
89
    public $hasFixedSizeColumns = false;
90
91
    /**
92
     * Auto generate table heading
93
     * @var [type]
94
     */
95
    protected $autoGenerateHeading = true;
96
97
    /**
98
     * @var bool
99
     */
100
    protected $hasRowsAdded = false;
101
102
    /**
103
     * Create a new worksheet
104
     *
105
     * @param PHPExcel $pParent
106
     * @param string   $pTitle
107
     */
108
    public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet')
109
    {
110
        parent::__construct($pParent, $pTitle);
111
        $this->setParent($pParent);
112
        // check if we should generate headings
113
        // defaults to true if not overridden by settings
114
        $this->autoGenerateHeading = config('excel.export.generate_heading_by_indices', true);
115
    }
116
117
    /**
118
     * Set default page setup
119
     * @return  void
120
     */
121
    public function setDefaultPageSetup()
122
    {
123
        // Get the page setup
124
        $pageSetup = $this->getPageSetup();
125
126
        foreach ($this->allowedPageSetup as $setup)
127
        {
128
            // set the setter
129
            list($setter, $set) = $this->_setSetter($setup);
130
131
            // get the value
132
            $value = config('excel.sheets.pageSetup.' . $setup, null);
133
134
            // Set the page setup value
135
            if (!is_null($value))
136
                call_user_func_array([$pageSetup, $setter], [$value]);
137
        }
138
139
        // Set default page margins
140
        $this->setPageMargin(config('excel.export.sheets.page_margin', false));
141
    }
142
143
    /**
144
     * Set the page margin
145
     * @param array|boolean|integer|float $margin
146
     */
147
    public function setPageMargin($margin = false)
148
    {
149
        if (!is_array($margin))
150
        {
151
            $marginArray = [$margin, $margin, $margin, $margin];
152
        }
153
        else
154
        {
155
            $marginArray = $margin;
156
        }
157
158
        // Get margin
159
        $pageMargin = $this->getPageMargins();
160
161
        if (isset($marginArray[0]))
162
            $pageMargin->setTop($marginArray[0]);
163
164
        if (isset($marginArray[1]))
165
            $pageMargin->setRight($marginArray[1]);
166
167
        if (isset($marginArray[2]))
168
            $pageMargin->setBottom($marginArray[2]);
169
170
        if (isset($marginArray[3]))
171
            $pageMargin->setLeft($marginArray[3]);
172
    }
173
174
    /**
175
     * Manipulate a single row
176
     * @param  integer|callback|array $rowNumber
177
     * @param  array|callback         $callback
178
     * @param  boolean                $explicit
179
     * @return LaravelExcelWorksheet
180
     */
181
    public function row($rowNumber, $callback = null, $explicit = false)
182
    {
183
        // If a callback is given, handle it with the cell writer
184
        if ($callback instanceof Closure)
185
        {
186
            $range = $this->rowToRange($rowNumber);
187
188
            return $this->cells($range, $callback);
189
        }
190
191
        // Else if the 2nd param was set, we will use it as a cell value
192
        if (is_array($callback))
193
        {
194
            // Interpret the callback as cell values
195
            $values = $callback;
196
197
            // Set start column
198
            $column = 'A';
199
200
            foreach ($values as $rowValue)
201
            {
202
                // Set cell coordinate
203
                $cell = $column . $rowNumber;
204
205
                // Set the cell value
206
                if ($explicit) {
207
                    $this->setCellValueExplicit($cell, $rowValue);
208
                } else {
209
                    $this->setCellValue($cell, $rowValue);
210
                }
211
                $column++;
212
            }
213
        }
214
215
        // Remember that we have added rows
216
        $this->hasRowsAdded = true;
217
218
        return $this;
219
    }
220
221
    /**
222
     * Add multiple rows
223
     * @param  array $rows
224
     * @param  boolean $explicit
225
     * @return LaravelExcelWorksheet
226
     */
227
    public function rows($rows = [], $explicit = false)
228
    {
229
        // Get the start row
230
        $startRow = $this->getStartRow();
231
232
        // Add rows
233
        foreach ($rows as $row)
234
        {
235
            $this->row($startRow, $row, $explicit);
236
            $startRow++;
237
        }
238
239
        return $this;
240
    }
241
242
    /**
243
     * Prepend a row
244
     * @param  integer        $rowNumber
245
     * @param  array|callback $callback
246
     * @param  boolean        $explicit
247
     * @return LaravelExcelWorksheet
248
     */
249
    public function prependRow($rowNumber = 1, $callback = null, $explicit = false)
250
    {
251
        // If only one param was given, prepend it before the first row
252
        if (is_null($callback))
253
        {
254
            $callback = $rowNumber;
255
            $rowNumber = 1;
256
        }
257
258
        // Create new row
259
        $this->insertNewRowBefore($rowNumber);
260
261
        // Add data to row
262
        return $this->row($rowNumber, $callback, $explicit);
263
    }
264
265
    /**
266
     * Prepend a row explicitly
267
     * @param  integer        $rowNumber
268
     * @param  array|callback $callback
269
     * @return LaravelExcelWorksheet
270
     */
271
    public function prependRowExplicit($rowNumber = 1, $callback = null)
272
    {
273
        return $this->prependRow($rowNumber, $callback, true);
274
    }
275
276
    /**
277
     * Append a row
278
     * @param  integer|callback $rowNumber
279
     * @param  array|callback   $callback
280
     * @param  boolean          $explicit
281
     * @return LaravelExcelWorksheet
282
     */
283
    public function appendRow($rowNumber = 1, $callback = null, $explicit = false)
284
    {
285
        // If only one param was given, add it as very last
286
        if (is_null($callback))
287
        {
288
            $callback = $rowNumber;
289
            $rowNumber = $this->getStartRow();
290
        }
291
292
        // Add the row
293
        return $this->row($rowNumber, $callback, $explicit);
294
    }
295
296
    /**
297
     * Append a row explicitly
298
     * @param  integer|callback $rowNumber
299
     * @param  array|callback   $callback
300
     * @return LaravelExcelWorksheet
301
     */
302
    public function appendRowExplicit($rowNumber = 1, $callback = null)
303
    {
304
        return $this->appendRow($rowNumber, $callback, true);
305
    }
306
307
    /**
308
     * Manipulate a single cell
309
     * @param  array|string $cell
310
     * @param bool|callable $callback $callback
311
     * @param       boolean $explicit
312
     * @return LaravelExcelWorksheet
313
     */
314
    public function cell($cell, $callback = false, $explicit = false)
315
    {
316
        // If a callback is given, handle it with the cell writer
317
        if ($callback instanceof Closure)
318
            return $this->cells($cell, $callback);
319
320
        // Else if the 2nd param was set, we will use it as a cell value
321
        if ($callback) {
322
            if ($explicit) {
323
                $this->setCellValueExplicit($cell, $callback);
324
            } else {
325
                $this->setCellValue($cell, $callback);
326
            }
327
        }
328
329
        return $this;
330
    }
331
332
    /**
333
     * Manipulate a cell or a range of cells
334
     * @param  array        $cells
335
     * @param bool|callable $callback $callback
336
     * @return LaravelExcelWorksheet
337
     */
338
    public function cells($cells, $callback = false)
339
    {
340
        // Init the cell writer
341
        $cells = new CellWriter($cells, $this);
342
343
        // Do the callback
344
        if ($callback instanceof Closure)
345
            call_user_func($callback, $cells);
346
347
        return $this;
348
    }
349
350
    /**
351
     *  Load a View and convert to HTML
352
     * @return LaravelExcelWorksheet
353
     */
354
    public function setView()
355
    {
356
        return call_user_func_array([$this, 'loadView'], func_get_args());
357
    }
358
359
    /**
360
     *  Load a View and convert to HTML
361
     * @param string $view
362
     * @param array  $data
363
     * @param array  $mergeData
364
     * @return LaravelExcelWorksheet
365
     */
366
    public function loadView($view, $data = [], $mergeData = [])
367
    {
368
        // Init the parser
369
        if (!$this->parser)
370
            $this->setParser();
371
372
        $this->parser->setView($view);
373
        $this->parser->setData($data);
374
        $this->parser->setMergeData($mergeData);
375
376
        return $this;
377
    }
378
379
    /**
380
     * Unset the view
381
     * @return LaravelExcelWorksheet
382
     */
383
    public function unsetView()
384
    {
385
        $this->parser = null;
386
387
        return $this;
388
    }
389
390
    /**
391
     * Set the parser
392
     * @param boolean $parser
393
     * @return ViewParser
394
     */
395
    public function setParser($parser = false)
396
    {
397
        return $this->parser = $parser ? $parser : app('excel.parsers.view');
398
    }
399
400
    /**
401
     * Get the view
402
     * @return ViewParser
403
     */
404
    public function getView()
405
    {
406
        return $this->parser;
407
    }
408
409
    /**
410
     * Return parsed sheet
411
     * @return LaravelExcelWorksheet
412
     */
413
    public function parsed()
414
    {
415
        // If parser is set, use it
416
        if ($this->parser)
417
            return $this->parser->parse($this);
418
419
        // Else return the entire sheet
420
        return $this;
421
    }
422
423
    /**
424
     * Set data for the current sheet
425
     * @param              $key
426
     * @param  bool|string $value
427
     * @param  boolean     $headingGeneration
428
     * @return LaravelExcelWorksheet
429
     */
430
    public function with($key, $value = false, $headingGeneration = true)
431
    {
432
        // Set the heading generation setting
433
        $this->setAutoHeadingGeneration($headingGeneration);
434
435
        // Add the vars
436
        $this->_addVars($key, $value);
437
438
        return $this;
439
    }
440
441
    /**
442
     * From array
443
     * @param  Collection|array $source
444
     * @param null              $nullValue
445
     * @param bool|string       $startCell
446
     * @param bool              $strictNullComparison
447
     * @param boolean           $headingGeneration
448
     * @return LaravelExcelWorksheet
449
     */
450
    public function fromModel($source = null, $nullValue = null, $startCell = 'A1', $strictNullComparison = false, $headingGeneration = true)
451
    {
452
        return $this->fromArray($source, $nullValue, $startCell, $strictNullComparison, $headingGeneration);
453
    }
454
455
    /**
456
     * Fill worksheet from values in array
457
     *
458
     * @param array       $source               Source array
459
     * @param mixed       $nullValue            Value in source array that stands for blank cell
460
     * @param bool|string $startCell            Insert array starting from this cell address as the top left coordinate
461
     * @param boolean     $strictNullComparison Apply strict comparison when testing for null values in the array
462
     * @param bool        $headingGeneration
463
     * @throws PHPExcel_Exception
464
     * @return LaravelExcelWorksheet
465
     */
466
    public function fromArray($source = null, $nullValue = null, $startCell = 'A1', $strictNullComparison = false, $headingGeneration = true)
467
    {
468
        // Set defaults
469
        $nullValue = !is_null($nullValue) ? $nullValue : $this->getDefaultNullValue();
470
        $startCell = $startCell ? $startCell : $this->getDefaultStartCell();
471
        $strictNullComparison = $strictNullComparison ? $strictNullComparison : $this->getDefaultStrictNullComparison();
472
473
        // Set the heading generation setting
474
        $this->setAutoHeadingGeneration($headingGeneration);
475
476
        // Add the vars
477
        $this->_addVars($source, false, $nullValue, $startCell, $strictNullComparison);
478
479
        return $this;
480
    }
481
482
    /**
483
     * Create sheet from array
484
     * @param null        $source
485
     * @param null        $nullValue
486
     * @param bool|string $startCell
487
     * @param bool        $strictNullComparison
488
     * @throws PHPExcel_Exception
489
     * @return $this
490
     */
491
    public function createSheetFromArray($source = null, $nullValue = null, $startCell = 'A1', $strictNullComparison = false)
492
    {
493
        if (!is_array($source))
494
            throw new PHPExcel_Exception("Parameter \$source should be an array.");
495
496
        //    Convert a 1-D array to 2-D (for ease of looping)
497
        if (!is_array(end($source)))
498
        {
499
            $source = [$source];
500
        }
501
502
        // start coordinate
503
        list ($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($startCell);
504
505
        $currentRow = $startRow;
506
        // Loop through $source
507
        foreach ($source as $rowData)
508
        {
509
            if (!is_array($rowData))
510
                throw new PHPExcel_Exception("Row `$rowData` must be array.");
511
512
            $currentColumn = $startColumn;
513
            foreach ($rowData as $cellValue)
514
            {
515
                if ($strictNullComparison)
516
                {
517
                    if ($cellValue !== $nullValue)
518
                    {
519
                        // Set cell value
520
                        $this->setValueOfCell($cellValue, $currentColumn, $currentRow);
521
                    }
522
                }
523
                else
524
                {
525
                    if ($cellValue != $nullValue)
526
                    {
527
                        // Set cell value
528
                        $this->setValueOfCell($cellValue, $currentColumn, $currentRow);
529
                    }
530
                }
531
                $currentColumn++;
532
            }
533
            $currentRow++;
534
        }
535
536
        return $this;
537
    }
538
539
    /**
540
     * Add vars to the data array
541
     * @param string      $key
542
     * @param bool|string $value
543
     * @param null        $nullValue
544
     * @param bool|string $startCell
545
     * @param bool        $strictNullComparison
546
     * @throws PHPExcel_Exception
547
     * @return void|$this
548
     */
549
    protected function _addVars($key, $value = false, $nullValue = null, $startCell = 'A1', $strictNullComparison = false)
550
    {
551
        // Add array of data
552
        if (is_array($key) || $key instanceof Collection)
553
        {
554
            // Set the data
555
            $this->data = $this->addData($key);
556
557
            // Create excel from array without a view
558
            if (!$this->parser)
559
            {
560
                return $this->createSheetFromArray($this->data, $nullValue, $startCell, $strictNullComparison);
561
            }
562
        }
563
564
        // Add seperate values
565
        else
566
        {
567
            $this->data[$key] = $value;
568
        }
569
570
        // Set data to parser
571
        if ($this->parser)
572
            $this->parser->setData($this->data);
573
    }
574
575
    /**
576
     * Add data
577
     * @param array $array
578
     * @return  array
579
     */
580
    protected function addData($array)
581
    {
582
        // Return empty array
583
        if (empty($array))
584
            return $this->data;
585
586
        // If a parser wasn't set
587
        if (!$this->parser)
588
        {
589
            // Transform model/collection to array
590
            if ($array instanceof Collection)
591
                $array = $array->toArray();
592
593
            // Get the firstRow
594
            $firstRow = reset($array);
595
596
            // Check if the array has array values
597
            if (is_array($firstRow) && count($firstRow) != count($firstRow, 1))
598
            {
599
                // Loop through the data to remove arrays
600
                $data = [];
601
                foreach ($array as $key1 => &$row)
602
                {
603
                    $data[$key1] = [];
604
                    array_walk($row, function($cell, $key2) use ($key1, &$data) {
605
                        $data[$key1][$key2] = is_array($cell) ? '': $cell;
606
                    });
607
                }
608
            }
609
            else
610
            {
611
                $data = $array;
612
            }
613
614
            // Check if we should auto add the first row based on the indices
615
            if ($this->generateHeadingByIndices())
616
            {
617
                // Get the first row
618
                $firstRow = reset($data);
619
620
                if (is_array($firstRow))
621
                {
622
                    // Get the array keys
623
                    $tableHeading = array_keys($firstRow);
624
625
                    // Add table headings as first row
626
                    array_unshift($data, $tableHeading);
627
                }
628
            }
629
        }
630
        else
631
        {
632
            $data = $array;
633
        }
634
635
        // Add results
636
        if (!empty($data))
637
            return !empty($this->data) ? array_merge($this->data, $data) : $data;
638
639
        // Return data
640
        return $this->data;
641
    }
642
643
    /**
644
     * Set the auto heading generation setting
645
     * @param boolean $boolean
646
     * @return LaravelExcelWorksheet
647
     */
648
    public function setAutoHeadingGeneration($boolean)
649
    {
650
        $this->autoGenerateHeading = $boolean;
651
652
        return $this;
653
    }
654
655
    /**
656
     * Disable the heading generation
657
     * @param  boolean $boolean
658
     * @return LaravelExcelWorksheet
659
     */
660
    public function disableHeadingGeneration($boolean = false)
661
    {
662
        $this->setAutoHeadingGeneration($boolean);
663
664
        return $this;
665
    }
666
667
    /**
668
     * Check if we should auto generate the table heading
669
     * @return boolean
670
     */
671
    protected function generateHeadingByIndices()
672
    {
673
        return $this->autoGenerateHeading;
674
    }
675
676
    /**
677
     * Set attributes
678
     * @param              $setter
679
     * @param array|string $params
680
     * @throws LaravelExcelException
681
     * @return  void|PHPExcel_Worksheet_PageSetup
682
     */
683
    public function _setAttributes($setter, $params)
684
    {
685
        // Set the setter and the key
686
        list($setter, $key) = $this->_setSetter($setter);
687
688
        // If is page setup
689
        if (in_array($key, $this->allowedPageSetup))
690
        {
691
            // Set params
692
            $params = is_array($params) ? $params : [$params];
693
694
            // Call the setter
695
            return call_user_func_array([$this->getPageSetup(), $setter], $params);
696
        }
697
698
        // If is a style
699
        elseif (in_array($key, $this->allowedStyles))
700
        {
701
            return $this->setDefaultStyles($setter, $key, $params);
702
        }
703
        else
704
        {
705
            throw new LaravelExcelException('[ERROR] Laravel Worksheet method [' . $setter . '] does not exist.');
706
        }
707
    }
708
709
    /**
710
     * Set default styles
711
     * @param string       $setter
712
     * @param string       $key
713
     * @param array|string $params
714
     * @return PHPExcel_Style
715
     */
716
    protected function setDefaultStyles($setter, $key, $params)
717
    {
718
        $caller = $this->getDefaultStyle();
719
        $params = is_array($params) ? $params : [$params];
720
721
        if (str_contains($key, 'font'))
722
            return $this->setFontStyle($caller, $setter, $key, $params);
723
724
        return call_user_func_array([$caller, $setter], $params);
725
    }
726
727
    /**
728
     * Set default styles by array
729
     * @param array $styles
730
     * @return  LaravelExcelWorksheet
731
     */
732
    public function setStyle($styles)
733
    {
734
        $this->getDefaultStyle()->applyFromArray($styles);
735
736
        return $this;
737
    }
738
739
    /**
740
     * Set the font
741
     * @param  array $fonts
742
     * @return LaravelExcelWorksheet
743
     */
744
    public function setFont($fonts)
745
    {
746
        foreach ($fonts as $key => $value)
747
        {
748
            $this->setFontStyle($this->getDefaultStyle(), $key, $key, $value);
749
        }
750
751
        return $this;
752
    }
753
754
    /**
755
     * Set default font styles
756
     * @param string       $caller
757
     * @param string       $key
758
     * @param array|string $params
759
     * @return  PHPExcel_Style
760
     */
761
    protected function setFontStyle($caller, $setter, $key, $params)
762
    {
763
        // Set caller to font
764
        $caller = $caller->getFont();
765
        $params = is_array($params) ? $params : [$params];
766
767
        // Clean the setter name
768
        $setter = lcfirst(str_replace('Font', '', $setter));
769
770
        // Replace special cases
771
        $setter = str_replace('Family', 'Name', $setter);
772
773
        return call_user_func_array([$caller, $setter], $params);
774
    }
775
776
    /**
777
     * Set the setter
778
     * @param string $setter
779
     * @return  array
780
     */
781
    protected function _setSetter($setter)
782
    {
783
        if (starts_with($setter, 'set'))
784
        {
785
            $key = lcfirst(str_replace('set', '', $setter));
786
        }
787
        else
788
        {
789
            $key = $setter;
790
            $setter = 'set' . ucfirst($key);
791
        }
792
793
        // Return the setter method and the key
794
        return [$setter, $key];
795
    }
796
797
    /**
798
     * Set the parent (excel object)
799
     * @param PHPExcel $parent
800
     */
801
    public function setParent($parent)
802
    {
803
        $this->_parent = $parent;
804
    }
805
806
    /**
807
     * Get the parent excel obj
808
     * @return PHPExcel
809
     */
810
    public function getParent()
811
    {
812
        return $this->_parent;
813
    }
814
815
    /**
816
     * Set the column width
817
     * @param string|array $column
818
     * @param boolean      $value
819
     * @return  LaravelExcelWorksheet
820
     */
821
    public function setWidth($column, $value = false)
822
    {
823
        // if is array of columns
824
        if (is_array($column))
825
        {
826
            // Set width for each column
827
            foreach ($column as $subColumn => $subValue)
828
            {
829
                $this->setWidth($subColumn, $subValue);
830
            }
831
        }
832
        else
833
        {
834
            // Disable the autosize and set column width
835
            $this->getColumnDimension($column)
836
                ->setAutoSize(false)
837
                ->setWidth($value);
838
839
            // Set autosized to true
840
            $this->hasFixedSizeColumns = true;
841
        }
842
843
        return $this;
844
    }
845
846
    /**
847
     * Set the row height
848
     * @param integer|array $row
849
     * @param boolean       $value
850
     * @return  LaravelExcelWorksheet
851
     */
852
    public function setHeight($row, $value = false)
853
    {
854
        // if is array of columns
855
        if (is_array($row))
856
        {
857
            // Set width for each column
858
            foreach ($row as $subRow => $subValue)
859
            {
860
                $this->setHeight($subRow, $subValue);
861
            }
862
        }
863
        else
864
        {
865
            // Set column width
866
            $this->getRowDimension($row)->setRowHeight($value);
867
        }
868
869
        return $this;
870
    }
871
872
    /**
873
     * Set cell size
874
     * @param array|string $cell
875
     * @param bool         $width
876
     * @param bool|int     $height
877
     * @return  LaravelExcelWorksheet
878
     */
879
    public function setSize($cell, $width = false, $height = false)
880
    {
881
        // if is array of columns
882
        if (is_array($cell))
883
        {
884
            // Set width for each column
885
            foreach ($cell as $subCell => $sizes)
886
            {
887
                $this->setSize($subCell, reset($sizes), end($sizes));
888
            }
889
        }
890
        else
891
        {
892
            // Split the cell to column and row
893
            list($column, $row) = preg_split('/(?<=[a-z])(?=[0-9]+)/i', $cell);
894
895
            if ($column)
896
                $this->setWidth($column, $width);
897
898
            if ($row)
899
                $this->setHeight($row, $height);
900
        }
901
902
        return $this;
903
    }
904
905
    /**
906
     * Autosize column for document
907
     * @param  array|boolean $columns
908
     * @return void
909
     */
910
    public function setAutoSize($columns = false)
911
    {
912
        // Remember that the sheet was autosized
913
        $this->hasFixedSizeColumns = $columns || !empty($columns) ? false : true;
914
915
        // Set autosize to true
916
        $this->autoSize = $columns ? $columns : false;
917
918
        // If is not an array
919
        if (!is_array($columns) && $columns)
920
        {
921
            // Get the highest column
922
            $toCol = $this->getHighestColumn();
923
924
            // Lop through the columns and set the auto size
925
            $toCol++;
926
            for ($i = 'A'; $i !== $toCol; $i++)
927
            {
928
                $this->getColumnDimension($i)->setAutoSize(true);
929
            }
930
        }
931
932
        // Set autosize for the given columns
933
        elseif (is_array($columns))
934
        {
935
            foreach ($columns as $column)
936
            {
937
                $this->getColumnDimension($column)->setAutoSize(true);
938
            }
939
        }
940
941
        // Calculate the column widths
942
        $this->calculateColumnWidths();
943
944
        return $this;
945
    }
946
947
    /**
948
     * Get Auto size
949
     * @return bool
950
     */
951
    public function getAutosize()
952
    {
953
        if (isset($this->autoSize))
954
            return $this->autoSize;
955
956
        return config('excel.export.autosize', true);
957
    }
958
959
    /**
960
     * Check if the sheet was auto sized dynamically
961
     * @return boolean
962
     */
963
    public function hasFixedSizeColumns()
964
    {
965
        return $this->hasFixedSizeColumns ? true : false;
966
    }
967
968
    /**
969
     * Set the auto filter
970
     * @param boolean $value
971
     * @return  LaravelExcelWorksheet
972
     */
973
    public function setAutoFilter($value = false)
974
    {
975
        $value = $value ? $value : $this->calculateWorksheetDimension();
976
        parent::setAutoFilter($value);
977
978
        return $this;
979
    }
980
981
    /**
982
     *  Freeze or lock rows and columns
983
     * @param string $pane rows and columns
984
     * @return LaravelExcelWorksheet
985
     */
986
    public function setFreeze($pane = 'A2')
987
    {
988
        $this->freezePane($pane);
989
990
        return $this;
991
    }
992
993
    /**
994
     * Freeze the first row
995
     * @return  LaravelExcelWorksheet
996
     */
997
    public function freezeFirstRow()
998
    {
999
        $this->setFreeze('A2');
1000
1001
        return $this;
1002
    }
1003
1004
    /**
1005
     * Freeze the first column
1006
     * @return  LaravelExcelWorksheet
1007
     */
1008
    public function freezeFirstColumn()
1009
    {
1010
        $this->setFreeze('B1');
1011
1012
        return $this;
1013
    }
1014
1015
    /**
1016
     * Freeze the first row and column
1017
     * @return  LaravelExcelWorksheet
1018
     */
1019
    public function freezeFirstRowAndColumn()
1020
    {
1021
        $this->setFreeze('B2');
1022
1023
        return $this;
1024
    }
1025
1026
    /**
1027
     *  Set a range of cell borders
1028
     * @param string $pane   Start and end of the cell (A1:F10)
1029
     * @param string $weight Border style
1030
     * @return LaravelExcelWorksheet
1031
     */
1032
    public function setBorder($pane = 'A1', $weight = 'thin')
1033
    {
1034
        // Set all borders
1035
        $this->getStyle($pane)
1036
            ->getBorders()
1037
            ->getAllBorders()
1038
            ->setBorderStyle($weight);
1039
1040
        return $this;
1041
    }
1042
1043
    /**
1044
     *  Set all cell borders
1045
     * @param string $weight Border style (Reference setBorder style list)
1046
     * @return LaravelExcelWorksheet
1047
     */
1048
    public function setAllBorders($weight = 'thin')
1049
    {
1050
        $styleArray = [
1051
            'borders' => [
1052
                'allborders' => [
1053
                    'style' => $weight
1054
                ]
1055
            ]
1056
        ];
1057
1058
        // Apply the style
1059
        $this->getDefaultStyle()
1060
            ->applyFromArray($styleArray);
1061
1062
        return $this;
1063
    }
1064
1065
    /**
1066
     *  Set the cell format of the column
1067
     * @param array $formats An array of cells you want to format columns
1068
     * @return LaravelExcelWorksheet
1069
     */
1070
    public function setColumnFormat(Array $formats)
1071
    {
1072
        // Loop through the columns
1073
        foreach ($formats as $column => $format)
1074
        {
1075
            // Change the format for a specific cell or range
1076
            $this->getStyle($column)
1077
                ->getNumberFormat()
1078
                ->setFormatCode($format);
1079
        }
1080
1081
        return $this;
1082
    }
1083
1084
    /**
1085
     * Merge cells
1086
     * @param  string $pRange
1087
     * @param bool    $alignment
1088
     * @throws PHPExcel_Exception
1089
     * @return LaravelExcelWorksheet
1090
     */
1091
    public function mergeCells($pRange = 'A1:A1', $alignment = false)
1092
    {
1093
        // Merge the cells
1094
        parent::mergeCells($pRange);
1095
1096
        // Set center alignment on merge cells
1097
        $this->cells($pRange, function ($cell) use ($alignment)
1098
        {
1099
            $aligment = is_string($alignment) ? $alignment : config('excel.export.merged_cell_alignment', 'left');
1100
            $cell->setAlignment($aligment);
1101
        });
1102
1103
        return $this;
1104
    }
1105
1106
    /**
1107
     *  Set the columns you want to merge
1108
     * @return LaravelExcelWorksheet
1109
     * @param array $mergeColumn An array of columns you want to merge
1110
     * @param bool  $alignment
1111
     */
1112
    public function setMergeColumn(Array $mergeColumn, $alignment = false)
1113
    {
1114
        foreach ($mergeColumn['columns'] as $column)
1115
        {
1116
            foreach ($mergeColumn['rows'] as $row)
1117
            {
1118
                $this->mergeCells($column . $row[0] . ":" . $column . $row[1], $alignment);
1119
            }
1120
        }
1121
1122
        return $this;
1123
    }
1124
1125
    /**
1126
     * Password protect a sheet
1127
     * @param          $password
1128
     * @param callable $callback
1129
     */
1130
    public function protect($password, Closure $callback = null)
1131
    {
1132
        $protection = $this->getProtection();
1133
        $protection->setPassword($password);
1134
        $protection->setSheet(true);
1135
        $protection->setSort(true);
1136
        $protection->setInsertRows(true);
1137
        $protection->setFormatCells(true);
1138
1139
        if(is_callable($callback)) {
1140
            call_user_func($callback, $protection);
1141
        }
1142
    }
1143
1144
    /**
1145
     * Return the start row
1146
     * @return integer
1147
     */
1148
    protected function getStartRow()
1149
    {
1150
        if ($this->getHighestRow() == 1 && !$this->hasRowsAdded)
1151
            return 1;
1152
1153
        return $this->getHighestRow() + 1;
1154
    }
1155
1156
    /**
1157
     * Return range from row
1158
     * @param  integer $rowNumber
1159
     * @return string $range
1160
     */
1161
    protected function rowToRange($rowNumber)
1162
    {
1163
        return 'A' . $rowNumber . ':' . $this->getHighestColumn() . $rowNumber;
1164
    }
1165
1166
    /**
1167
     * Return default null value
1168
     * @return string|integer|null
1169
     */
1170
    protected function getDefaultNullValue()
1171
    {
1172
        return config('excel.export.sheets.nullValue', null);
1173
    }
1174
1175
    /**
1176
     * Return default null value
1177
     * @return string|integer|null
1178
     */
1179
    protected function getDefaultStartCell()
1180
    {
1181
        return config('excel.export.sheets.startCell', 'A1');
1182
    }
1183
1184
1185
    /**
1186
     * Return default strict null comparison
1187
     * @return boolean
1188
     */
1189
    protected function getDefaultStrictNullComparison()
1190
    {
1191
        return config('excel.export.sheets.strictNullComparison', false);
1192
    }
1193
1194
    /**
1195
     * load info from parent obj
1196
     * @param \PHPExcel_Worksheet $sheet
1197
     * @return $this
1198
     */
1199
    function cloneParent(PHPExcel_Worksheet $sheet)
1200
    {
1201
        // Init new reflection object
1202
        $class = new \ReflectionClass(get_class($sheet));
1203
1204
        // Loop through all properties
1205
        foreach($class->getProperties() as $property)
1206
        {
1207
            // Make the property public
1208
            $property->setAccessible(true);
1209
1210
            // Get value from original sheet
1211
            $value = $property->getValue($sheet);
1212
1213
            // Set the found value to this sheet
1214
            $property->setValue(
1215
                $this,
1216
                $value
1217
            );
1218
        }
1219
1220
        // Rebind the PhpExcel object to the style objects
1221
        $this->getStyle()->bindParent($this->getParent());
1222
1223
        return $this;
1224
    }
1225
1226
    /**
1227
     * Dynamically call methods
1228
     * @param  string $method
1229
     * @param  array  $params
1230
     * @throws LaravelExcelException
1231
     * @return LaravelExcelWorksheet
1232
     */
1233
    public function __call($method, $params)
1234
    {
1235
        // If the dynamic call starts with "with", add the var to the data array
1236
        if (starts_with($method, 'with'))
1237
        {
1238
            $key = lcfirst(str_replace('with', '', $method));
1239
            $this->_addVars($key, reset($params));
1240
1241
            return $this;
1242
        }
1243
1244
        // If it's a setter
1245
        elseif (starts_with($method, 'set'))
1246
        {
1247
            // set the attribute
1248
            $this->_setAttributes($method, $params);
1249
1250
            return $this;
1251
        }
1252
1253
        throw new LaravelExcelException('[ERROR] Laravel Worksheet method [' . $method . '] does not exist.');
1254
    }
1255
1256
    /**
1257
     * @param string     $cellValue
1258
     * @param mixed|null $currentColumn
1259
     * @param bool       $startRow
1260
     * @return \PHPExcel_Cell|\PHPExcel_Worksheet|void
1261
     * @throws PHPExcel_Exception
1262
     */
1263
    public function setValueOfCell($cellValue, $currentColumn, $startRow)
1264
    {
1265
        is_string($cellValue) && is_numeric($cellValue) && !is_integer($cellValue)
1266
            ? $this->getCell($currentColumn . $startRow)->setValueExplicit($cellValue)
1267
            : $this->getCell($currentColumn . $startRow)->setValue($cellValue);
1268
    }
1269
1270
    /**
1271
     * Allowed page setup
1272
     * @return array
1273
     */
1274
    public function getAllowedPageSetup()
1275
    {
1276
        return $this->allowedPageSetup;
1277
    }
1278
1279
    /**
1280
     * Allowed page setup
1281
     * @return array
1282
     */
1283
    public function getAllowedStyles()
1284
    {
1285
        return $this->allowedStyles;
1286
    }
1287
}
1288