Passed
Pull Request — master (#3468)
by Mark
17:10 queued 07:39
created

Style::allConditionalStyles()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 4
nop 1
dl 0
loc 15
ccs 8
cts 8
cp 1
crap 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx;
4
5
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Namespaces;
6
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
7
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
8
use PhpOffice\PhpSpreadsheet\Spreadsheet;
9
use PhpOffice\PhpSpreadsheet\Style\Alignment;
10
use PhpOffice\PhpSpreadsheet\Style\Border;
11
use PhpOffice\PhpSpreadsheet\Style\Borders;
12
use PhpOffice\PhpSpreadsheet\Style\Conditional;
13
use PhpOffice\PhpSpreadsheet\Style\Fill;
14
use PhpOffice\PhpSpreadsheet\Style\Font;
15
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
16
use PhpOffice\PhpSpreadsheet\Style\Protection;
17
18
class Style extends WriterPart
19
{
20
    /**
21
     * Write styles to XML format.
22
     *
23
     * @return string XML Output
24
     */
25 266
    public function writeStyles(Spreadsheet $spreadsheet)
26
    {
27
        // Create XML writer
28 266
        $objWriter = null;
29 266
        if ($this->getParentWriter()->getUseDiskCaching()) {
30
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
31
        } else {
32 266
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
33
        }
34
35
        // XML header
36 266
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
37
38
        // styleSheet
39 266
        $objWriter->startElement('styleSheet');
40 266
        $objWriter->writeAttribute('xml:space', 'preserve');
41 266
        $objWriter->writeAttribute('xmlns', Namespaces::MAIN);
42
43
        // numFmts
44 266
        $objWriter->startElement('numFmts');
45 266
        $objWriter->writeAttribute('count', (string) $this->getParentWriter()->getNumFmtHashTable()->count());
46
47
        // numFmt
48 266
        for ($i = 0; $i < $this->getParentWriter()->getNumFmtHashTable()->count(); ++$i) {
49 37
            $this->writeNumFmt($objWriter, $this->getParentWriter()->getNumFmtHashTable()->getByIndex($i), $i);
50
        }
51
52 266
        $objWriter->endElement();
53
54
        // fonts
55 266
        $objWriter->startElement('fonts');
56 266
        $objWriter->writeAttribute('count', (string) $this->getParentWriter()->getFontHashTable()->count());
57
58
        // font
59 266
        for ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) {
60 266
            $thisfont = $this->getParentWriter()->getFontHashTable()->getByIndex($i);
61 266
            if ($thisfont !== null) {
62 266
                $this->writeFont($objWriter, $thisfont);
63
            }
64
        }
65
66 266
        $objWriter->endElement();
67
68
        // fills
69 266
        $objWriter->startElement('fills');
70 266
        $objWriter->writeAttribute('count', (string) $this->getParentWriter()->getFillHashTable()->count());
71
72
        // fill
73 266
        for ($i = 0; $i < $this->getParentWriter()->getFillHashTable()->count(); ++$i) {
74 266
            $thisfill = $this->getParentWriter()->getFillHashTable()->getByIndex($i);
75 266
            if ($thisfill !== null) {
76 266
                $this->writeFill($objWriter, $thisfill);
77
            }
78
        }
79
80 266
        $objWriter->endElement();
81
82
        // borders
83 266
        $objWriter->startElement('borders');
84 266
        $objWriter->writeAttribute('count', (string) $this->getParentWriter()->getBordersHashTable()->count());
85
86
        // border
87 266
        for ($i = 0; $i < $this->getParentWriter()->getBordersHashTable()->count(); ++$i) {
88 266
            $thisborder = $this->getParentWriter()->getBordersHashTable()->getByIndex($i);
89 266
            if ($thisborder !== null) {
90 266
                $this->writeBorder($objWriter, $thisborder);
91
            }
92
        }
93
94 266
        $objWriter->endElement();
95
96
        // cellStyleXfs
97 266
        $objWriter->startElement('cellStyleXfs');
98 266
        $objWriter->writeAttribute('count', '1');
99
100
        // xf
101 266
        $objWriter->startElement('xf');
102 266
        $objWriter->writeAttribute('numFmtId', '0');
103 266
        $objWriter->writeAttribute('fontId', '0');
104 266
        $objWriter->writeAttribute('fillId', '0');
105 266
        $objWriter->writeAttribute('borderId', '0');
106 266
        $objWriter->endElement();
107
108 266
        $objWriter->endElement();
109
110
        // cellXfs
111 266
        $objWriter->startElement('cellXfs');
112 266
        $objWriter->writeAttribute('count', (string) count($spreadsheet->getCellXfCollection()));
113
114
        // xf
115 266
        $alignment = new Alignment();
116 266
        $defaultAlignHash = $alignment->getHashCode();
117 266
        if ($defaultAlignHash !== $spreadsheet->getDefaultStyle()->getAlignment()->getHashCode()) {
118 6
            $defaultAlignHash = '';
119
        }
120 266
        foreach ($spreadsheet->getCellXfCollection() as $cellXf) {
121 266
            $this->writeCellStyleXf($objWriter, $cellXf, $spreadsheet, $defaultAlignHash);
122
        }
123
124 266
        $objWriter->endElement();
125
126
        // cellStyles
127 266
        $objWriter->startElement('cellStyles');
128 266
        $objWriter->writeAttribute('count', '1');
129
130
        // cellStyle
131 266
        $objWriter->startElement('cellStyle');
132 266
        $objWriter->writeAttribute('name', 'Normal');
133 266
        $objWriter->writeAttribute('xfId', '0');
134 266
        $objWriter->writeAttribute('builtinId', '0');
135 266
        $objWriter->endElement();
136
137 266
        $objWriter->endElement();
138
139
        // dxfs
140 266
        $objWriter->startElement('dxfs');
141 266
        $objWriter->writeAttribute('count', (string) $this->getParentWriter()->getStylesConditionalHashTable()->count());
142
143
        // dxf
144 266
        for ($i = 0; $i < $this->getParentWriter()->getStylesConditionalHashTable()->count(); ++$i) {
145 23
            $thisstyle = $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i);
146 23
            if ($thisstyle !== null) {
147 23
                $this->writeCellStyleDxf($objWriter, $thisstyle->getStyle());
148
            }
149
        }
150
151 266
        $objWriter->endElement();
152
153
        // tableStyles
154 266
        $objWriter->startElement('tableStyles');
155 266
        $objWriter->writeAttribute('defaultTableStyle', 'TableStyleMedium9');
156 266
        $objWriter->writeAttribute('defaultPivotStyle', 'PivotTableStyle1');
157 266
        $objWriter->endElement();
158
159 266
        $objWriter->endElement();
160
161
        // Return
162 266
        return $objWriter->getData();
163
    }
164
165
    /**
166
     * Write Fill.
167
     */
168 266
    private function writeFill(XMLWriter $objWriter, Fill $fill): void
169
    {
170
        // Check if this is a pattern type or gradient type
171
        if (
172 266
            $fill->getFillType() === Fill::FILL_GRADIENT_LINEAR ||
173 266
            $fill->getFillType() === Fill::FILL_GRADIENT_PATH
174
        ) {
175
            // Gradient fill
176 6
            $this->writeGradientFill($objWriter, $fill);
177 266
        } elseif ($fill->getFillType() !== null) {
178
            // Pattern fill
179 266
            $this->writePatternFill($objWriter, $fill);
180
        }
181
    }
182
183
    /**
184
     * Write Gradient Fill.
185
     */
186 6
    private function writeGradientFill(XMLWriter $objWriter, Fill $fill): void
187
    {
188
        // fill
189 6
        $objWriter->startElement('fill');
190
191
        // gradientFill
192 6
        $objWriter->startElement('gradientFill');
193 6
        $objWriter->writeAttribute('type', (string) $fill->getFillType());
194 6
        $objWriter->writeAttribute('degree', (string) $fill->getRotation());
195
196
        // stop
197 6
        $objWriter->startElement('stop');
198 6
        $objWriter->writeAttribute('position', '0');
199
200
        // color
201 6
        if ($fill->getStartColor()->getARGB() !== null) {
202 6
            $objWriter->startElement('color');
203 6
            $objWriter->writeAttribute('rgb', $fill->getStartColor()->getARGB());
204 6
            $objWriter->endElement();
205
        }
206
207 6
        $objWriter->endElement();
208
209
        // stop
210 6
        $objWriter->startElement('stop');
211 6
        $objWriter->writeAttribute('position', '1');
212
213
        // color
214 6
        if ($fill->getEndColor()->getARGB() !== null) {
215 6
            $objWriter->startElement('color');
216 6
            $objWriter->writeAttribute('rgb', $fill->getEndColor()->getARGB());
217 6
            $objWriter->endElement();
218
        }
219
220 6
        $objWriter->endElement();
221
222 6
        $objWriter->endElement();
223
224 6
        $objWriter->endElement();
225
    }
226
227 266
    private static function writePatternColors(Fill $fill): bool
228
    {
229 266
        if ($fill->getFillType() === Fill::FILL_NONE) {
230 266
            return false;
231
        }
232
233 266
        return $fill->getFillType() === Fill::FILL_SOLID || $fill->getColorsChanged();
234
    }
235
236
    /**
237
     * Write Pattern Fill.
238
     */
239 266
    private function writePatternFill(XMLWriter $objWriter, Fill $fill): void
240
    {
241
        // fill
242 266
        $objWriter->startElement('fill');
243
244
        // patternFill
245 266
        $objWriter->startElement('patternFill');
246 266
        $objWriter->writeAttribute('patternType', (string) $fill->getFillType());
247
248 266
        if (self::writePatternColors($fill)) {
249
            // fgColor
250 37
            if ($fill->getStartColor()->getARGB()) {
251 23
                if (!$fill->getEndColor()->getARGB() && $fill->getFillType() === Fill::FILL_SOLID) {
252 1
                    $objWriter->startElement('bgColor');
253 1
                    $objWriter->writeAttribute('rgb', $fill->getStartColor()->getARGB());
254
                } else {
255 23
                    $objWriter->startElement('fgColor');
256 23
                    $objWriter->writeAttribute('rgb', $fill->getStartColor()->getARGB());
257
                }
258 23
                $objWriter->endElement();
259
            }
260
            // bgColor
261 37
            if ($fill->getEndColor()->getARGB()) {
262 37
                $objWriter->startElement('bgColor');
263 37
                $objWriter->writeAttribute('rgb', $fill->getEndColor()->getARGB());
264 37
                $objWriter->endElement();
265
            }
266
        }
267
268 266
        $objWriter->endElement();
269
270 266
        $objWriter->endElement();
271
    }
272
273 266
    private function startFont(XMLWriter $objWriter, bool &$fontStarted): void
274
    {
275 266
        if (!$fontStarted) {
276 266
            $fontStarted = true;
277 266
            $objWriter->startElement('font');
278
        }
279
    }
280
281
    /**
282
     * Write Font.
283
     */
284 266
    private function writeFont(XMLWriter $objWriter, Font $font): void
285
    {
286 266
        $fontStarted = false;
287
        // font
288
        //    Weird! The order of these elements actually makes a difference when opening Xlsx
289
        //        files in Excel2003 with the compatibility pack. It's not documented behaviour,
290
        //        and makes for a real WTF!
291
292
        // Bold. We explicitly write this element also when false (like MS Office Excel 2007 does
293
        // for conditional formatting). Otherwise it will apparently not be picked up in conditional
294
        // formatting style dialog
295 266
        if ($font->getBold() !== null) {
296 266
            $this->startFont($objWriter, $fontStarted);
297 266
            $objWriter->startElement('b');
298 266
            $objWriter->writeAttribute('val', $font->getBold() ? '1' : '0');
299 266
            $objWriter->endElement();
300
        }
301
302
        // Italic
303 266
        if ($font->getItalic() !== null) {
304 266
            $this->startFont($objWriter, $fontStarted);
305 266
            $objWriter->startElement('i');
306 266
            $objWriter->writeAttribute('val', $font->getItalic() ? '1' : '0');
307 266
            $objWriter->endElement();
308
        }
309
310
        // Strikethrough
311 266
        if ($font->getStrikethrough() !== null) {
312 266
            $this->startFont($objWriter, $fontStarted);
313 266
            $objWriter->startElement('strike');
314 266
            $objWriter->writeAttribute('val', $font->getStrikethrough() ? '1' : '0');
315 266
            $objWriter->endElement();
316
        }
317
318
        // Underline
319 266
        if ($font->getUnderline() !== null) {
320 266
            $this->startFont($objWriter, $fontStarted);
321 266
            $objWriter->startElement('u');
322 266
            $objWriter->writeAttribute('val', $font->getUnderline());
323 266
            $objWriter->endElement();
324
        }
325
326
        // Superscript / subscript
327 266
        if ($font->getSuperscript() === true || $font->getSubscript() === true) {
328 2
            $this->startFont($objWriter, $fontStarted);
329 2
            $objWriter->startElement('vertAlign');
330 2
            if ($font->getSuperscript() === true) {
331 2
                $objWriter->writeAttribute('val', 'superscript');
332 2
            } elseif ($font->getSubscript() === true) {
333 2
                $objWriter->writeAttribute('val', 'subscript');
334
            }
335 2
            $objWriter->endElement();
336
        }
337
338
        // Size
339 266
        if ($font->getSize() !== null) {
340 266
            $this->startFont($objWriter, $fontStarted);
341 266
            $objWriter->startElement('sz');
342 266
            $objWriter->writeAttribute('val', StringHelper::formatNumber($font->getSize()));
343 266
            $objWriter->endElement();
344
        }
345
346
        // Foreground color
347 266
        if ($font->getColor()->getARGB() !== null) {
348 266
            $this->startFont($objWriter, $fontStarted);
349 266
            $objWriter->startElement('color');
350 266
            $objWriter->writeAttribute('rgb', $font->getColor()->getARGB());
351 266
            $objWriter->endElement();
352
        }
353
354
        // Name
355 266
        if ($font->getName() !== null) {
356 266
            $this->startFont($objWriter, $fontStarted);
357 266
            $objWriter->startElement('name');
358 266
            $objWriter->writeAttribute('val', $font->getName());
359 266
            $objWriter->endElement();
360
        }
361
362 266
        if ($fontStarted) {
363 266
            $objWriter->endElement();
364
        }
365
    }
366
367
    /**
368
     * Write Border.
369
     */
370 266
    private function writeBorder(XMLWriter $objWriter, Borders $borders): void
371
    {
372
        // Write border
373 266
        $objWriter->startElement('border');
374
        // Diagonal?
375 266
        switch ($borders->getDiagonalDirection()) {
376
            case Borders::DIAGONAL_UP:
377 2
                $objWriter->writeAttribute('diagonalUp', 'true');
378 2
                $objWriter->writeAttribute('diagonalDown', 'false');
379
380 2
                break;
381
            case Borders::DIAGONAL_DOWN:
382 2
                $objWriter->writeAttribute('diagonalUp', 'false');
383 2
                $objWriter->writeAttribute('diagonalDown', 'true');
384
385 2
                break;
386
            case Borders::DIAGONAL_BOTH:
387 3
                $objWriter->writeAttribute('diagonalUp', 'true');
388 3
                $objWriter->writeAttribute('diagonalDown', 'true');
389
390 3
                break;
391
        }
392
393
        // BorderPr
394 266
        $this->writeBorderPr($objWriter, 'left', $borders->getLeft());
395 266
        $this->writeBorderPr($objWriter, 'right', $borders->getRight());
396 266
        $this->writeBorderPr($objWriter, 'top', $borders->getTop());
397 266
        $this->writeBorderPr($objWriter, 'bottom', $borders->getBottom());
398 266
        $this->writeBorderPr($objWriter, 'diagonal', $borders->getDiagonal());
399 266
        $objWriter->endElement();
400
    }
401
402
    /** @var mixed */
403
    private static $scrutinizerFalse = false;
404
405
    /**
406
     * Write Cell Style Xf.
407
     */
408 266
    private function writeCellStyleXf(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Style\Style $style, Spreadsheet $spreadsheet, string $defaultAlignHash): void
409
    {
410
        // xf
411 266
        $objWriter->startElement('xf');
412 266
        $objWriter->writeAttribute('xfId', '0');
413 266
        $objWriter->writeAttribute('fontId', (string) (int) $this->getParentWriter()->getFontHashTable()->getIndexForHashCode($style->getFont()->getHashCode()));
414 266
        if ($style->getQuotePrefix()) {
415 2
            $objWriter->writeAttribute('quotePrefix', '1');
416
        }
417
418 266
        if ($style->getNumberFormat()->getBuiltInFormatCode() === self::$scrutinizerFalse) {
419 37
            $objWriter->writeAttribute('numFmtId', (string) (int) ($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($style->getNumberFormat()->getHashCode()) + 164));
420
        } else {
421 266
            $objWriter->writeAttribute('numFmtId', (string) (int) $style->getNumberFormat()->getBuiltInFormatCode());
422
        }
423
424 266
        $objWriter->writeAttribute('fillId', (string) (int) $this->getParentWriter()->getFillHashTable()->getIndexForHashCode($style->getFill()->getHashCode()));
425 266
        $objWriter->writeAttribute('borderId', (string) (int) $this->getParentWriter()->getBordersHashTable()->getIndexForHashCode($style->getBorders()->getHashCode()));
426
427
        // Apply styles?
428 266
        $objWriter->writeAttribute('applyFont', ($spreadsheet->getDefaultStyle()->getFont()->getHashCode() != $style->getFont()->getHashCode()) ? '1' : '0');
429 266
        $objWriter->writeAttribute('applyNumberFormat', ($spreadsheet->getDefaultStyle()->getNumberFormat()->getHashCode() != $style->getNumberFormat()->getHashCode()) ? '1' : '0');
430 266
        $objWriter->writeAttribute('applyFill', ($spreadsheet->getDefaultStyle()->getFill()->getHashCode() != $style->getFill()->getHashCode()) ? '1' : '0');
431 266
        $objWriter->writeAttribute('applyBorder', ($spreadsheet->getDefaultStyle()->getBorders()->getHashCode() != $style->getBorders()->getHashCode()) ? '1' : '0');
432 266
        if ($defaultAlignHash !== '' && $defaultAlignHash === $style->getAlignment()->getHashCode()) {
433 260
            $applyAlignment = '0';
434
        } else {
435 46
            $applyAlignment = '1';
436
        }
437 266
        $objWriter->writeAttribute('applyAlignment', $applyAlignment);
438 266
        if ($style->getProtection()->getLocked() != Protection::PROTECTION_INHERIT || $style->getProtection()->getHidden() != Protection::PROTECTION_INHERIT) {
439 21
            $objWriter->writeAttribute('applyProtection', 'true');
440
        }
441
442
        // alignment
443 266
        if ($applyAlignment === '1') {
444 46
            $objWriter->startElement('alignment');
445 46
            $vertical = Alignment::VERTICAL_ALIGNMENT_FOR_XLSX[$style->getAlignment()->getVertical()] ?? '';
446 46
            $horizontal = Alignment::HORIZONTAL_ALIGNMENT_FOR_XLSX[$style->getAlignment()->getHorizontal()] ?? '';
447 46
            if ($horizontal !== '') {
448 34
                $objWriter->writeAttribute('horizontal', $horizontal);
449
            }
450 46
            if ($vertical !== '') {
451 46
                $objWriter->writeAttribute('vertical', $vertical);
452
            }
453
454 46
            if ($style->getAlignment()->getTextRotation() >= 0) {
455 45
                $textRotation = $style->getAlignment()->getTextRotation();
456
            } else {
457 5
                $textRotation = 90 - $style->getAlignment()->getTextRotation();
458
            }
459 46
            $objWriter->writeAttribute('textRotation', (string) $textRotation);
460
461 46
            $objWriter->writeAttribute('wrapText', ($style->getAlignment()->getWrapText() ? 'true' : 'false'));
462 46
            $objWriter->writeAttribute('shrinkToFit', ($style->getAlignment()->getShrinkToFit() ? 'true' : 'false'));
463
464 46
            if ($style->getAlignment()->getIndent() > 0) {
465 1
                $objWriter->writeAttribute('indent', (string) $style->getAlignment()->getIndent());
466
            }
467 46
            if ($style->getAlignment()->getReadOrder() > 0) {
468
                $objWriter->writeAttribute('readingOrder', (string) $style->getAlignment()->getReadOrder());
469
            }
470 46
            $objWriter->endElement();
471
        }
472
473
        // protection
474 266
        if ($style->getProtection()->getLocked() != Protection::PROTECTION_INHERIT || $style->getProtection()->getHidden() != Protection::PROTECTION_INHERIT) {
475 21
            $objWriter->startElement('protection');
476 21
            if ($style->getProtection()->getLocked() != Protection::PROTECTION_INHERIT) {
477 15
                $objWriter->writeAttribute('locked', ($style->getProtection()->getLocked() == Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
478
            }
479 21
            if ($style->getProtection()->getHidden() != Protection::PROTECTION_INHERIT) {
480 11
                $objWriter->writeAttribute('hidden', ($style->getProtection()->getHidden() == Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
481
            }
482 21
            $objWriter->endElement();
483
        }
484
485 266
        $objWriter->endElement();
486
    }
487
488
    /**
489
     * Write Cell Style Dxf.
490
     */
491 23
    private function writeCellStyleDxf(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Style\Style $style): void
492
    {
493
        // dxf
494 23
        $objWriter->startElement('dxf');
495
496
        // font
497 23
        $this->writeFont($objWriter, $style->getFont());
498
499
        // numFmt
500 23
        $this->writeNumFmt($objWriter, $style->getNumberFormat());
501
502
        // fill
503 23
        $this->writeFill($objWriter, $style->getFill());
504
505
        // alignment
506 23
        $horizontal = Alignment::HORIZONTAL_ALIGNMENT_FOR_XLSX[$style->getAlignment()->getHorizontal()] ?? '';
507 23
        $vertical = Alignment::VERTICAL_ALIGNMENT_FOR_XLSX[$style->getAlignment()->getVertical()] ?? '';
508 23
        $rotation = $style->getAlignment()->getTextRotation();
509 23
        if ($horizontal || $vertical || $rotation !== null) {
510 1
            $objWriter->startElement('alignment');
511 1
            if ($horizontal) {
512
                $objWriter->writeAttribute('horizontal', $horizontal);
513
            }
514 1
            if ($vertical) {
515
                $objWriter->writeAttribute('vertical', $vertical);
516
            }
517
518 1
            if ($rotation !== null) {
519 1
                if ($rotation >= 0) {
520 1
                    $textRotation = $rotation;
521
                } else {
522
                    $textRotation = 90 - $rotation;
523
                }
524 1
                $objWriter->writeAttribute('textRotation', (string) $textRotation);
525
            }
526 1
            $objWriter->endElement();
527
        }
528
529
        // border
530 23
        $this->writeBorder($objWriter, $style->getBorders());
531
532
        // protection
533 23
        if ((!empty($style->getProtection()->getLocked())) || (!empty($style->getProtection()->getHidden()))) {
534
            if (
535
                $style->getProtection()->getLocked() !== Protection::PROTECTION_INHERIT ||
536
                $style->getProtection()->getHidden() !== Protection::PROTECTION_INHERIT
537
            ) {
538
                $objWriter->startElement('protection');
539
                if (
540
                    ($style->getProtection()->getLocked() !== null) &&
541
                    ($style->getProtection()->getLocked() !== Protection::PROTECTION_INHERIT)
542
                ) {
543
                    $objWriter->writeAttribute('locked', ($style->getProtection()->getLocked() == Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
544
                }
545
                if (
546
                    ($style->getProtection()->getHidden() !== null) &&
547
                    ($style->getProtection()->getHidden() !== Protection::PROTECTION_INHERIT)
548
                ) {
549
                    $objWriter->writeAttribute('hidden', ($style->getProtection()->getHidden() == Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
550
                }
551
                $objWriter->endElement();
552
            }
553
        }
554
555 23
        $objWriter->endElement();
556
    }
557
558
    /**
559
     * Write BorderPr.
560
     *
561
     * @param string $name Element name
562
     */
563 266
    private function writeBorderPr(XMLWriter $objWriter, $name, Border $border): void
564
    {
565
        // Write BorderPr
566 266
        if ($border->getBorderStyle() === Border::BORDER_OMIT) {
567 23
            return;
568
        }
569 266
        $objWriter->startElement($name);
570 266
        if ($border->getBorderStyle() !== Border::BORDER_NONE) {
571 24
            $objWriter->writeAttribute('style', $border->getBorderStyle());
572
573
            // color
574 24
            if ($border->getColor()->getARGB() !== null) {
575 24
                $objWriter->startElement('color');
576 24
                $objWriter->writeAttribute('rgb', $border->getColor()->getARGB());
577 24
                $objWriter->endElement();
578
            }
579
        }
580 266
        $objWriter->endElement();
581
    }
582
583
    /**
584
     * Write NumberFormat.
585
     *
586
     * @param int $id Number Format identifier
587
     */
588 57
    private function writeNumFmt(XMLWriter $objWriter, ?NumberFormat $numberFormat, $id = 0): void
589
    {
590
        // Translate formatcode
591 57
        $formatCode = ($numberFormat === null) ? null : $numberFormat->getFormatCode();
592
593
        // numFmt
594 57
        if ($formatCode !== null) {
595 39
            $objWriter->startElement('numFmt');
596 39
            $objWriter->writeAttribute('numFmtId', (string) ($id + 164));
597 39
            $objWriter->writeAttribute('formatCode', $formatCode);
598 39
            $objWriter->endElement();
599
        }
600
    }
601
602
    /**
603
     * Get an array of all styles.
604
     *
605
     * @return \PhpOffice\PhpSpreadsheet\Style\Style[] All styles in PhpSpreadsheet
606
     */
607 266
    public function allStyles(Spreadsheet $spreadsheet)
608
    {
609 266
        return $spreadsheet->getCellXfCollection();
610
    }
611
612
    /**
613
     * Get an array of all conditional styles.
614
     *
615
     * @return Conditional[] All conditional styles in PhpSpreadsheet
616
     */
617 266
    public function allConditionalStyles(Spreadsheet $spreadsheet)
618
    {
619
        // Get an array of all styles
620 266
        $aStyles = [];
621
622 266
        $sheetCount = $spreadsheet->getSheetCount();
623 266
        for ($i = 0; $i < $sheetCount; ++$i) {
624 266
            foreach ($spreadsheet->getSheet($i)->getConditionalStylesCollection() as $conditionalStyles) {
625 23
                foreach ($conditionalStyles as $conditionalStyle) {
626 23
                    $aStyles[] = $conditionalStyle;
627
                }
628
            }
629
        }
630
631 266
        return $aStyles;
632
    }
633
634
    /**
635
     * Get an array of all fills.
636
     *
637
     * @return Fill[] All fills in PhpSpreadsheet
638
     */
639 266
    public function allFills(Spreadsheet $spreadsheet)
640
    {
641
        // Get an array of unique fills
642 266
        $aFills = [];
643
644
        // Two first fills are predefined
645 266
        $fill0 = new Fill();
646 266
        $fill0->setFillType(Fill::FILL_NONE);
647 266
        $aFills[] = $fill0;
648
649 266
        $fill1 = new Fill();
650 266
        $fill1->setFillType(Fill::FILL_PATTERN_GRAY125);
651 266
        $aFills[] = $fill1;
652
        // The remaining fills
653 266
        $aStyles = $this->allStyles($spreadsheet);
654
        /** @var \PhpOffice\PhpSpreadsheet\Style\Style $style */
655 266
        foreach ($aStyles as $style) {
656 266
            if (!isset($aFills[$style->getFill()->getHashCode()])) {
657 266
                $aFills[$style->getFill()->getHashCode()] = $style->getFill();
658
            }
659
        }
660
661 266
        return $aFills;
662
    }
663
664
    /**
665
     * Get an array of all fonts.
666
     *
667
     * @return Font[] All fonts in PhpSpreadsheet
668
     */
669 266
    public function allFonts(Spreadsheet $spreadsheet)
670
    {
671
        // Get an array of unique fonts
672 266
        $aFonts = [];
673 266
        $aStyles = $this->allStyles($spreadsheet);
674
675
        /** @var \PhpOffice\PhpSpreadsheet\Style\Style $style */
676 266
        foreach ($aStyles as $style) {
677 266
            if (!isset($aFonts[$style->getFont()->getHashCode()])) {
678 266
                $aFonts[$style->getFont()->getHashCode()] = $style->getFont();
679
            }
680
        }
681
682 266
        return $aFonts;
683
    }
684
685
    /**
686
     * Get an array of all borders.
687
     *
688
     * @return Borders[] All borders in PhpSpreadsheet
689
     */
690 266
    public function allBorders(Spreadsheet $spreadsheet)
691
    {
692
        // Get an array of unique borders
693 266
        $aBorders = [];
694 266
        $aStyles = $this->allStyles($spreadsheet);
695
696
        /** @var \PhpOffice\PhpSpreadsheet\Style\Style $style */
697 266
        foreach ($aStyles as $style) {
698 266
            if (!isset($aBorders[$style->getBorders()->getHashCode()])) {
699 266
                $aBorders[$style->getBorders()->getHashCode()] = $style->getBorders();
700
            }
701
        }
702
703 266
        return $aBorders;
704
    }
705
706
    /**
707
     * Get an array of all number formats.
708
     *
709
     * @return NumberFormat[] All number formats in PhpSpreadsheet
710
     */
711 266
    public function allNumberFormats(Spreadsheet $spreadsheet)
712
    {
713
        // Get an array of unique number formats
714 266
        $aNumFmts = [];
715 266
        $aStyles = $this->allStyles($spreadsheet);
716
717
        /** @var \PhpOffice\PhpSpreadsheet\Style\Style $style */
718 266
        foreach ($aStyles as $style) {
719 266
            if ($style->getNumberFormat()->getBuiltInFormatCode() === false && !isset($aNumFmts[$style->getNumberFormat()->getHashCode()])) {
720 37
                $aNumFmts[$style->getNumberFormat()->getHashCode()] = $style->getNumberFormat();
721
            }
722
        }
723
724 266
        return $aNumFmts;
725
    }
726
}
727