Passed
Push — master ( fde2cc...f1d90a )
by Mark
17:04 queued 08:09
created

Cell::getAppliedStyle()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.0175

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 0
dl 0
loc 13
ccs 7
cts 8
cp 0.875
crap 3.0175
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Cell;
4
5
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
6
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
7
use PhpOffice\PhpSpreadsheet\Collection\Cells;
8
use PhpOffice\PhpSpreadsheet\Exception;
9
use PhpOffice\PhpSpreadsheet\RichText\RichText;
10
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDate;
11
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
12
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\CellStyleAssessor;
13
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
14
use PhpOffice\PhpSpreadsheet\Style\Style;
15
use PhpOffice\PhpSpreadsheet\Worksheet\Table;
16
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
17
18
class Cell
19
{
20
    /**
21
     * Value binder to use.
22
     *
23
     * @var IValueBinder
24
     */
25
    private static $valueBinder;
26
27
    /**
28
     * Value of the cell.
29
     *
30
     * @var mixed
31
     */
32
    private $value;
33
34
    /**
35
     *    Calculated value of the cell (used for caching)
36
     *    This returns the value last calculated by MS Excel or whichever spreadsheet program was used to
37
     *        create the original spreadsheet file.
38
     *    Note that this value is not guaranteed to reflect the actual calculated value because it is
39
     *        possible that auto-calculation was disabled in the original spreadsheet, and underlying data
40
     *        values used by the formula have changed since it was last calculated.
41
     *
42
     * @var mixed
43
     */
44
    private $calculatedValue;
45
46
    /**
47
     * Type of the cell data.
48
     *
49
     * @var string
50
     */
51
    private $dataType;
52
53
    /**
54
     * The collection of cells that this cell belongs to (i.e. The Cell Collection for the parent Worksheet).
55
     *
56
     * @var ?Cells
57
     */
58
    private $parent;
59
60
    /**
61
     * Index to the cellXf reference for the styling of this cell.
62
     *
63
     * @var int
64
     */
65
    private $xfIndex = 0;
66
67
    /**
68
     * Attributes of the formula.
69
     *
70
     * @var mixed
71
     */
72
    private $formulaAttributes;
73
74
    /** @var IgnoredErrors */
75
    private $ignoredErrors;
76
77
    /**
78
     * Update the cell into the cell collection.
79
     *
80
     * @return $this
81
     */
82 9450
    public function updateInCollection(): self
83
    {
84 9450
        $parent = $this->parent;
85 9450
        if ($parent === null) {
86 2
            throw new Exception('Cannot update when cell is not bound to a worksheet');
87
        }
88 9448
        $parent->update($this);
89
90 9448
        return $this;
91
    }
92
93 8949
    public function detach(): void
94
    {
95 8949
        $this->parent = null;
96
    }
97
98 8348
    public function attach(Cells $parent): void
99
    {
100 8348
        $this->parent = $parent;
101
    }
102
103
    /**
104
     * Create a new Cell.
105
     *
106
     * @param mixed $value
107
     */
108 9501
    public function __construct($value, ?string $dataType, Worksheet $worksheet)
109
    {
110
        // Initialise cell value
111 9501
        $this->value = $value;
112
113
        // Set worksheet cache
114 9501
        $this->parent = $worksheet->getCellCollection();
115
116
        // Set datatype?
117 9501
        if ($dataType !== null) {
118 9501
            if ($dataType == DataType::TYPE_STRING2) {
119
                $dataType = DataType::TYPE_STRING;
120
            }
121 9501
            $this->dataType = $dataType;
122
        } elseif (self::getValueBinder()->bindValue($this, $value) === false) {
123
            throw new Exception('Value could not be bound to cell.');
124
        }
125 9501
        $this->ignoredErrors = new IgnoredErrors();
126
    }
127
128
    /**
129
     * Get cell coordinate column.
130
     *
131
     * @return string
132
     */
133 513
    public function getColumn()
134
    {
135 513
        $parent = $this->parent;
136 513
        if ($parent === null) {
137 1
            throw new Exception('Cannot get column when cell is not bound to a worksheet');
138
        }
139
140 512
        return $parent->getCurrentColumn();
141
    }
142
143
    /**
144
     * Get cell coordinate row.
145
     *
146
     * @return int
147
     */
148 503
    public function getRow()
149
    {
150 503
        $parent = $this->parent;
151 503
        if ($parent === null) {
152 1
            throw new Exception('Cannot get row when cell is not bound to a worksheet');
153
        }
154
155 502
        return $parent->getCurrentRow();
156
    }
157
158
    /**
159
     * Get cell coordinate.
160
     *
161
     * @return string
162
     */
163 9456
    public function getCoordinate()
164
    {
165 9456
        $parent = $this->parent;
166 9456
        if ($parent !== null) {
167 9456
            $coordinate = $parent->getCurrentCoordinate();
168
        } else {
169 2
            $coordinate = null;
170
        }
171 9456
        if ($coordinate === null) {
172 2
            throw new Exception('Coordinate no longer exists');
173
        }
174
175 9456
        return $coordinate;
176
    }
177
178
    /**
179
     * Get cell value.
180
     *
181
     * @return mixed
182
     */
183 8858
    public function getValue()
184
    {
185 8858
        return $this->value;
186
    }
187
188
    /**
189
     * Get cell value with formatting.
190
     */
191 83
    public function getFormattedValue(): string
192
    {
193 83
        return (string) NumberFormat::toFormattedString(
194 83
            $this->getCalculatedValue(),
195 83
            (string) $this->getStyle()->getNumberFormat()->getFormatCode()
196 83
        );
197
    }
198
199
    /**
200
     * @param mixed $oldValue
201
     * @param mixed $newValue
202
     */
203 9417
    protected static function updateIfCellIsTableHeader(?Worksheet $workSheet, self $cell, $oldValue, $newValue): void
204
    {
205 9417
        if (StringHelper::strToLower($oldValue ?? '') === StringHelper::strToLower($newValue ?? '') || $workSheet === null) {
206 850
            return;
207
        }
208
209 9383
        foreach ($workSheet->getTableCollection() as $table) {
210
            /** @var Table $table */
211 9
            if ($cell->isInRange($table->getRange())) {
212 7
                $rangeRowsColumns = Coordinate::getRangeBoundaries($table->getRange());
213 7
                if ($cell->getRow() === (int) $rangeRowsColumns[0][1]) {
214 4
                    Table\Column::updateStructuredReferences($workSheet, $oldValue, $newValue);
215
                }
216
217 7
                return;
218
            }
219
        }
220
    }
221
222
    /**
223
     * Set cell value.
224
     *
225
     *    Sets the value for a cell, automatically determining the datatype using the value binder
226
     *
227
     * @param mixed $value Value
228
     * @param null|IValueBinder $binder Value Binder to override the currently set Value Binder
229
     *
230
     * @throws Exception
231
     *
232
     * @return $this
233
     */
234 9163
    public function setValue($value, ?IValueBinder $binder = null): self
235
    {
236 9163
        $binder ??= self::getValueBinder();
237 9163
        if (!$binder->bindValue($this, $value)) {
238
            throw new Exception('Value could not be bound to cell.');
239
        }
240
241 9162
        return $this;
242
    }
243
244
    /**
245
     * Set the value for a cell, with the explicit data type passed to the method (bypassing any use of the value binder).
246
     *
247
     * @param mixed $value Value
248
     * @param string $dataType Explicit data type, see DataType::TYPE_*
249
     *        Note that PhpSpreadsheet does not validate that the value and datatype are consistent, in using this
250
     *             method, then it is your responsibility as an end-user developer to validate that the value and
251
     *             the datatype match.
252
     *       If you do mismatch value and datatype, then the value you enter may be changed to match the datatype
253
     *          that you specify.
254
     *
255
     * @return Cell
256
     */
257 9420
    public function setValueExplicit($value, string $dataType = DataType::TYPE_STRING)
258
    {
259 9420
        $oldValue = $this->value;
260
261
        // set the value according to data type
262
        switch ($dataType) {
263 260
            case DataType::TYPE_NULL:
264 537
                $this->value = null;
265
266 537
                break;
267 259
            case DataType::TYPE_STRING2:
268 2
                $dataType = DataType::TYPE_STRING;
269
                // no break
270 259
            case DataType::TYPE_STRING:
271
                // Synonym for string
272 234
            case DataType::TYPE_INLINE:
273
                // Rich text
274 4819
                $this->value = DataType::checkString($value);
275
276 4819
                break;
277 233
            case DataType::TYPE_NUMERIC:
278 6827
                if (is_string($value) && !is_numeric($value)) {
279 1
                    throw new Exception('Invalid numeric value for datatype Numeric');
280
                }
281 6826
                $this->value = 0 + $value;
282
283 6826
                break;
284 192
            case DataType::TYPE_FORMULA:
285 8036
                $this->value = (string) $value;
286
287 8036
                break;
288 17
            case DataType::TYPE_BOOL:
289 594
                $this->value = (bool) $value;
290
291 594
                break;
292
            case DataType::TYPE_ISO_DATE:
293 6
                $this->value = SharedDate::convertIsoDate($value);
294 5
                $dataType = DataType::TYPE_NUMERIC;
295
296 5
                break;
297
            case DataType::TYPE_ERROR:
298 19
                $this->value = DataType::checkErrorCode($value);
299
300 19
                break;
301
            default:
302 1
                throw new Exception('Invalid datatype: ' . $dataType);
303
        }
304
305
        // set the datatype
306 9418
        $this->dataType = $dataType;
307
308 9418
        $this->updateInCollection();
309 9417
        $cellCoordinate = $this->getCoordinate();
310 9417
        self::updateIfCellIsTableHeader($this->getParent()->getParent(), $this, $oldValue, $value); // @phpstan-ignore-line
311
312 9417
        return $this->getParent()->get($cellCoordinate); // @phpstan-ignore-line
313
    }
314
315
    public const CALCULATE_DATE_TIME_ASIS = 0;
316
    public const CALCULATE_DATE_TIME_FLOAT = 1;
317
    public const CALCULATE_TIME_FLOAT = 2;
318
319
    /** @var int */
320
    private static $calculateDateTimeType = self::CALCULATE_DATE_TIME_ASIS;
321
322 45
    public static function getCalculateDateTimeType(): int
323
    {
324 45
        return self::$calculateDateTimeType;
325
    }
326
327 45
    public static function setCalculateDateTimeType(int $calculateDateTimeType): void
328
    {
329
        switch ($calculateDateTimeType) {
330
            case self::CALCULATE_DATE_TIME_ASIS:
331
            case self::CALCULATE_DATE_TIME_FLOAT:
332
            case self::CALCULATE_TIME_FLOAT:
333 45
                self::$calculateDateTimeType = $calculateDateTimeType;
334
335 45
                break;
336
            default:
337 1
                throw new \PhpOffice\PhpSpreadsheet\Calculation\Exception("Invalid value $calculateDateTimeType for calculated date time type");
338
        }
339
    }
340
341
    /**
342
     * Convert date, time, or datetime from int to float if desired.
343
     *
344
     * @param mixed $result
345
     *
346
     * @return mixed
347
     */
348 8366
    private function convertDateTimeInt($result)
349
    {
350 8366
        if (is_int($result)) {
351 4393
            if (self::$calculateDateTimeType === self::CALCULATE_TIME_FLOAT) {
352 4
                if (SharedDate::isDateTime($this, $result, false)) {
353 4
                    $result = (float) $result;
354
                }
355 4389
            } elseif (self::$calculateDateTimeType === self::CALCULATE_DATE_TIME_FLOAT) {
356 4
                if (SharedDate::isDateTime($this, $result, true)) {
357 3
                    $result = (float) $result;
358
                }
359
            }
360
        }
361
362 8366
        return $result;
363
    }
364
365
    /**
366
     * Get calculated cell value.
367
     *
368
     * @param bool $resetLog Whether the calculation engine logger should be reset or not
369
     *
370
     * @return mixed
371
     */
372 8603
    public function getCalculatedValue(bool $resetLog = true)
373
    {
374 8603
        if ($this->dataType === DataType::TYPE_FORMULA) {
375
            try {
376 7719
                $index = $this->getWorksheet()->getParentOrThrow()->getActiveSheetIndex();
377 7719
                $selected = $this->getWorksheet()->getSelectedCells();
378 7719
                $result = Calculation::getInstance(
379 7719
                    $this->getWorksheet()->getParent()
380 7719
                )->calculateCellValue($this, $resetLog);
381 7480
                $result = $this->convertDateTimeInt($result);
382 7480
                $this->getWorksheet()->setSelectedCells($selected);
383 7480
                $this->getWorksheet()->getParentOrThrow()->setActiveSheetIndex($index);
384
                //    We don't yet handle array returns
385 7480
                if (is_array($result)) {
386 7480
                    while (is_array($result)) {
387 4737
                        $result = array_shift($result);
388
                    }
389
                }
390 256
            } catch (Exception $ex) {
391 256
                if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->calculatedValue !== null)) {
392 1
                    return $this->calculatedValue; // Fallback for calculations referencing external files.
393 256
                } elseif (preg_match('/[Uu]ndefined (name|offset: 2|array key 2)/', $ex->getMessage()) === 1) {
394 28
                    return ExcelError::NAME();
395
                }
396
397 228
                throw new \PhpOffice\PhpSpreadsheet\Calculation\Exception(
398 228
                    $this->getWorksheet()->getTitle() . '!' . $this->getCoordinate() . ' -> ' . $ex->getMessage(),
399 228
                    $ex->getCode(),
400 228
                    $ex
401 228
                );
402
            }
403
404 7480
            if ($result === '#Not Yet Implemented') {
405 3
                return $this->calculatedValue; // Fallback if calculation engine does not support the formula.
406
            }
407
408 7480
            return $result;
409 7368
        } elseif ($this->value instanceof RichText) {
410 19
            return $this->value->getPlainText();
411
        }
412
413 7363
        return $this->convertDateTimeInt($this->value);
414
    }
415
416
    /**
417
     * Set old calculated value (cached).
418
     *
419
     * @param mixed $originalValue Value
420
     */
421 375
    public function setCalculatedValue($originalValue): self
422
    {
423 375
        if ($originalValue !== null) {
424 375
            $this->calculatedValue = (is_numeric($originalValue)) ? (float) $originalValue : $originalValue;
425
        }
426
427 375
        return $this->updateInCollection();
428
    }
429
430
    /**
431
     *    Get old calculated value (cached)
432
     *    This returns the value last calculated by MS Excel or whichever spreadsheet program was used to
433
     *        create the original spreadsheet file.
434
     *    Note that this value is not guaranteed to reflect the actual calculated value because it is
435
     *        possible that auto-calculation was disabled in the original spreadsheet, and underlying data
436
     *        values used by the formula have changed since it was last calculated.
437
     *
438
     * @return mixed
439
     */
440 3
    public function getOldCalculatedValue()
441
    {
442 3
        return $this->calculatedValue;
443
    }
444
445
    /**
446
     * Get cell data type.
447
     */
448 1284
    public function getDataType(): string
449
    {
450 1284
        return $this->dataType;
451
    }
452
453
    /**
454
     * Set cell data type.
455
     *
456
     * @param string $dataType see DataType::TYPE_*
457
     */
458
    public function setDataType($dataType): self
459
    {
460
        if ($dataType == DataType::TYPE_STRING2) {
461
            $dataType = DataType::TYPE_STRING;
462
        }
463
        $this->dataType = $dataType;
464
465
        return $this->updateInCollection();
466
    }
467
468
    /**
469
     * Identify if the cell contains a formula.
470
     */
471 67
    public function isFormula(): bool
472
    {
473 67
        return $this->dataType === DataType::TYPE_FORMULA && $this->getStyle()->getQuotePrefix() === false;
474
    }
475
476
    /**
477
     *    Does this cell contain Data validation rules?
478
     */
479 16
    public function hasDataValidation(): bool
480
    {
481 16
        if (!isset($this->parent)) {
482 1
            throw new Exception('Cannot check for data validation when cell is not bound to a worksheet');
483
        }
484
485 15
        return $this->getWorksheet()->dataValidationExists($this->getCoordinate());
486
    }
487
488
    /**
489
     * Get Data validation rules.
490
     */
491 27
    public function getDataValidation(): DataValidation
492
    {
493 27
        if (!isset($this->parent)) {
494 1
            throw new Exception('Cannot get data validation for cell that is not bound to a worksheet');
495
        }
496
497 26
        return $this->getWorksheet()->getDataValidation($this->getCoordinate());
498
    }
499
500
    /**
501
     * Set Data validation rules.
502
     */
503 4
    public function setDataValidation(?DataValidation $dataValidation = null): self
504
    {
505 4
        if (!isset($this->parent)) {
506 1
            throw new Exception('Cannot set data validation for cell that is not bound to a worksheet');
507
        }
508
509 3
        $this->getWorksheet()->setDataValidation($this->getCoordinate(), $dataValidation);
510
511 3
        return $this->updateInCollection();
512
    }
513
514
    /**
515
     * Does this cell contain valid value?
516
     */
517 7
    public function hasValidValue(): bool
518
    {
519 7
        $validator = new DataValidator();
520
521 7
        return $validator->isValid($this);
522
    }
523
524
    /**
525
     * Does this cell contain a Hyperlink?
526
     */
527 1
    public function hasHyperlink(): bool
528
    {
529 1
        if (!isset($this->parent)) {
530 1
            throw new Exception('Cannot check for hyperlink when cell is not bound to a worksheet');
531
        }
532
533
        return $this->getWorksheet()->hyperlinkExists($this->getCoordinate());
534
    }
535
536
    /**
537
     * Get Hyperlink.
538
     */
539 63
    public function getHyperlink(): Hyperlink
540
    {
541 63
        if (!isset($this->parent)) {
542 1
            throw new Exception('Cannot get hyperlink for cell that is not bound to a worksheet');
543
        }
544
545 62
        return $this->getWorksheet()->getHyperlink($this->getCoordinate());
546
    }
547
548
    /**
549
     * Set Hyperlink.
550
     */
551 1
    public function setHyperlink(?Hyperlink $hyperlink = null): self
552
    {
553 1
        if (!isset($this->parent)) {
554 1
            throw new Exception('Cannot set hyperlink for cell that is not bound to a worksheet');
555
        }
556
557
        $this->getWorksheet()->setHyperlink($this->getCoordinate(), $hyperlink);
558
559
        return $this->updateInCollection();
560
    }
561
562
    /**
563
     * Get cell collection.
564
     *
565
     * @return ?Cells
566
     */
567 9419
    public function getParent()
568
    {
569 9419
        return $this->parent;
570
    }
571
572
    /**
573
     * Get parent worksheet.
574
     */
575 8669
    public function getWorksheet(): Worksheet
576
    {
577 8669
        $parent = $this->parent;
578 8669
        if ($parent !== null) {
579 8669
            $worksheet = $parent->getParent();
580
        } else {
581 1
            $worksheet = null;
582
        }
583
584 8669
        if ($worksheet === null) {
585 1
            throw new Exception('Worksheet no longer exists');
586
        }
587
588 8669
        return $worksheet;
589
    }
590
591 9
    public function getWorksheetOrNull(): ?Worksheet
592
    {
593 9
        $parent = $this->parent;
594 9
        if ($parent !== null) {
595 9
            $worksheet = $parent->getParent();
596
        } else {
597
            $worksheet = null;
598
        }
599
600 9
        return $worksheet;
601
    }
602
603
    /**
604
     * Is this cell in a merge range.
605
     */
606 7
    public function isInMergeRange(): bool
607
    {
608 7
        return (bool) $this->getMergeRange();
609
    }
610
611
    /**
612
     * Is this cell the master (top left cell) in a merge range (that holds the actual data value).
613
     */
614 27
    public function isMergeRangeValueCell(): bool
615
    {
616 27
        if ($mergeRange = $this->getMergeRange()) {
617 5
            $mergeRange = Coordinate::splitRange($mergeRange);
618 5
            [$startCell] = $mergeRange[0];
619
620 5
            return $this->getCoordinate() === $startCell;
621
        }
622
623 24
        return false;
624
    }
625
626
    /**
627
     * If this cell is in a merge range, then return the range.
628
     *
629
     * @return false|string
630
     */
631 30
    public function getMergeRange()
632
    {
633 30
        foreach ($this->getWorksheet()->getMergeCells() as $mergeRange) {
634 5
            if ($this->isInRange($mergeRange)) {
635 5
                return $mergeRange;
636
            }
637
        }
638
639 27
        return false;
640
    }
641
642
    /**
643
     * Get cell style.
644
     */
645 8528
    public function getStyle(): Style
646
    {
647 8528
        return $this->getWorksheet()->getStyle($this->getCoordinate());
648
    }
649
650
    /**
651
     * Get cell style.
652
     */
653 6
    public function getAppliedStyle(): Style
654
    {
655 6
        if ($this->getWorksheet()->conditionalStylesExists($this->getCoordinate()) === false) {
656 2
            return $this->getStyle();
657
        }
658 4
        $range = $this->getWorksheet()->getConditionalRange($this->getCoordinate());
659 4
        if ($range === null) {
660
            return $this->getStyle();
661
        }
662
663 4
        $matcher = new CellStyleAssessor($this, $range);
664
665 4
        return $matcher->matchConditions($this->getWorksheet()->getConditionalStyles($this->getCoordinate()));
666
    }
667
668
    /**
669
     * Re-bind parent.
670
     */
671
    public function rebindParent(Worksheet $parent): self
672
    {
673
        $this->parent = $parent->getCellCollection();
674
675
        return $this->updateInCollection();
676
    }
677
678
    /**
679
     *    Is cell in a specific range?
680
     *
681
     * @param string $range Cell range (e.g. A1:A1)
682
     */
683 233
    public function isInRange(string $range): bool
684
    {
685 233
        [$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($range);
686
687
        // Translate properties
688 233
        $myColumn = Coordinate::columnIndexFromString($this->getColumn());
689 233
        $myRow = $this->getRow();
690
691
        // Verify if cell is in range
692 233
        return ($rangeStart[0] <= $myColumn) && ($rangeEnd[0] >= $myColumn) &&
693 233
                ($rangeStart[1] <= $myRow) && ($rangeEnd[1] >= $myRow);
694
    }
695
696
    /**
697
     * Compare 2 cells.
698
     *
699
     * @param Cell $a Cell a
700
     * @param Cell $b Cell b
701
     *
702
     * @return int Result of comparison (always -1 or 1, never zero!)
703
     */
704
    public static function compareCells(self $a, self $b): int
705
    {
706
        if ($a->getRow() < $b->getRow()) {
707
            return -1;
708
        } elseif ($a->getRow() > $b->getRow()) {
709
            return 1;
710
        } elseif (Coordinate::columnIndexFromString($a->getColumn()) < Coordinate::columnIndexFromString($b->getColumn())) {
711
            return -1;
712
        }
713
714
        return 1;
715
    }
716
717
    /**
718
     * Get value binder to use.
719
     */
720 9164
    public static function getValueBinder(): IValueBinder
721
    {
722 9164
        if (self::$valueBinder === null) {
723 236
            self::$valueBinder = new DefaultValueBinder();
724
        }
725
726 9164
        return self::$valueBinder;
727
    }
728
729
    /**
730
     * Set value binder to use.
731
     */
732 145
    public static function setValueBinder(IValueBinder $binder): void
733
    {
734 145
        self::$valueBinder = $binder;
735
    }
736
737
    /**
738
     * Implement PHP __clone to create a deep clone, not just a shallow copy.
739
     */
740 6
    public function __clone()
741
    {
742 6
        $vars = get_object_vars($this);
743 6
        foreach ($vars as $propertyName => $propertyValue) {
744 6
            if ((is_object($propertyValue)) && ($propertyName !== 'parent')) {
745 6
                $this->$propertyName = clone $propertyValue;
746
            } else {
747 6
                $this->$propertyName = $propertyValue;
748
            }
749
        }
750
    }
751
752
    /**
753
     * Get index to cellXf.
754
     */
755 8944
    public function getXfIndex(): int
756
    {
757 8944
        return $this->xfIndex;
758
    }
759
760
    /**
761
     * Set index to cellXf.
762
     */
763 1497
    public function setXfIndex(int $indexValue): self
764
    {
765 1497
        $this->xfIndex = $indexValue;
766
767 1497
        return $this->updateInCollection();
768
    }
769
770
    /**
771
     * Set the formula attributes.
772
     *
773
     * @param mixed $attributes
774
     *
775
     * @return $this
776
     */
777 2
    public function setFormulaAttributes($attributes): self
778
    {
779 2
        $this->formulaAttributes = $attributes;
780
781 2
        return $this;
782
    }
783
784
    /**
785
     * Get the formula attributes.
786
     *
787
     * @return mixed
788
     */
789 77
    public function getFormulaAttributes()
790
    {
791 77
        return $this->formulaAttributes;
792
    }
793
794
    /**
795
     * Convert to string.
796
     *
797
     * @return string
798
     */
799 1
    public function __toString()
800
    {
801 1
        return (string) $this->getValue();
802
    }
803
804 274
    public function getIgnoredErrors(): IgnoredErrors
805
    {
806 274
        return $this->ignoredErrors;
807
    }
808
}
809