Passed
Push — master ( 955217...cf30c2 )
by Adrien
27:35 queued 19:31
created

Worksheet::writeSheetData()   F

Complexity

Conditions 16
Paths 782

Size

Total Lines 76
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 16.4163

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 16
eloc 33
c 2
b 0
f 0
nc 782
nop 3
dl 0
loc 76
ccs 30
cts 34
cp 0.8824
crap 16.4163
rs 1.7027

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx;
4
5
use PhpOffice\PhpSpreadsheet\Cell\Cell;
6
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
7
use PhpOffice\PhpSpreadsheet\RichText\RichText;
8
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
9
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
10
use PhpOffice\PhpSpreadsheet\Style\Conditional;
11
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
12
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
13
use PhpOffice\PhpSpreadsheet\Worksheet\SheetView;
14
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet as PhpspreadsheetWorksheet;
15
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
16
17
/**
18
 * @category   PhpSpreadsheet
19
 *
20
 * @copyright  Copyright (c) 2006 - 2015 PhpSpreadsheet (https://github.com/PHPOffice/PhpSpreadsheet)
21
 */
22
class Worksheet extends WriterPart
23
{
24
    /**
25
     * Write worksheet to XML format.
26
     *
27
     * @param PhpspreadsheetWorksheet $pSheet
28
     * @param string[] $pStringTable
29
     * @param bool $includeCharts Flag indicating if we should write charts
30
     *
31
     * @throws WriterException
32
     *
33
     * @return string XML Output
34
     */
35 100
    public function writeWorksheet(PhpspreadsheetWorksheet $pSheet, $pStringTable = null, $includeCharts = false)
36
    {
37
        // Create XML writer
38 100
        $objWriter = null;
39 100
        if ($this->getParentWriter()->getUseDiskCaching()) {
40
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
41
        } else {
42 100
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
43
        }
44
45
        // XML header
46 100
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
47
48
        // Worksheet
49 100
        $objWriter->startElement('worksheet');
50 100
        $objWriter->writeAttribute('xml:space', 'preserve');
51 100
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
52 100
        $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
53
54 100
        $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing');
55 100
        $objWriter->writeAttribute('xmlns:x14', 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/main');
56 100
        $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006');
57 100
        $objWriter->writeAttribute('mc:Ignorable', 'x14ac');
58 100
        $objWriter->writeAttribute('xmlns:x14ac', 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac');
59
60
        // sheetPr
61 100
        $this->writeSheetPr($objWriter, $pSheet);
62
63
        // Dimension
64 100
        $this->writeDimension($objWriter, $pSheet);
65
66
        // sheetViews
67 100
        $this->writeSheetViews($objWriter, $pSheet);
68
69
        // sheetFormatPr
70 100
        $this->writeSheetFormatPr($objWriter, $pSheet);
71
72
        // cols
73 100
        $this->writeCols($objWriter, $pSheet);
74
75
        // sheetData
76 100
        $this->writeSheetData($objWriter, $pSheet, $pStringTable);
1 ignored issue
show
Bug introduced by
It seems like $pStringTable can also be of type null; however, parameter $pStringTable of PhpOffice\PhpSpreadsheet...sheet::writeSheetData() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

76
        $this->writeSheetData($objWriter, $pSheet, /** @scrutinizer ignore-type */ $pStringTable);
Loading history...
77
78
        // sheetProtection
79 100
        $this->writeSheetProtection($objWriter, $pSheet);
80
81
        // protectedRanges
82 100
        $this->writeProtectedRanges($objWriter, $pSheet);
83
84
        // autoFilter
85 100
        $this->writeAutoFilter($objWriter, $pSheet);
86
87
        // mergeCells
88 100
        $this->writeMergeCells($objWriter, $pSheet);
89
90
        // conditionalFormatting
91 100
        $this->writeConditionalFormatting($objWriter, $pSheet);
92
93
        // dataValidations
94 100
        $this->writeDataValidations($objWriter, $pSheet);
95
96
        // hyperlinks
97 100
        $this->writeHyperlinks($objWriter, $pSheet);
98
99
        // Print options
100 100
        $this->writePrintOptions($objWriter, $pSheet);
101
102
        // Page margins
103 100
        $this->writePageMargins($objWriter, $pSheet);
104
105
        // Page setup
106 100
        $this->writePageSetup($objWriter, $pSheet);
107
108
        // Header / footer
109 100
        $this->writeHeaderFooter($objWriter, $pSheet);
110
111
        // Breaks
112 100
        $this->writeBreaks($objWriter, $pSheet);
113
114
        // Drawings and/or Charts
115 100
        $this->writeDrawings($objWriter, $pSheet, $includeCharts);
116
117
        // LegacyDrawing
118 100
        $this->writeLegacyDrawing($objWriter, $pSheet);
119
120
        // LegacyDrawingHF
121 100
        $this->writeLegacyDrawingHF($objWriter, $pSheet);
122
123
        // AlternateContent
124 100
        $this->writeAlternateContent($objWriter, $pSheet);
125
126 100
        $objWriter->endElement();
127
128
        // Return
129 100
        return $objWriter->getData();
130
    }
131
132
    /**
133
     * Write SheetPr.
134
     *
135
     * @param XMLWriter $objWriter XML Writer
136
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
137
     */
138 100
    private function writeSheetPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
139
    {
140
        // sheetPr
141 100
        $objWriter->startElement('sheetPr');
142 100
        if ($pSheet->getParent()->hasMacros()) {
143
            //if the workbook have macros, we need to have codeName for the sheet
144 1
            if (!$pSheet->hasCodeName()) {
145
                $pSheet->setCodeName($pSheet->getTitle());
146
            }
147 1
            $objWriter->writeAttribute('codeName', $pSheet->getCodeName());
148
        }
149 100
        $autoFilterRange = $pSheet->getAutoFilter()->getRange();
150 100
        if (!empty($autoFilterRange)) {
151 3
            $objWriter->writeAttribute('filterMode', 1);
152 3
            $pSheet->getAutoFilter()->showHideRows();
153
        }
154
155
        // tabColor
156 100
        if ($pSheet->isTabColorSet()) {
157 6
            $objWriter->startElement('tabColor');
158 6
            $objWriter->writeAttribute('rgb', $pSheet->getTabColor()->getARGB());
159 6
            $objWriter->endElement();
160
        }
161
162
        // outlinePr
163 100
        $objWriter->startElement('outlinePr');
164 100
        $objWriter->writeAttribute('summaryBelow', ($pSheet->getShowSummaryBelow() ? '1' : '0'));
165 100
        $objWriter->writeAttribute('summaryRight', ($pSheet->getShowSummaryRight() ? '1' : '0'));
166 100
        $objWriter->endElement();
167
168
        // pageSetUpPr
169 100
        if ($pSheet->getPageSetup()->getFitToPage()) {
170
            $objWriter->startElement('pageSetUpPr');
171
            $objWriter->writeAttribute('fitToPage', '1');
172
            $objWriter->endElement();
173
        }
174
175 100
        $objWriter->endElement();
176 100
    }
177
178
    /**
179
     * Write Dimension.
180
     *
181
     * @param XMLWriter $objWriter XML Writer
182
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
183
     */
184 100
    private function writeDimension(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
185
    {
186
        // dimension
187 100
        $objWriter->startElement('dimension');
188 100
        $objWriter->writeAttribute('ref', $pSheet->calculateWorksheetDimension());
189 100
        $objWriter->endElement();
190 100
    }
191
192
    /**
193
     * Write SheetViews.
194
     *
195
     * @param XMLWriter $objWriter XML Writer
196
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
197
     *
198
     * @throws WriterException
199
     */
200 100
    private function writeSheetViews(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
201
    {
202
        // sheetViews
203 100
        $objWriter->startElement('sheetViews');
204
205
        // Sheet selected?
206 100
        $sheetSelected = false;
207 100
        if ($this->getParentWriter()->getSpreadsheet()->getIndex($pSheet) == $this->getParentWriter()->getSpreadsheet()->getActiveSheetIndex()) {
208 100
            $sheetSelected = true;
209
        }
210
211
        // sheetView
212 100
        $objWriter->startElement('sheetView');
213 100
        $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0');
214 100
        $objWriter->writeAttribute('workbookViewId', '0');
215
216
        // Zoom scales
217 100
        if ($pSheet->getSheetView()->getZoomScale() != 100) {
218
            $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale());
219
        }
220 100
        if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) {
221
            $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal());
222
        }
223
224
        // Show zeros (Excel also writes this attribute only if set to false)
225 100
        if ($pSheet->getSheetView()->getShowZeros() === false) {
226
            $objWriter->writeAttribute('showZeros', 0);
227
        }
228
229
        // View Layout Type
230 100
        if ($pSheet->getSheetView()->getView() !== SheetView::SHEETVIEW_NORMAL) {
231 1
            $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView());
232
        }
233
234
        // Gridlines
235 100
        if ($pSheet->getShowGridlines()) {
236 100
            $objWriter->writeAttribute('showGridLines', 'true');
237
        } else {
238
            $objWriter->writeAttribute('showGridLines', 'false');
239
        }
240
241
        // Row and column headers
242 100
        if ($pSheet->getShowRowColHeaders()) {
243 100
            $objWriter->writeAttribute('showRowColHeaders', '1');
244
        } else {
245
            $objWriter->writeAttribute('showRowColHeaders', '0');
246
        }
247
248
        // Right-to-left
249 100
        if ($pSheet->getRightToLeft()) {
250
            $objWriter->writeAttribute('rightToLeft', 'true');
251
        }
252
253 100
        $activeCell = $pSheet->getActiveCell();
254 100
        $sqref = $pSheet->getSelectedCells();
255
256
        // Pane
257 100
        $pane = '';
258 100
        if ($pSheet->getFreezePane()) {
259 5
            [$xSplit, $ySplit] = Coordinate::coordinateFromString($pSheet->getFreezePane());
260 5
            $xSplit = Coordinate::columnIndexFromString($xSplit);
261 5
            --$xSplit;
262 5
            --$ySplit;
263
264 5
            $topLeftCell = $pSheet->getTopLeftCell();
265 5
            $activeCell = $topLeftCell;
266 5
            $sqref = $topLeftCell;
267
268
            // pane
269 5
            $pane = 'topRight';
270 5
            $objWriter->startElement('pane');
271 5
            if ($xSplit > 0) {
272 1
                $objWriter->writeAttribute('xSplit', $xSplit);
273
            }
274 5
            if ($ySplit > 0) {
275 5
                $objWriter->writeAttribute('ySplit', $ySplit);
276 5
                $pane = ($xSplit > 0) ? 'bottomRight' : 'bottomLeft';
277
            }
278 5
            $objWriter->writeAttribute('topLeftCell', $topLeftCell);
279 5
            $objWriter->writeAttribute('activePane', $pane);
280 5
            $objWriter->writeAttribute('state', 'frozen');
281 5
            $objWriter->endElement();
282
283 5
            if (($xSplit > 0) && ($ySplit > 0)) {
284
                //    Write additional selections if more than two panes (ie both an X and a Y split)
285 1
                $objWriter->startElement('selection');
286 1
                $objWriter->writeAttribute('pane', 'topRight');
287 1
                $objWriter->endElement();
288 1
                $objWriter->startElement('selection');
289 1
                $objWriter->writeAttribute('pane', 'bottomLeft');
290 1
                $objWriter->endElement();
291
            }
292
        }
293
294
        // Selection
295
        // Only need to write selection element if we have a split pane
296
        // We cheat a little by over-riding the active cell selection, setting it to the split cell
297 100
        $objWriter->startElement('selection');
298 100
        if ($pane != '') {
299 5
            $objWriter->writeAttribute('pane', $pane);
300
        }
301 100
        $objWriter->writeAttribute('activeCell', $activeCell);
302 100
        $objWriter->writeAttribute('sqref', $sqref);
303 100
        $objWriter->endElement();
304
305 100
        $objWriter->endElement();
306
307 100
        $objWriter->endElement();
308 100
    }
309
310
    /**
311
     * Write SheetFormatPr.
312
     *
313
     * @param XMLWriter $objWriter XML Writer
314
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
315
     */
316 100
    private function writeSheetFormatPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
317
    {
318
        // sheetFormatPr
319 100
        $objWriter->startElement('sheetFormatPr');
320
321
        // Default row height
322 100
        if ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) {
323 3
            $objWriter->writeAttribute('customHeight', 'true');
324 3
            $objWriter->writeAttribute('defaultRowHeight', StringHelper::formatNumber($pSheet->getDefaultRowDimension()->getRowHeight()));
325
        } else {
326 97
            $objWriter->writeAttribute('defaultRowHeight', '14.4');
327
        }
328
329
        // Set Zero Height row
330 100
        if ((string) $pSheet->getDefaultRowDimension()->getZeroHeight() === '1' ||
331 100
            strtolower((string) $pSheet->getDefaultRowDimension()->getZeroHeight()) == 'true') {
332
            $objWriter->writeAttribute('zeroHeight', '1');
333
        }
334
335
        // Default column width
336 100
        if ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) {
337 2
            $objWriter->writeAttribute('defaultColWidth', StringHelper::formatNumber($pSheet->getDefaultColumnDimension()->getWidth()));
338
        }
339
340
        // Outline level - row
341 100
        $outlineLevelRow = 0;
342 100
        foreach ($pSheet->getRowDimensions() as $dimension) {
343 13
            if ($dimension->getOutlineLevel() > $outlineLevelRow) {
344
                $outlineLevelRow = $dimension->getOutlineLevel();
345
            }
346
        }
347 100
        $objWriter->writeAttribute('outlineLevelRow', (int) $outlineLevelRow);
348
349
        // Outline level - column
350 100
        $outlineLevelCol = 0;
351 100
        foreach ($pSheet->getColumnDimensions() as $dimension) {
352 23
            if ($dimension->getOutlineLevel() > $outlineLevelCol) {
353 1
                $outlineLevelCol = $dimension->getOutlineLevel();
354
            }
355
        }
356 100
        $objWriter->writeAttribute('outlineLevelCol', (int) $outlineLevelCol);
357
358 100
        $objWriter->endElement();
359 100
    }
360
361
    /**
362
     * Write Cols.
363
     *
364
     * @param XMLWriter $objWriter XML Writer
365
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
366
     */
367 100
    private function writeCols(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
368
    {
369
        // cols
370 100
        if (count($pSheet->getColumnDimensions()) > 0) {
371 23
            $objWriter->startElement('cols');
372
373 23
            $pSheet->calculateColumnWidths();
374
375
            // Loop through column dimensions
376 23
            foreach ($pSheet->getColumnDimensions() as $colDimension) {
377
                // col
378 23
                $objWriter->startElement('col');
379 23
                $objWriter->writeAttribute('min', Coordinate::columnIndexFromString($colDimension->getColumnIndex()));
380 23
                $objWriter->writeAttribute('max', Coordinate::columnIndexFromString($colDimension->getColumnIndex()));
381
382 23
                if ($colDimension->getWidth() < 0) {
383
                    // No width set, apply default of 10
384 2
                    $objWriter->writeAttribute('width', '9.10');
385
                } else {
386
                    // Width set
387 23
                    $objWriter->writeAttribute('width', StringHelper::formatNumber($colDimension->getWidth()));
388
                }
389
390
                // Column visibility
391 23
                if ($colDimension->getVisible() === false) {
392 3
                    $objWriter->writeAttribute('hidden', 'true');
393
                }
394
395
                // Auto size?
396 23
                if ($colDimension->getAutoSize()) {
397 8
                    $objWriter->writeAttribute('bestFit', 'true');
398
                }
399
400
                // Custom width?
401 23
                if ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) {
402 23
                    $objWriter->writeAttribute('customWidth', 'true');
403
                }
404
405
                // Collapsed
406 23
                if ($colDimension->getCollapsed() === true) {
407 1
                    $objWriter->writeAttribute('collapsed', 'true');
408
                }
409
410
                // Outline level
411 23
                if ($colDimension->getOutlineLevel() > 0) {
412 1
                    $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel());
413
                }
414
415
                // Style
416 23
                $objWriter->writeAttribute('style', $colDimension->getXfIndex());
417
418 23
                $objWriter->endElement();
419
            }
420
421 23
            $objWriter->endElement();
422
        }
423 100
    }
424
425
    /**
426
     * Write SheetProtection.
427
     *
428
     * @param XMLWriter $objWriter XML Writer
429
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
430
     */
431 100
    private function writeSheetProtection(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
432
    {
433
        // sheetProtection
434 100
        $objWriter->startElement('sheetProtection');
435
436 100
        if ($pSheet->getProtection()->getPassword() !== '') {
437 2
            $objWriter->writeAttribute('password', $pSheet->getProtection()->getPassword());
438
        }
439
440 100
        $objWriter->writeAttribute('sheet', ($pSheet->getProtection()->getSheet() ? 'true' : 'false'));
441 100
        $objWriter->writeAttribute('objects', ($pSheet->getProtection()->getObjects() ? 'true' : 'false'));
442 100
        $objWriter->writeAttribute('scenarios', ($pSheet->getProtection()->getScenarios() ? 'true' : 'false'));
443 100
        $objWriter->writeAttribute('formatCells', ($pSheet->getProtection()->getFormatCells() ? 'true' : 'false'));
444 100
        $objWriter->writeAttribute('formatColumns', ($pSheet->getProtection()->getFormatColumns() ? 'true' : 'false'));
445 100
        $objWriter->writeAttribute('formatRows', ($pSheet->getProtection()->getFormatRows() ? 'true' : 'false'));
446 100
        $objWriter->writeAttribute('insertColumns', ($pSheet->getProtection()->getInsertColumns() ? 'true' : 'false'));
447 100
        $objWriter->writeAttribute('insertRows', ($pSheet->getProtection()->getInsertRows() ? 'true' : 'false'));
448 100
        $objWriter->writeAttribute('insertHyperlinks', ($pSheet->getProtection()->getInsertHyperlinks() ? 'true' : 'false'));
449 100
        $objWriter->writeAttribute('deleteColumns', ($pSheet->getProtection()->getDeleteColumns() ? 'true' : 'false'));
450 100
        $objWriter->writeAttribute('deleteRows', ($pSheet->getProtection()->getDeleteRows() ? 'true' : 'false'));
451 100
        $objWriter->writeAttribute('selectLockedCells', ($pSheet->getProtection()->getSelectLockedCells() ? 'true' : 'false'));
452 100
        $objWriter->writeAttribute('sort', ($pSheet->getProtection()->getSort() ? 'true' : 'false'));
453 100
        $objWriter->writeAttribute('autoFilter', ($pSheet->getProtection()->getAutoFilter() ? 'true' : 'false'));
454 100
        $objWriter->writeAttribute('pivotTables', ($pSheet->getProtection()->getPivotTables() ? 'true' : 'false'));
455 100
        $objWriter->writeAttribute('selectUnlockedCells', ($pSheet->getProtection()->getSelectUnlockedCells() ? 'true' : 'false'));
456 100
        $objWriter->endElement();
457 100
    }
458
459
    /**
460
     * Write ConditionalFormatting.
461
     *
462
     * @param XMLWriter $objWriter XML Writer
463
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
464
     *
465
     * @throws WriterException
466
     */
467 100
    private function writeConditionalFormatting(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
468
    {
469
        // Conditional id
470 100
        $id = 1;
471
472
        // Loop through styles in the current worksheet
473 100
        foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) {
474 3
            foreach ($conditionalStyles as $conditional) {
475
                // WHY was this again?
476
                // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()) == '') {
477
                //    continue;
478
                // }
479 3
                if ($conditional->getConditionType() != Conditional::CONDITION_NONE) {
480
                    // conditionalFormatting
481 3
                    $objWriter->startElement('conditionalFormatting');
482 3
                    $objWriter->writeAttribute('sqref', $cellCoordinate);
483
484
                    // cfRule
485 3
                    $objWriter->startElement('cfRule');
486 3
                    $objWriter->writeAttribute('type', $conditional->getConditionType());
487 3
                    $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()));
488 3
                    $objWriter->writeAttribute('priority', $id++);
489
490 3
                    if (($conditional->getConditionType() == Conditional::CONDITION_CELLIS || $conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT)
491 3
                        && $conditional->getOperatorType() != Conditional::OPERATOR_NONE) {
492 3
                        $objWriter->writeAttribute('operator', $conditional->getOperatorType());
493
                    }
494
495 3
                    if ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
496 3
                        && $conditional->getText() !== null) {
497
                        $objWriter->writeAttribute('text', $conditional->getText());
498
                    }
499
500 3
                    if ($conditional->getStopIfTrue()) {
501 1
                        $objWriter->writeAttribute('stopIfTrue', '1');
502
                    }
503
504 3
                    if ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
505 3
                        && $conditional->getOperatorType() == Conditional::OPERATOR_CONTAINSTEXT
506 3
                        && $conditional->getText() !== null) {
507
                        $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))');
508 3
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
509 3
                        && $conditional->getOperatorType() == Conditional::OPERATOR_BEGINSWITH
510 3
                        && $conditional->getText() !== null) {
511
                        $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"');
512 3
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
513 3
                        && $conditional->getOperatorType() == Conditional::OPERATOR_ENDSWITH
514 3
                        && $conditional->getText() !== null) {
515
                        $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"');
516 3
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
517 3
                        && $conditional->getOperatorType() == Conditional::OPERATOR_NOTCONTAINS
518 3
                        && $conditional->getText() !== null) {
519
                        $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))');
520 3
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CELLIS
521 1
                        || $conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
522 3
                        || $conditional->getConditionType() == Conditional::CONDITION_EXPRESSION) {
523 3
                        foreach ($conditional->getConditions() as $formula) {
524
                            // Formula
525 3
                            $objWriter->writeElement('formula', $formula);
526
                        }
527
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSBLANKS) {
528
                        // formula copied from ms xlsx xml source file
529
                        $objWriter->writeElement('formula', 'LEN(TRIM(' . $cellCoordinate . '))=0');
530
                    }
531
532 3
                    $objWriter->endElement();
533
534 3
                    $objWriter->endElement();
535
                }
536
            }
537
        }
538 100
    }
539
540
    /**
541
     * Write DataValidations.
542
     *
543
     * @param XMLWriter $objWriter XML Writer
544
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
545
     */
546 100
    private function writeDataValidations(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
547
    {
548
        // Datavalidation collection
549 100
        $dataValidationCollection = $pSheet->getDataValidationCollection();
550
551
        // Write data validations?
552 100
        if (!empty($dataValidationCollection)) {
553 2
            $dataValidationCollection = Coordinate::mergeRangesInCollection($dataValidationCollection);
554 2
            $objWriter->startElement('dataValidations');
555 2
            $objWriter->writeAttribute('count', count($dataValidationCollection));
556
557 2
            foreach ($dataValidationCollection as $coordinate => $dv) {
558 2
                $objWriter->startElement('dataValidation');
559
560 2
                if ($dv->getType() != '') {
561 2
                    $objWriter->writeAttribute('type', $dv->getType());
562
                }
563
564 2
                if ($dv->getErrorStyle() != '') {
565 2
                    $objWriter->writeAttribute('errorStyle', $dv->getErrorStyle());
566
                }
567
568 2
                if ($dv->getOperator() != '') {
569 2
                    $objWriter->writeAttribute('operator', $dv->getOperator());
570
                }
571
572 2
                $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0'));
573 2
                $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0'));
574 2
                $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0'));
575 2
                $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0'));
576
577 2
                if ($dv->getErrorTitle() !== '') {
578 2
                    $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle());
579
                }
580 2
                if ($dv->getError() !== '') {
581 2
                    $objWriter->writeAttribute('error', $dv->getError());
582
                }
583 2
                if ($dv->getPromptTitle() !== '') {
584 2
                    $objWriter->writeAttribute('promptTitle', $dv->getPromptTitle());
585
                }
586 2
                if ($dv->getPrompt() !== '') {
587 2
                    $objWriter->writeAttribute('prompt', $dv->getPrompt());
588
                }
589
590 2
                $objWriter->writeAttribute('sqref', $coordinate);
591
592 2
                if ($dv->getFormula1() !== '') {
593 2
                    $objWriter->writeElement('formula1', $dv->getFormula1());
594
                }
595 2
                if ($dv->getFormula2() !== '') {
596 1
                    $objWriter->writeElement('formula2', $dv->getFormula2());
597
                }
598
599 2
                $objWriter->endElement();
600
            }
601
602 2
            $objWriter->endElement();
603
        }
604 100
    }
605
606
    /**
607
     * Write Hyperlinks.
608
     *
609
     * @param XMLWriter $objWriter XML Writer
610
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
611
     */
612 100
    private function writeHyperlinks(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
613
    {
614
        // Hyperlink collection
615 100
        $hyperlinkCollection = $pSheet->getHyperlinkCollection();
616
617
        // Relation ID
618 100
        $relationId = 1;
619
620
        // Write hyperlinks?
621 100
        if (!empty($hyperlinkCollection)) {
622 10
            $objWriter->startElement('hyperlinks');
623
624 10
            foreach ($hyperlinkCollection as $coordinate => $hyperlink) {
625 10
                $objWriter->startElement('hyperlink');
626
627 10
                $objWriter->writeAttribute('ref', $coordinate);
628 10
                if (!$hyperlink->isInternal()) {
629 10
                    $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId);
630 10
                    ++$relationId;
631
                } else {
632 7
                    $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl()));
633
                }
634
635 10
                if ($hyperlink->getTooltip() !== '') {
636 6
                    $objWriter->writeAttribute('tooltip', $hyperlink->getTooltip());
637 6
                    $objWriter->writeAttribute('display', $hyperlink->getTooltip());
638
                }
639
640 10
                $objWriter->endElement();
641
            }
642
643 10
            $objWriter->endElement();
644
        }
645 100
    }
646
647
    /**
648
     * Write ProtectedRanges.
649
     *
650
     * @param XMLWriter $objWriter XML Writer
651
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
652
     */
653 100
    private function writeProtectedRanges(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
654
    {
655 100
        if (count($pSheet->getProtectedCells()) > 0) {
656
            // protectedRanges
657 6
            $objWriter->startElement('protectedRanges');
658
659
            // Loop protectedRanges
660 6
            foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) {
661
                // protectedRange
662 6
                $objWriter->startElement('protectedRange');
663 6
                $objWriter->writeAttribute('name', 'p' . md5($protectedCell));
664 6
                $objWriter->writeAttribute('sqref', $protectedCell);
665 6
                if (!empty($passwordHash)) {
666 6
                    $objWriter->writeAttribute('password', $passwordHash);
0 ignored issues
show
Bug introduced by
$passwordHash of type array is incompatible with the type string expected by parameter $value of XMLWriter::writeAttribute(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

666
                    $objWriter->writeAttribute('password', /** @scrutinizer ignore-type */ $passwordHash);
Loading history...
667
                }
668 6
                $objWriter->endElement();
669
            }
670
671 6
            $objWriter->endElement();
672
        }
673 100
    }
674
675
    /**
676
     * Write MergeCells.
677
     *
678
     * @param XMLWriter $objWriter XML Writer
679
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
680
     */
681 100
    private function writeMergeCells(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
682
    {
683 100
        if (count($pSheet->getMergeCells()) > 0) {
684
            // mergeCells
685 13
            $objWriter->startElement('mergeCells');
686
687
            // Loop mergeCells
688 13
            foreach ($pSheet->getMergeCells() as $mergeCell) {
689
                // mergeCell
690 13
                $objWriter->startElement('mergeCell');
691 13
                $objWriter->writeAttribute('ref', $mergeCell);
0 ignored issues
show
Bug introduced by
$mergeCell of type array is incompatible with the type string expected by parameter $value of XMLWriter::writeAttribute(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

691
                $objWriter->writeAttribute('ref', /** @scrutinizer ignore-type */ $mergeCell);
Loading history...
692 13
                $objWriter->endElement();
693
            }
694
695 13
            $objWriter->endElement();
696
        }
697 100
    }
698
699
    /**
700
     * Write PrintOptions.
701
     *
702
     * @param XMLWriter $objWriter XML Writer
703
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
704
     */
705 100
    private function writePrintOptions(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
706
    {
707
        // printOptions
708 100
        $objWriter->startElement('printOptions');
709
710 100
        $objWriter->writeAttribute('gridLines', ($pSheet->getPrintGridlines() ? 'true' : 'false'));
711 100
        $objWriter->writeAttribute('gridLinesSet', 'true');
712
713 100
        if ($pSheet->getPageSetup()->getHorizontalCentered()) {
714
            $objWriter->writeAttribute('horizontalCentered', 'true');
715
        }
716
717 100
        if ($pSheet->getPageSetup()->getVerticalCentered()) {
718
            $objWriter->writeAttribute('verticalCentered', 'true');
719
        }
720
721 100
        $objWriter->endElement();
722 100
    }
723
724
    /**
725
     * Write PageMargins.
726
     *
727
     * @param XMLWriter $objWriter XML Writer
728
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
729
     */
730 100
    private function writePageMargins(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
731
    {
732
        // pageMargins
733 100
        $objWriter->startElement('pageMargins');
734 100
        $objWriter->writeAttribute('left', StringHelper::formatNumber($pSheet->getPageMargins()->getLeft()));
735 100
        $objWriter->writeAttribute('right', StringHelper::formatNumber($pSheet->getPageMargins()->getRight()));
736 100
        $objWriter->writeAttribute('top', StringHelper::formatNumber($pSheet->getPageMargins()->getTop()));
737 100
        $objWriter->writeAttribute('bottom', StringHelper::formatNumber($pSheet->getPageMargins()->getBottom()));
738 100
        $objWriter->writeAttribute('header', StringHelper::formatNumber($pSheet->getPageMargins()->getHeader()));
739 100
        $objWriter->writeAttribute('footer', StringHelper::formatNumber($pSheet->getPageMargins()->getFooter()));
740 100
        $objWriter->endElement();
741 100
    }
742
743
    /**
744
     * Write AutoFilter.
745
     *
746
     * @param XMLWriter $objWriter XML Writer
747
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
748
     */
749 100
    private function writeAutoFilter(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
750
    {
751 100
        $autoFilterRange = $pSheet->getAutoFilter()->getRange();
752 100
        if (!empty($autoFilterRange)) {
753
            // autoFilter
754 3
            $objWriter->startElement('autoFilter');
755
756
            // Strip any worksheet reference from the filter coordinates
757 3
            $range = Coordinate::splitRange($autoFilterRange);
758 3
            $range = $range[0];
759
            //    Strip any worksheet ref
760 3
            [$ws, $range[0]] = PhpspreadsheetWorksheet::extractSheetTitle($range[0], true);
761 3
            $range = implode(':', $range);
762
763 3
            $objWriter->writeAttribute('ref', str_replace('$', '', $range));
764
765 3
            $columns = $pSheet->getAutoFilter()->getColumns();
766 3
            if (count($columns) > 0) {
767 2
                foreach ($columns as $columnID => $column) {
768 2
                    $rules = $column->getRules();
769 2
                    if (count($rules) > 0) {
770 2
                        $objWriter->startElement('filterColumn');
771 2
                        $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID));
772
773 2
                        $objWriter->startElement($column->getFilterType());
774 2
                        if ($column->getJoin() == Column::AUTOFILTER_COLUMN_JOIN_AND) {
775 1
                            $objWriter->writeAttribute('and', 1);
776
                        }
777
778 2
                        foreach ($rules as $rule) {
779 2
                            if (($column->getFilterType() === Column::AUTOFILTER_FILTERTYPE_FILTER) &&
780 2
                                ($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_EQUAL) &&
781 2
                                ($rule->getValue() === '')) {
782
                                //    Filter rule for Blanks
783 1
                                $objWriter->writeAttribute('blank', 1);
784 2
                            } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) {
785
                                //    Dynamic Filter Rule
786 1
                                $objWriter->writeAttribute('type', $rule->getGrouping());
787 1
                                $val = $column->getAttribute('val');
788 1
                                if ($val !== null) {
789 1
                                    $objWriter->writeAttribute('val', $val);
790
                                }
791 1
                                $maxVal = $column->getAttribute('maxVal');
792 1
                                if ($maxVal !== null) {
793 1
                                    $objWriter->writeAttribute('maxVal', $maxVal);
794
                                }
795 2
                            } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) {
796
                                //    Top 10 Filter Rule
797
                                $objWriter->writeAttribute('val', $rule->getValue());
798
                                $objWriter->writeAttribute('percent', (($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0'));
799
                                $objWriter->writeAttribute('top', (($rule->getGrouping() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1' : '0'));
800
                            } else {
801
                                //    Filter, DateGroupItem or CustomFilter
802 2
                                $objWriter->startElement($rule->getRuleType());
803
804 2
                                if ($rule->getOperator() !== Rule::AUTOFILTER_COLUMN_RULE_EQUAL) {
805 1
                                    $objWriter->writeAttribute('operator', $rule->getOperator());
806
                                }
807 2
                                if ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DATEGROUP) {
808
                                    // Date Group filters
809 1
                                    foreach ($rule->getValue() as $key => $value) {
0 ignored issues
show
Bug introduced by
The expression $rule->getValue() of type string is not traversable.
Loading history...
810 1
                                        if ($value > '') {
811 1
                                            $objWriter->writeAttribute($key, $value);
812
                                        }
813
                                    }
814 1
                                    $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping());
815
                                } else {
816 2
                                    $objWriter->writeAttribute('val', $rule->getValue());
817
                                }
818
819 2
                                $objWriter->endElement();
820
                            }
821
                        }
822
823 2
                        $objWriter->endElement();
824
825 2
                        $objWriter->endElement();
826
                    }
827
                }
828
            }
829 3
            $objWriter->endElement();
830
        }
831 100
    }
832
833
    /**
834
     * Write PageSetup.
835
     *
836
     * @param XMLWriter $objWriter XML Writer
837
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
838
     */
839 100
    private function writePageSetup(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
840
    {
841
        // pageSetup
842 100
        $objWriter->startElement('pageSetup');
843 100
        $objWriter->writeAttribute('paperSize', $pSheet->getPageSetup()->getPaperSize());
844 100
        $objWriter->writeAttribute('orientation', $pSheet->getPageSetup()->getOrientation());
845
846 100
        if ($pSheet->getPageSetup()->getScale() !== null) {
0 ignored issues
show
introduced by
The condition $pSheet->getPageSetup()->getScale() !== null is always true.
Loading history...
847 100
            $objWriter->writeAttribute('scale', $pSheet->getPageSetup()->getScale());
848
        }
849 100
        if ($pSheet->getPageSetup()->getFitToHeight() !== null) {
0 ignored issues
show
introduced by
The condition $pSheet->getPageSetup()-...tFitToHeight() !== null is always true.
Loading history...
850 100
            $objWriter->writeAttribute('fitToHeight', $pSheet->getPageSetup()->getFitToHeight());
851
        } else {
852
            $objWriter->writeAttribute('fitToHeight', '0');
853
        }
854 100
        if ($pSheet->getPageSetup()->getFitToWidth() !== null) {
0 ignored issues
show
introduced by
The condition $pSheet->getPageSetup()->getFitToWidth() !== null is always true.
Loading history...
855 100
            $objWriter->writeAttribute('fitToWidth', $pSheet->getPageSetup()->getFitToWidth());
856
        } else {
857
            $objWriter->writeAttribute('fitToWidth', '0');
858
        }
859 100
        if ($pSheet->getPageSetup()->getFirstPageNumber() !== null) {
0 ignored issues
show
introduced by
The condition $pSheet->getPageSetup()-...stPageNumber() !== null is always true.
Loading history...
860
            $objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber());
861
            $objWriter->writeAttribute('useFirstPageNumber', '1');
862
        }
863
864 100
        $getUnparsedLoadedData = $pSheet->getParent()->getUnparsedLoadedData();
865 100
        if (isset($getUnparsedLoadedData['sheets'][$pSheet->getCodeName()]['pageSetupRelId'])) {
866 4
            $objWriter->writeAttribute('r:id', $getUnparsedLoadedData['sheets'][$pSheet->getCodeName()]['pageSetupRelId']);
867
        }
868
869 100
        $objWriter->endElement();
870 100
    }
871
872
    /**
873
     * Write Header / Footer.
874
     *
875
     * @param XMLWriter $objWriter XML Writer
876
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
877
     */
878 100
    private function writeHeaderFooter(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
879
    {
880
        // headerFooter
881 100
        $objWriter->startElement('headerFooter');
882 100
        $objWriter->writeAttribute('differentOddEven', ($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false'));
883 100
        $objWriter->writeAttribute('differentFirst', ($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false'));
884 100
        $objWriter->writeAttribute('scaleWithDoc', ($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false'));
885 100
        $objWriter->writeAttribute('alignWithMargins', ($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false'));
886
887 100
        $objWriter->writeElement('oddHeader', $pSheet->getHeaderFooter()->getOddHeader());
888 100
        $objWriter->writeElement('oddFooter', $pSheet->getHeaderFooter()->getOddFooter());
889 100
        $objWriter->writeElement('evenHeader', $pSheet->getHeaderFooter()->getEvenHeader());
890 100
        $objWriter->writeElement('evenFooter', $pSheet->getHeaderFooter()->getEvenFooter());
891 100
        $objWriter->writeElement('firstHeader', $pSheet->getHeaderFooter()->getFirstHeader());
892 100
        $objWriter->writeElement('firstFooter', $pSheet->getHeaderFooter()->getFirstFooter());
893 100
        $objWriter->endElement();
894 100
    }
895
896
    /**
897
     * Write Breaks.
898
     *
899
     * @param XMLWriter $objWriter XML Writer
900
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
901
     */
902 100
    private function writeBreaks(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
903
    {
904
        // Get row and column breaks
905 100
        $aRowBreaks = [];
906 100
        $aColumnBreaks = [];
907 100
        foreach ($pSheet->getBreaks() as $cell => $breakType) {
908 1
            if ($breakType == PhpspreadsheetWorksheet::BREAK_ROW) {
909 1
                $aRowBreaks[] = $cell;
910
            } elseif ($breakType == PhpspreadsheetWorksheet::BREAK_COLUMN) {
911
                $aColumnBreaks[] = $cell;
912
            }
913
        }
914
915
        // rowBreaks
916 100
        if (!empty($aRowBreaks)) {
917 1
            $objWriter->startElement('rowBreaks');
918 1
            $objWriter->writeAttribute('count', count($aRowBreaks));
919 1
            $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks));
920
921 1
            foreach ($aRowBreaks as $cell) {
922 1
                $coords = Coordinate::coordinateFromString($cell);
923
924 1
                $objWriter->startElement('brk');
925 1
                $objWriter->writeAttribute('id', $coords[1]);
926 1
                $objWriter->writeAttribute('man', '1');
927 1
                $objWriter->endElement();
928
            }
929
930 1
            $objWriter->endElement();
931
        }
932
933
        // Second, write column breaks
934 100
        if (!empty($aColumnBreaks)) {
935
            $objWriter->startElement('colBreaks');
936
            $objWriter->writeAttribute('count', count($aColumnBreaks));
937
            $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks));
938
939
            foreach ($aColumnBreaks as $cell) {
940
                $coords = Coordinate::coordinateFromString($cell);
941
942
                $objWriter->startElement('brk');
943
                $objWriter->writeAttribute('id', Coordinate::columnIndexFromString($coords[0]) - 1);
944
                $objWriter->writeAttribute('man', '1');
945
                $objWriter->endElement();
946
            }
947
948
            $objWriter->endElement();
949
        }
950 100
    }
951
952
    /**
953
     * Write SheetData.
954
     *
955
     * @param XMLWriter $objWriter XML Writer
956
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
957
     * @param string[] $pStringTable String table
958
     *
959
     * @throws WriterException
960
     */
961 100
    private function writeSheetData(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, array $pStringTable)
962
    {
963
        // Flipped stringtable, for faster index searching
964 100
        $aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->flipStringTable($pStringTable);
0 ignored issues
show
Bug introduced by
The method flipStringTable() does not exist on PhpOffice\PhpSpreadsheet\Writer\Xlsx\WriterPart. It seems like you code against a sub-type of PhpOffice\PhpSpreadsheet\Writer\Xlsx\WriterPart such as PhpOffice\PhpSpreadsheet\Writer\Xlsx\StringTable. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

964
        $aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->/** @scrutinizer ignore-call */ flipStringTable($pStringTable);
Loading history...
965
966
        // sheetData
967 100
        $objWriter->startElement('sheetData');
968
969
        // Get column count
970 100
        $colCount = Coordinate::columnIndexFromString($pSheet->getHighestColumn());
971
972
        // Highest row number
973 100
        $highestRow = $pSheet->getHighestRow();
974
975
        // Loop through cells
976 100
        $cellsByRow = [];
977 100
        foreach ($pSheet->getCoordinates() as $coordinate) {
978 94
            $cellAddress = Coordinate::coordinateFromString($coordinate);
979 94
            $cellsByRow[$cellAddress[1]][] = $coordinate;
980
        }
981
982 100
        $currentRow = 0;
983 100
        while ($currentRow++ < $highestRow) {
984
            // Get row dimension
985 100
            $rowDimension = $pSheet->getRowDimension($currentRow);
986
987
            // Write current row?
988 100
            $writeCurrentRow = isset($cellsByRow[$currentRow]) || $rowDimension->getRowHeight() >= 0 || $rowDimension->getVisible() == false || $rowDimension->getCollapsed() == true || $rowDimension->getOutlineLevel() > 0 || $rowDimension->getXfIndex() !== null;
0 ignored issues
show
introduced by
The condition $rowDimension->getXfIndex() !== null is always true.
Loading history...
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
989
990 100
            if ($writeCurrentRow) {
991
                // Start a new row
992 94
                $objWriter->startElement('row');
993 94
                $objWriter->writeAttribute('r', $currentRow);
994 94
                $objWriter->writeAttribute('spans', '1:' . $colCount);
995
996
                // Row dimensions
997 94
                if ($rowDimension->getRowHeight() >= 0) {
998 6
                    $objWriter->writeAttribute('customHeight', '1');
999 6
                    $objWriter->writeAttribute('ht', StringHelper::formatNumber($rowDimension->getRowHeight()));
1000
                }
1001
1002
                // Row visibility
1003 94
                if (!$rowDimension->getVisible() === true) {
1004 2
                    $objWriter->writeAttribute('hidden', 'true');
1005
                }
1006
1007
                // Collapsed
1008 94
                if ($rowDimension->getCollapsed() === true) {
1009
                    $objWriter->writeAttribute('collapsed', 'true');
1010
                }
1011
1012
                // Outline level
1013 94
                if ($rowDimension->getOutlineLevel() > 0) {
1014
                    $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel());
1015
                }
1016
1017
                // Style
1018 94
                if ($rowDimension->getXfIndex() !== null) {
1019
                    $objWriter->writeAttribute('s', $rowDimension->getXfIndex());
1020
                    $objWriter->writeAttribute('customFormat', '1');
1021
                }
1022
1023
                // Write cells
1024 94
                if (isset($cellsByRow[$currentRow])) {
1025 94
                    foreach ($cellsByRow[$currentRow] as $cellAddress) {
1026
                        // Write cell
1027 94
                        $this->writeCell($objWriter, $pSheet, $cellAddress, $aFlippedStringTable);
1028
                    }
1029
                }
1030
1031
                // End row
1032 94
                $objWriter->endElement();
1033
            }
1034
        }
1035
1036 100
        $objWriter->endElement();
1037 100
    }
1038
1039
    /**
1040
     * Write Cell.
1041
     *
1042
     * @param XMLWriter $objWriter XML Writer
1043
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1044
     * @param Cell $pCellAddress Cell Address
1045
     * @param string[] $pFlippedStringTable String table (flipped), for faster index searching
1046
     *
1047
     * @throws WriterException
1048
     */
1049 94
    private function writeCell(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, $pCellAddress, array $pFlippedStringTable)
1050
    {
1051
        // Cell
1052 94
        $pCell = $pSheet->getCell($pCellAddress);
1053 94
        $objWriter->startElement('c');
1054 94
        $objWriter->writeAttribute('r', $pCellAddress);
1055
1056
        // Sheet styles
1057 94
        if ($pCell->getXfIndex() != '') {
1058 33
            $objWriter->writeAttribute('s', $pCell->getXfIndex());
1059
        }
1060
1061
        // If cell value is supplied, write cell value
1062 94
        $cellValue = $pCell->getValue();
1063 94
        if (is_object($cellValue) || $cellValue !== '') {
1064
            // Map type
1065 94
            $mappedType = $pCell->getDataType();
1066
1067
            // Write data type depending on its type
1068 94
            switch (strtolower($mappedType)) {
1069 94
                case 'inlinestr':    // Inline string
1070 93
                case 's':            // String
1071 80
                case 'b':            // Boolean
1072 62
                    $objWriter->writeAttribute('t', $mappedType);
1073
1074 62
                    break;
1075 77
                case 'f':            // Formula
1076 22
                    $calculatedValue = ($this->getParentWriter()->getPreCalculateFormulas()) ?
1077 22
                        $pCell->getCalculatedValue() : $cellValue;
1078 22
                    if (is_string($calculatedValue)) {
1079 14
                        $objWriter->writeAttribute('t', 'str');
1080 19
                    } elseif (is_bool($calculatedValue)) {
1081 5
                        $objWriter->writeAttribute('t', 'b');
1082
                    }
1083
1084 22
                    break;
1085 73
                case 'e':            // Error
1086
                    $objWriter->writeAttribute('t', $mappedType);
1087
            }
1088
1089
            // Write data depending on its type
1090 94
            switch (strtolower($mappedType)) {
1091 94
                case 'inlinestr':    // Inline string
1092 8
                    if (!$cellValue instanceof RichText) {
1093
                        $objWriter->writeElement('t', StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue)));
1094 8
                    } elseif ($cellValue instanceof RichText) {
0 ignored issues
show
introduced by
$cellValue is always a sub-type of PhpOffice\PhpSpreadsheet\RichText\RichText.
Loading history...
1095 8
                        $objWriter->startElement('is');
1096 8
                        $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $cellValue);
0 ignored issues
show
Bug introduced by
The method writeRichText() does not exist on PhpOffice\PhpSpreadsheet\Writer\Xlsx\WriterPart. It seems like you code against a sub-type of PhpOffice\PhpSpreadsheet\Writer\Xlsx\WriterPart such as PhpOffice\PhpSpreadsheet\Writer\Xlsx\StringTable. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1096
                        $this->getParentWriter()->getWriterPart('stringtable')->/** @scrutinizer ignore-call */ writeRichText($objWriter, $cellValue);
Loading history...
1097 8
                        $objWriter->endElement();
1098
                    }
1099
1100 8
                    break;
1101 93
                case 's':            // String
1102 60
                    if (!$cellValue instanceof RichText) {
1103 60
                        if (isset($pFlippedStringTable[$cellValue])) {
1104 60
                            $objWriter->writeElement('v', $pFlippedStringTable[$cellValue]);
1105
                        }
1106 2
                    } elseif ($cellValue instanceof RichText) {
0 ignored issues
show
introduced by
$cellValue is always a sub-type of PhpOffice\PhpSpreadsheet\RichText\RichText.
Loading history...
1107 2
                        $objWriter->writeElement('v', $pFlippedStringTable[$cellValue->getHashCode()]);
1108
                    }
1109
1110 60
                    break;
1111 80
                case 'f':            // Formula
1112 22
                    $attributes = $pCell->getFormulaAttributes();
1113 22
                    if (($attributes['t'] ?? null) === 'array') {
1114
                        $objWriter->startElement('f');
1115
                        $objWriter->writeAttribute('t', 'array');
1116
                        $objWriter->writeAttribute('ref', $pCellAddress);
1117
                        $objWriter->writeAttribute('aca', '1');
1118
                        $objWriter->writeAttribute('ca', '1');
1119
                        $objWriter->text(substr($cellValue, 1));
1120
                        $objWriter->endElement();
1121
                    } else {
1122 22
                        $objWriter->writeElement('f', substr($cellValue, 1));
1123
                    }
1124 22
                    if ($this->getParentWriter()->getOffice2003Compatibility() === false) {
1125 22
                        if ($this->getParentWriter()->getPreCalculateFormulas()) {
1126 22
                            if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) !== '#') {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $calculatedValue does not seem to be defined for all execution paths leading up to this point.
Loading history...
1127 22
                                $objWriter->writeElement('v', StringHelper::formatNumber($calculatedValue));
1128
                            } else {
1129 22
                                $objWriter->writeElement('v', '0');
1130
                            }
1131
                        } else {
1132
                            $objWriter->writeElement('v', '0');
1133
                        }
1134
                    }
1135
1136 22
                    break;
1137 76
                case 'n':            // Numeric
1138
                    //force a decimal to be written if the type is float
1139 65
                    if (is_float($cellValue)) {
1140 27
                        $cellValue = (string) $cellValue;
1141 27
                        if (strpos($cellValue, '.') === false) {
1142 17
                            $cellValue = $cellValue . '.0';
1143
                        }
1144
                    }
1145
                    // force point as decimal separator in case current locale uses comma
1146 65
                    $objWriter->writeElement('v', str_replace(',', '.', $cellValue));
1147
1148 65
                    break;
1149 29
                case 'b':            // Boolean
1150 9
                    $objWriter->writeElement('v', ($cellValue ? '1' : '0'));
1151
1152 9
                    break;
1153 24
                case 'e':            // Error
1154
                    if (substr($cellValue, 0, 1) === '=') {
1155
                        $objWriter->writeElement('f', substr($cellValue, 1));
1156
                        $objWriter->writeElement('v', substr($cellValue, 1));
1157
                    } else {
1158
                        $objWriter->writeElement('v', $cellValue);
1159
                    }
1160
1161
                    break;
1162
            }
1163
        }
1164
1165 94
        $objWriter->endElement();
1166 94
    }
1167
1168
    /**
1169
     * Write Drawings.
1170
     *
1171
     * @param XMLWriter $objWriter XML Writer
1172
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1173
     * @param bool $includeCharts Flag indicating if we should include drawing details for charts
1174
     */
1175 100
    private function writeDrawings(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, $includeCharts = false)
1176
    {
1177 100
        $unparsedLoadedData = $pSheet->getParent()->getUnparsedLoadedData();
1178 100
        $hasUnparsedDrawing = isset($unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds']);
1179 100
        $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0;
1180 100
        if ($chartCount == 0 && $pSheet->getDrawingCollection()->count() == 0 && !$hasUnparsedDrawing) {
1181 75
            return;
1182
        }
1183
1184
        // If sheet contains drawings, add the relationships
1185 27
        $objWriter->startElement('drawing');
1186
1187 27
        $rId = 'rId1';
1188 27
        if (isset($unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds'])) {
1189 4
            $drawingOriginalIds = $unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds'];
1190
            // take first. In future can be overriten
1191 4
            $rId = reset($drawingOriginalIds);
1192
        }
1193
1194 27
        $objWriter->writeAttribute('r:id', $rId);
1195 27
        $objWriter->endElement();
1196 27
    }
1197
1198
    /**
1199
     * Write LegacyDrawing.
1200
     *
1201
     * @param XMLWriter $objWriter XML Writer
1202
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1203
     */
1204 100
    private function writeLegacyDrawing(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
1205
    {
1206
        // If sheet contains comments, add the relationships
1207 100
        if (count($pSheet->getComments()) > 0) {
1208 10
            $objWriter->startElement('legacyDrawing');
1209 10
            $objWriter->writeAttribute('r:id', 'rId_comments_vml1');
1210 10
            $objWriter->endElement();
1211
        }
1212 100
    }
1213
1214
    /**
1215
     * Write LegacyDrawingHF.
1216
     *
1217
     * @param XMLWriter $objWriter XML Writer
1218
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1219
     */
1220 100
    private function writeLegacyDrawingHF(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
1221
    {
1222
        // If sheet contains images, add the relationships
1223 100
        if (count($pSheet->getHeaderFooter()->getImages()) > 0) {
1224 1
            $objWriter->startElement('legacyDrawingHF');
1225 1
            $objWriter->writeAttribute('r:id', 'rId_headerfooter_vml1');
1226 1
            $objWriter->endElement();
1227
        }
1228 100
    }
1229
1230 100
    private function writeAlternateContent(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
1231
    {
1232 100
        if (empty($pSheet->getParent()->getUnparsedLoadedData()['sheets'][$pSheet->getCodeName()]['AlternateContents'])) {
1233 100
            return;
1234
        }
1235
1236 1
        foreach ($pSheet->getParent()->getUnparsedLoadedData()['sheets'][$pSheet->getCodeName()]['AlternateContents'] as $alternateContent) {
1237 1
            $objWriter->writeRaw($alternateContent);
1238
        }
1239 1
    }
1240
}
1241