Failed Conditions
Push — master ( 27d83b...a2771e )
by Adrien
35:04
created

Worksheet::writeConditionalFormatting()   C

Complexity

Conditions 26
Paths 51

Size

Total Lines 65
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 37
CRAP Score 27.1391

Importance

Changes 0
Metric Value
cc 26
eloc 41
nc 51
nop 2
dl 0
loc 65
ccs 37
cts 42
cp 0.881
crap 27.1391
rs 5.7771
c 0
b 0
f 0

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 60
    public function writeWorksheet(PhpspreadsheetWorksheet $pSheet, $pStringTable = null, $includeCharts = false)
36
    {
37
        // Create XML writer
38 60
        $objWriter = null;
39 60
        if ($this->getParentWriter()->getUseDiskCaching()) {
40
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
41
        } else {
42 60
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
43
        }
44
45
        // XML header
46 60
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
47
48
        // Worksheet
49 60
        $objWriter->startElement('worksheet');
50 60
        $objWriter->writeAttribute('xml:space', 'preserve');
51 60
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
52 60
        $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
53
54
        // sheetPr
55 60
        $this->writeSheetPr($objWriter, $pSheet);
56
57
        // Dimension
58 60
        $this->writeDimension($objWriter, $pSheet);
59
60
        // sheetViews
61 60
        $this->writeSheetViews($objWriter, $pSheet);
62
63
        // sheetFormatPr
64 60
        $this->writeSheetFormatPr($objWriter, $pSheet);
65
66
        // cols
67 60
        $this->writeCols($objWriter, $pSheet);
68
69
        // sheetData
70 60
        $this->writeSheetData($objWriter, $pSheet, $pStringTable);
71
72
        // sheetProtection
73 60
        $this->writeSheetProtection($objWriter, $pSheet);
74
75
        // protectedRanges
76 60
        $this->writeProtectedRanges($objWriter, $pSheet);
77
78
        // autoFilter
79 60
        $this->writeAutoFilter($objWriter, $pSheet);
80
81
        // mergeCells
82 60
        $this->writeMergeCells($objWriter, $pSheet);
83
84
        // conditionalFormatting
85 60
        $this->writeConditionalFormatting($objWriter, $pSheet);
86
87
        // dataValidations
88 60
        $this->writeDataValidations($objWriter, $pSheet);
89
90
        // hyperlinks
91 60
        $this->writeHyperlinks($objWriter, $pSheet);
92
93
        // Print options
94 60
        $this->writePrintOptions($objWriter, $pSheet);
95
96
        // Page margins
97 60
        $this->writePageMargins($objWriter, $pSheet);
98
99
        // Page setup
100 60
        $this->writePageSetup($objWriter, $pSheet);
101
102
        // Header / footer
103 60
        $this->writeHeaderFooter($objWriter, $pSheet);
104
105
        // Breaks
106 60
        $this->writeBreaks($objWriter, $pSheet);
107
108
        // Drawings and/or Charts
109 60
        $this->writeDrawings($objWriter, $pSheet, $includeCharts);
110
111
        // LegacyDrawing
112 60
        $this->writeLegacyDrawing($objWriter, $pSheet);
113
114
        // LegacyDrawingHF
115 60
        $this->writeLegacyDrawingHF($objWriter, $pSheet);
116
117 60
        $objWriter->endElement();
118
119
        // Return
120 60
        return $objWriter->getData();
121
    }
122
123
    /**
124
     * Write SheetPr.
125
     *
126
     * @param XMLWriter $objWriter XML Writer
127
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
128
     */
129 60
    private function writeSheetPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
130
    {
131
        // sheetPr
132 60
        $objWriter->startElement('sheetPr');
133 60
        if ($pSheet->getParent()->hasMacros()) {
134
            //if the workbook have macros, we need to have codeName for the sheet
135
            if ($pSheet->hasCodeName() == false) {
136
                $pSheet->setCodeName($pSheet->getTitle());
137
            }
138
            $objWriter->writeAttribute('codeName', $pSheet->getCodeName());
139
        }
140 60
        $autoFilterRange = $pSheet->getAutoFilter()->getRange();
141 60
        if (!empty($autoFilterRange)) {
142 3
            $objWriter->writeAttribute('filterMode', 1);
143 3
            $pSheet->getAutoFilter()->showHideRows();
144
        }
145
146
        // tabColor
147 60
        if ($pSheet->isTabColorSet()) {
148 6
            $objWriter->startElement('tabColor');
149 6
            $objWriter->writeAttribute('rgb', $pSheet->getTabColor()->getARGB());
150 6
            $objWriter->endElement();
151
        }
152
153
        // outlinePr
154 60
        $objWriter->startElement('outlinePr');
155 60
        $objWriter->writeAttribute('summaryBelow', ($pSheet->getShowSummaryBelow() ? '1' : '0'));
156 60
        $objWriter->writeAttribute('summaryRight', ($pSheet->getShowSummaryRight() ? '1' : '0'));
157 60
        $objWriter->endElement();
158
159
        // pageSetUpPr
160 60
        if ($pSheet->getPageSetup()->getFitToPage()) {
161
            $objWriter->startElement('pageSetUpPr');
162
            $objWriter->writeAttribute('fitToPage', '1');
163
            $objWriter->endElement();
164
        }
165
166 60
        $objWriter->endElement();
167 60
    }
168
169
    /**
170
     * Write Dimension.
171
     *
172
     * @param XMLWriter $objWriter XML Writer
173
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
174
     */
175 60
    private function writeDimension(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
176
    {
177
        // dimension
178 60
        $objWriter->startElement('dimension');
179 60
        $objWriter->writeAttribute('ref', $pSheet->calculateWorksheetDimension());
180 60
        $objWriter->endElement();
181 60
    }
182
183
    /**
184
     * Write SheetViews.
185
     *
186
     * @param XMLWriter $objWriter XML Writer
187
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
188
     *
189
     * @throws WriterException
190
     */
191 60
    private function writeSheetViews(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
192
    {
193
        // sheetViews
194 60
        $objWriter->startElement('sheetViews');
195
196
        // Sheet selected?
197 60
        $sheetSelected = false;
198 60
        if ($this->getParentWriter()->getSpreadsheet()->getIndex($pSheet) == $this->getParentWriter()->getSpreadsheet()->getActiveSheetIndex()) {
199 60
            $sheetSelected = true;
200
        }
201
202
        // sheetView
203 60
        $objWriter->startElement('sheetView');
204 60
        $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0');
205 60
        $objWriter->writeAttribute('workbookViewId', '0');
206
207
        // Zoom scales
208 60
        if ($pSheet->getSheetView()->getZoomScale() != 100) {
209
            $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale());
210
        }
211 60
        if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) {
212
            $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal());
213
        }
214
215
        // View Layout Type
216 60
        if ($pSheet->getSheetView()->getView() !== SheetView::SHEETVIEW_NORMAL) {
217 1
            $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView());
218
        }
219
220
        // Gridlines
221 60
        if ($pSheet->getShowGridlines()) {
222 60
            $objWriter->writeAttribute('showGridLines', 'true');
223
        } else {
224
            $objWriter->writeAttribute('showGridLines', 'false');
225
        }
226
227
        // Row and column headers
228 60
        if ($pSheet->getShowRowColHeaders()) {
229 60
            $objWriter->writeAttribute('showRowColHeaders', '1');
230
        } else {
231
            $objWriter->writeAttribute('showRowColHeaders', '0');
232
        }
233
234
        // Right-to-left
235 60
        if ($pSheet->getRightToLeft()) {
236
            $objWriter->writeAttribute('rightToLeft', 'true');
237
        }
238
239 60
        $activeCell = $pSheet->getActiveCell();
240
241
        // Pane
242 60
        $pane = '';
243 60
        if ($pSheet->getFreezePane()) {
244 4
            list($xSplit, $ySplit) = Coordinate::coordinateFromString($pSheet->getFreezePane());
245 4
            $xSplit = Coordinate::columnIndexFromString($xSplit);
246 4
            --$xSplit;
247 4
            --$ySplit;
248
249 4
            $topLeftCell = $pSheet->getTopLeftCell();
250 4
            $activeCell = $topLeftCell;
251
252
            // pane
253 4
            $pane = 'topRight';
254 4
            $objWriter->startElement('pane');
255 4
            if ($xSplit > 0) {
256 1
                $objWriter->writeAttribute('xSplit', $xSplit);
257
            }
258 4
            if ($ySplit > 0) {
259 4
                $objWriter->writeAttribute('ySplit', $ySplit);
260 4
                $pane = ($xSplit > 0) ? 'bottomRight' : 'bottomLeft';
261
            }
262 4
            $objWriter->writeAttribute('topLeftCell', $topLeftCell);
263 4
            $objWriter->writeAttribute('activePane', $pane);
264 4
            $objWriter->writeAttribute('state', 'frozen');
265 4
            $objWriter->endElement();
266
267 4
            if (($xSplit > 0) && ($ySplit > 0)) {
268
                //    Write additional selections if more than two panes (ie both an X and a Y split)
269 1
                $objWriter->startElement('selection');
270 1
                $objWriter->writeAttribute('pane', 'topRight');
271 1
                $objWriter->endElement();
272 1
                $objWriter->startElement('selection');
273 1
                $objWriter->writeAttribute('pane', 'bottomLeft');
274 1
                $objWriter->endElement();
275
            }
276
        }
277
278
        // Selection
279
        // Only need to write selection element if we have a split pane
280
        // We cheat a little by over-riding the active cell selection, setting it to the split cell
281 60
        $objWriter->startElement('selection');
282 60
        if ($pane != '') {
283 4
            $objWriter->writeAttribute('pane', $pane);
284
        }
285 60
        $objWriter->writeAttribute('activeCell', $activeCell);
286 60
        $objWriter->writeAttribute('sqref', $activeCell);
287 60
        $objWriter->endElement();
288
289 60
        $objWriter->endElement();
290
291 60
        $objWriter->endElement();
292 60
    }
293
294
    /**
295
     * Write SheetFormatPr.
296
     *
297
     * @param XMLWriter $objWriter XML Writer
298
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
299
     */
300 60
    private function writeSheetFormatPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
301
    {
302
        // sheetFormatPr
303 60
        $objWriter->startElement('sheetFormatPr');
304
305
        // Default row height
306 60
        if ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) {
307 2
            $objWriter->writeAttribute('customHeight', 'true');
308 2
            $objWriter->writeAttribute('defaultRowHeight', StringHelper::formatNumber($pSheet->getDefaultRowDimension()->getRowHeight()));
309
        } else {
310 58
            $objWriter->writeAttribute('defaultRowHeight', '14.4');
311
        }
312
313
        // Set Zero Height row
314 60
        if ((string) $pSheet->getDefaultRowDimension()->getZeroHeight() == '1' ||
315 60
            strtolower((string) $pSheet->getDefaultRowDimension()->getZeroHeight()) == 'true') {
316
            $objWriter->writeAttribute('zeroHeight', '1');
317
        }
318
319
        // Default column width
320 60
        if ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) {
321 1
            $objWriter->writeAttribute('defaultColWidth', StringHelper::formatNumber($pSheet->getDefaultColumnDimension()->getWidth()));
322
        }
323
324
        // Outline level - row
325 60
        $outlineLevelRow = 0;
326 60
        foreach ($pSheet->getRowDimensions() as $dimension) {
327 11
            if ($dimension->getOutlineLevel() > $outlineLevelRow) {
328 11
                $outlineLevelRow = $dimension->getOutlineLevel();
329
            }
330
        }
331 60
        $objWriter->writeAttribute('outlineLevelRow', (int) $outlineLevelRow);
332
333
        // Outline level - column
334 60
        $outlineLevelCol = 0;
335 60
        foreach ($pSheet->getColumnDimensions() as $dimension) {
336 21
            if ($dimension->getOutlineLevel() > $outlineLevelCol) {
337 21
                $outlineLevelCol = $dimension->getOutlineLevel();
338
            }
339
        }
340 60
        $objWriter->writeAttribute('outlineLevelCol', (int) $outlineLevelCol);
341
342 60
        $objWriter->endElement();
343 60
    }
344
345
    /**
346
     * Write Cols.
347
     *
348
     * @param XMLWriter $objWriter XML Writer
349
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
350
     */
351 60
    private function writeCols(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
352
    {
353
        // cols
354 60
        if (count($pSheet->getColumnDimensions()) > 0) {
355 21
            $objWriter->startElement('cols');
356
357 21
            $pSheet->calculateColumnWidths();
358
359
            // Loop through column dimensions
360 21
            foreach ($pSheet->getColumnDimensions() as $colDimension) {
361
                // col
362 21
                $objWriter->startElement('col');
363 21
                $objWriter->writeAttribute('min', Coordinate::columnIndexFromString($colDimension->getColumnIndex()));
364 21
                $objWriter->writeAttribute('max', Coordinate::columnIndexFromString($colDimension->getColumnIndex()));
365
366 21
                if ($colDimension->getWidth() < 0) {
367
                    // No width set, apply default of 10
368 2
                    $objWriter->writeAttribute('width', '9.10');
369
                } else {
370
                    // Width set
371 21
                    $objWriter->writeAttribute('width', StringHelper::formatNumber($colDimension->getWidth()));
372
                }
373
374
                // Column visibility
375 21
                if ($colDimension->getVisible() == false) {
376 3
                    $objWriter->writeAttribute('hidden', 'true');
377
                }
378
379
                // Auto size?
380 21
                if ($colDimension->getAutoSize()) {
381 8
                    $objWriter->writeAttribute('bestFit', 'true');
382
                }
383
384
                // Custom width?
385 21
                if ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) {
386 21
                    $objWriter->writeAttribute('customWidth', 'true');
387
                }
388
389
                // Collapsed
390 21
                if ($colDimension->getCollapsed() == true) {
391 1
                    $objWriter->writeAttribute('collapsed', 'true');
392
                }
393
394
                // Outline level
395 21
                if ($colDimension->getOutlineLevel() > 0) {
396 1
                    $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel());
397
                }
398
399
                // Style
400 21
                $objWriter->writeAttribute('style', $colDimension->getXfIndex());
401
402 21
                $objWriter->endElement();
403
            }
404
405 21
            $objWriter->endElement();
406
        }
407 60
    }
408
409
    /**
410
     * Write SheetProtection.
411
     *
412
     * @param XMLWriter $objWriter XML Writer
413
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
414
     */
415 60
    private function writeSheetProtection(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
416
    {
417
        // sheetProtection
418 60
        $objWriter->startElement('sheetProtection');
419
420 60
        if ($pSheet->getProtection()->getPassword() != '') {
421 1
            $objWriter->writeAttribute('password', $pSheet->getProtection()->getPassword());
422
        }
423
424 60
        $objWriter->writeAttribute('sheet', ($pSheet->getProtection()->getSheet() ? 'true' : 'false'));
425 60
        $objWriter->writeAttribute('objects', ($pSheet->getProtection()->getObjects() ? 'true' : 'false'));
426 60
        $objWriter->writeAttribute('scenarios', ($pSheet->getProtection()->getScenarios() ? 'true' : 'false'));
427 60
        $objWriter->writeAttribute('formatCells', ($pSheet->getProtection()->getFormatCells() ? 'true' : 'false'));
428 60
        $objWriter->writeAttribute('formatColumns', ($pSheet->getProtection()->getFormatColumns() ? 'true' : 'false'));
429 60
        $objWriter->writeAttribute('formatRows', ($pSheet->getProtection()->getFormatRows() ? 'true' : 'false'));
430 60
        $objWriter->writeAttribute('insertColumns', ($pSheet->getProtection()->getInsertColumns() ? 'true' : 'false'));
431 60
        $objWriter->writeAttribute('insertRows', ($pSheet->getProtection()->getInsertRows() ? 'true' : 'false'));
432 60
        $objWriter->writeAttribute('insertHyperlinks', ($pSheet->getProtection()->getInsertHyperlinks() ? 'true' : 'false'));
433 60
        $objWriter->writeAttribute('deleteColumns', ($pSheet->getProtection()->getDeleteColumns() ? 'true' : 'false'));
434 60
        $objWriter->writeAttribute('deleteRows', ($pSheet->getProtection()->getDeleteRows() ? 'true' : 'false'));
435 60
        $objWriter->writeAttribute('selectLockedCells', ($pSheet->getProtection()->getSelectLockedCells() ? 'true' : 'false'));
436 60
        $objWriter->writeAttribute('sort', ($pSheet->getProtection()->getSort() ? 'true' : 'false'));
437 60
        $objWriter->writeAttribute('autoFilter', ($pSheet->getProtection()->getAutoFilter() ? 'true' : 'false'));
438 60
        $objWriter->writeAttribute('pivotTables', ($pSheet->getProtection()->getPivotTables() ? 'true' : 'false'));
439 60
        $objWriter->writeAttribute('selectUnlockedCells', ($pSheet->getProtection()->getSelectUnlockedCells() ? 'true' : 'false'));
440 60
        $objWriter->endElement();
441 60
    }
442
443
    /**
444
     * Write ConditionalFormatting.
445
     *
446
     * @param XMLWriter $objWriter XML Writer
447
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
448
     *
449
     * @throws WriterException
450
     */
451 60
    private function writeConditionalFormatting(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
452
    {
453
        // Conditional id
454 60
        $id = 1;
455
456
        // Loop through styles in the current worksheet
457 60
        foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) {
458 3
            foreach ($conditionalStyles as $conditional) {
459
                // WHY was this again?
460
                // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()) == '') {
0 ignored issues
show
Unused Code Comprehensibility introduced by
66% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
461
                //    continue;
462
                // }
463 3
                if ($conditional->getConditionType() != Conditional::CONDITION_NONE) {
464
                    // conditionalFormatting
465 3
                    $objWriter->startElement('conditionalFormatting');
466 3
                    $objWriter->writeAttribute('sqref', $cellCoordinate);
467
468
                    // cfRule
469 3
                    $objWriter->startElement('cfRule');
470 3
                    $objWriter->writeAttribute('type', $conditional->getConditionType());
471 3
                    $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()));
472 3
                    $objWriter->writeAttribute('priority', $id++);
473
474 3
                    if (($conditional->getConditionType() == Conditional::CONDITION_CELLIS || $conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT)
475 3
                        && $conditional->getOperatorType() != Conditional::OPERATOR_NONE) {
476 3
                        $objWriter->writeAttribute('operator', $conditional->getOperatorType());
477
                    }
478
479 3
                    if ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
480 3
                        && $conditional->getText() !== null) {
481
                        $objWriter->writeAttribute('text', $conditional->getText());
482
                    }
483
484 3
                    if ($conditional->getStopIfTrue()) {
485 1
                        $objWriter->writeAttribute('stopIfTrue', '1');
486
                    }
487
488 3
                    if ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
489 3
                        && $conditional->getOperatorType() == Conditional::OPERATOR_CONTAINSTEXT
490 3
                        && $conditional->getText() !== null) {
491
                        $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))');
492 3
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
493 3
                        && $conditional->getOperatorType() == Conditional::OPERATOR_BEGINSWITH
494 3
                        && $conditional->getText() !== null) {
495
                        $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"');
496 3
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
497 3
                        && $conditional->getOperatorType() == Conditional::OPERATOR_ENDSWITH
498 3
                        && $conditional->getText() !== null) {
499
                        $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"');
500 3
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
501 3
                        && $conditional->getOperatorType() == Conditional::OPERATOR_NOTCONTAINS
502 3
                        && $conditional->getText() !== null) {
503
                        $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))');
504 3
                    } elseif ($conditional->getConditionType() == Conditional::CONDITION_CELLIS
505 1
                        || $conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
506 3
                        || $conditional->getConditionType() == Conditional::CONDITION_EXPRESSION) {
507 3
                        foreach ($conditional->getConditions() as $formula) {
508
                            // Formula
509 3
                            $objWriter->writeElement('formula', $formula);
510
                        }
511
                    }
512
513 3
                    $objWriter->endElement();
514
515 3
                    $objWriter->endElement();
516
                }
517
            }
518
        }
519 60
    }
520
521
    /**
522
     * Write DataValidations.
523
     *
524
     * @param XMLWriter $objWriter XML Writer
525
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
526
     */
527 60
    private function writeDataValidations(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
528
    {
529
        // Datavalidation collection
530 60
        $dataValidationCollection = $pSheet->getDataValidationCollection();
531
532
        // Write data validations?
533 60
        if (!empty($dataValidationCollection)) {
534 2
            $dataValidationCollection = Coordinate::mergeRangesInCollection($dataValidationCollection);
535 2
            $objWriter->startElement('dataValidations');
536 2
            $objWriter->writeAttribute('count', count($dataValidationCollection));
537
538 2
            foreach ($dataValidationCollection as $coordinate => $dv) {
539 2
                $objWriter->startElement('dataValidation');
540
541 2
                if ($dv->getType() != '') {
542 2
                    $objWriter->writeAttribute('type', $dv->getType());
543
                }
544
545 2
                if ($dv->getErrorStyle() != '') {
546 2
                    $objWriter->writeAttribute('errorStyle', $dv->getErrorStyle());
547
                }
548
549 2
                if ($dv->getOperator() != '') {
550 2
                    $objWriter->writeAttribute('operator', $dv->getOperator());
551
                }
552
553 2
                $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0'));
554 2
                $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0'));
555 2
                $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0'));
556 2
                $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0'));
557
558 2
                if ($dv->getErrorTitle() !== '') {
559 2
                    $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle());
560
                }
561 2
                if ($dv->getError() !== '') {
562 2
                    $objWriter->writeAttribute('error', $dv->getError());
563
                }
564 2
                if ($dv->getPromptTitle() !== '') {
565 2
                    $objWriter->writeAttribute('promptTitle', $dv->getPromptTitle());
566
                }
567 2
                if ($dv->getPrompt() !== '') {
568 2
                    $objWriter->writeAttribute('prompt', $dv->getPrompt());
569
                }
570
571 2
                $objWriter->writeAttribute('sqref', $coordinate);
572
573 2
                if ($dv->getFormula1() !== '') {
574 2
                    $objWriter->writeElement('formula1', $dv->getFormula1());
575
                }
576 2
                if ($dv->getFormula2() !== '') {
577 1
                    $objWriter->writeElement('formula2', $dv->getFormula2());
578
                }
579
580 2
                $objWriter->endElement();
581
            }
582
583 2
            $objWriter->endElement();
584
        }
585 60
    }
586
587
    /**
588
     * Write Hyperlinks.
589
     *
590
     * @param XMLWriter $objWriter XML Writer
591
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
592
     */
593 60
    private function writeHyperlinks(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
594
    {
595
        // Hyperlink collection
596 60
        $hyperlinkCollection = $pSheet->getHyperlinkCollection();
597
598
        // Relation ID
599 60
        $relationId = 1;
600
601
        // Write hyperlinks?
602 60
        if (!empty($hyperlinkCollection)) {
603 10
            $objWriter->startElement('hyperlinks');
604
605 10
            foreach ($hyperlinkCollection as $coordinate => $hyperlink) {
606 10
                $objWriter->startElement('hyperlink');
607
608 10
                $objWriter->writeAttribute('ref', $coordinate);
609 10
                if (!$hyperlink->isInternal()) {
610 10
                    $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId);
611 10
                    ++$relationId;
612
                } else {
613 7
                    $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl()));
614
                }
615
616 10
                if ($hyperlink->getTooltip() != '') {
617 6
                    $objWriter->writeAttribute('tooltip', $hyperlink->getTooltip());
618
                }
619
620 10
                $objWriter->endElement();
621
            }
622
623 10
            $objWriter->endElement();
624
        }
625 60
    }
626
627
    /**
628
     * Write ProtectedRanges.
629
     *
630
     * @param XMLWriter $objWriter XML Writer
631
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
632
     */
633 60
    private function writeProtectedRanges(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
634
    {
635 60
        if (count($pSheet->getProtectedCells()) > 0) {
636
            // protectedRanges
637 6
            $objWriter->startElement('protectedRanges');
638
639
            // Loop protectedRanges
640 6
            foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) {
641
                // protectedRange
642 6
                $objWriter->startElement('protectedRange');
643 6
                $objWriter->writeAttribute('name', 'p' . md5($protectedCell));
644 6
                $objWriter->writeAttribute('sqref', $protectedCell);
645 6
                if (!empty($passwordHash)) {
646 6
                    $objWriter->writeAttribute('password', $passwordHash);
647
                }
648 6
                $objWriter->endElement();
649
            }
650
651 6
            $objWriter->endElement();
652
        }
653 60
    }
654
655
    /**
656
     * Write MergeCells.
657
     *
658
     * @param XMLWriter $objWriter XML Writer
659
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
660
     */
661 60
    private function writeMergeCells(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
662
    {
663 60
        if (count($pSheet->getMergeCells()) > 0) {
664
            // mergeCells
665 13
            $objWriter->startElement('mergeCells');
666
667
            // Loop mergeCells
668 13
            foreach ($pSheet->getMergeCells() as $mergeCell) {
669
                // mergeCell
670 13
                $objWriter->startElement('mergeCell');
671 13
                $objWriter->writeAttribute('ref', $mergeCell);
672 13
                $objWriter->endElement();
673
            }
674
675 13
            $objWriter->endElement();
676
        }
677 60
    }
678
679
    /**
680
     * Write PrintOptions.
681
     *
682
     * @param XMLWriter $objWriter XML Writer
683
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
684
     */
685 60
    private function writePrintOptions(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
686
    {
687
        // printOptions
688 60
        $objWriter->startElement('printOptions');
689
690 60
        $objWriter->writeAttribute('gridLines', ($pSheet->getPrintGridlines() ? 'true' : 'false'));
691 60
        $objWriter->writeAttribute('gridLinesSet', 'true');
692
693 60
        if ($pSheet->getPageSetup()->getHorizontalCentered()) {
694
            $objWriter->writeAttribute('horizontalCentered', 'true');
695
        }
696
697 60
        if ($pSheet->getPageSetup()->getVerticalCentered()) {
698
            $objWriter->writeAttribute('verticalCentered', 'true');
699
        }
700
701 60
        $objWriter->endElement();
702 60
    }
703
704
    /**
705
     * Write PageMargins.
706
     *
707
     * @param XMLWriter $objWriter XML Writer
708
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
709
     */
710 60
    private function writePageMargins(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
711
    {
712
        // pageMargins
713 60
        $objWriter->startElement('pageMargins');
714 60
        $objWriter->writeAttribute('left', StringHelper::formatNumber($pSheet->getPageMargins()->getLeft()));
715 60
        $objWriter->writeAttribute('right', StringHelper::formatNumber($pSheet->getPageMargins()->getRight()));
716 60
        $objWriter->writeAttribute('top', StringHelper::formatNumber($pSheet->getPageMargins()->getTop()));
717 60
        $objWriter->writeAttribute('bottom', StringHelper::formatNumber($pSheet->getPageMargins()->getBottom()));
718 60
        $objWriter->writeAttribute('header', StringHelper::formatNumber($pSheet->getPageMargins()->getHeader()));
719 60
        $objWriter->writeAttribute('footer', StringHelper::formatNumber($pSheet->getPageMargins()->getFooter()));
720 60
        $objWriter->endElement();
721 60
    }
722
723
    /**
724
     * Write AutoFilter.
725
     *
726
     * @param XMLWriter $objWriter XML Writer
727
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
728
     */
729 60
    private function writeAutoFilter(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
730
    {
731 60
        $autoFilterRange = $pSheet->getAutoFilter()->getRange();
732 60
        if (!empty($autoFilterRange)) {
733
            // autoFilter
734 3
            $objWriter->startElement('autoFilter');
735
736
            // Strip any worksheet reference from the filter coordinates
737 3
            $range = Coordinate::splitRange($autoFilterRange);
738 3
            $range = $range[0];
739
            //    Strip any worksheet ref
740 3
            if (strpos($range[0], '!') !== false) {
741
                list($ws, $range[0]) = explode('!', $range[0]);
742
            }
743 3
            $range = implode(':', $range);
744
745 3
            $objWriter->writeAttribute('ref', str_replace('$', '', $range));
746
747 3
            $columns = $pSheet->getAutoFilter()->getColumns();
748 3
            if (count($columns) > 0) {
749 2
                foreach ($columns as $columnID => $column) {
750 2
                    $rules = $column->getRules();
751 2
                    if (count($rules) > 0) {
752 2
                        $objWriter->startElement('filterColumn');
753 2
                        $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID));
754
755 2
                        $objWriter->startElement($column->getFilterType());
756 2
                        if ($column->getJoin() == Column::AUTOFILTER_COLUMN_JOIN_AND) {
757 1
                            $objWriter->writeAttribute('and', 1);
758
                        }
759
760 2
                        foreach ($rules as $rule) {
761 2
                            if (($column->getFilterType() === Column::AUTOFILTER_FILTERTYPE_FILTER) &&
762 2
                                ($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_EQUAL) &&
763 2
                                ($rule->getValue() === '')) {
764
                                //    Filter rule for Blanks
765 1
                                $objWriter->writeAttribute('blank', 1);
766 2
                            } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) {
767
                                //    Dynamic Filter Rule
768 1
                                $objWriter->writeAttribute('type', $rule->getGrouping());
769 1
                                $val = $column->getAttribute('val');
770 1
                                if ($val !== null) {
771 1
                                    $objWriter->writeAttribute('val', $val);
772
                                }
773 1
                                $maxVal = $column->getAttribute('maxVal');
774 1
                                if ($maxVal !== null) {
775 1
                                    $objWriter->writeAttribute('maxVal', $maxVal);
776
                                }
777 2
                            } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) {
778
                                //    Top 10 Filter Rule
779
                                $objWriter->writeAttribute('val', $rule->getValue());
780
                                $objWriter->writeAttribute('percent', (($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0'));
781
                                $objWriter->writeAttribute('top', (($rule->getGrouping() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1' : '0'));
782
                            } else {
783
                                //    Filter, DateGroupItem or CustomFilter
784 2
                                $objWriter->startElement($rule->getRuleType());
785
786 2
                                if ($rule->getOperator() !== Rule::AUTOFILTER_COLUMN_RULE_EQUAL) {
787 1
                                    $objWriter->writeAttribute('operator', $rule->getOperator());
788
                                }
789 2
                                if ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DATEGROUP) {
790
                                    // Date Group filters
791 1
                                    foreach ($rule->getValue() as $key => $value) {
792 1
                                        if ($value > '') {
793 1
                                            $objWriter->writeAttribute($key, $value);
794
                                        }
795
                                    }
796 1
                                    $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping());
797
                                } else {
798 2
                                    $objWriter->writeAttribute('val', $rule->getValue());
799
                                }
800
801 2
                                $objWriter->endElement();
802
                            }
803
                        }
804
805 2
                        $objWriter->endElement();
806
807 2
                        $objWriter->endElement();
808
                    }
809
                }
810
            }
811 3
            $objWriter->endElement();
812
        }
813 60
    }
814
815
    /**
816
     * Write PageSetup.
817
     *
818
     * @param XMLWriter $objWriter XML Writer
819
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
820
     */
821 60
    private function writePageSetup(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
822
    {
823
        // pageSetup
824 60
        $objWriter->startElement('pageSetup');
825 60
        $objWriter->writeAttribute('paperSize', $pSheet->getPageSetup()->getPaperSize());
826 60
        $objWriter->writeAttribute('orientation', $pSheet->getPageSetup()->getOrientation());
827
828 60
        if ($pSheet->getPageSetup()->getScale() !== null) {
829 60
            $objWriter->writeAttribute('scale', $pSheet->getPageSetup()->getScale());
830
        }
831 60
        if ($pSheet->getPageSetup()->getFitToHeight() !== null) {
832 60
            $objWriter->writeAttribute('fitToHeight', $pSheet->getPageSetup()->getFitToHeight());
833
        } else {
834
            $objWriter->writeAttribute('fitToHeight', '0');
835
        }
836 60
        if ($pSheet->getPageSetup()->getFitToWidth() !== null) {
837 60
            $objWriter->writeAttribute('fitToWidth', $pSheet->getPageSetup()->getFitToWidth());
838
        } else {
839
            $objWriter->writeAttribute('fitToWidth', '0');
840
        }
841 60
        if ($pSheet->getPageSetup()->getFirstPageNumber() !== null) {
842
            $objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber());
843
            $objWriter->writeAttribute('useFirstPageNumber', '1');
844
        }
845
846 60
        $objWriter->endElement();
847 60
    }
848
849
    /**
850
     * Write Header / Footer.
851
     *
852
     * @param XMLWriter $objWriter XML Writer
853
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
854
     */
855 60
    private function writeHeaderFooter(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
856
    {
857
        // headerFooter
858 60
        $objWriter->startElement('headerFooter');
859 60
        $objWriter->writeAttribute('differentOddEven', ($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false'));
860 60
        $objWriter->writeAttribute('differentFirst', ($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false'));
861 60
        $objWriter->writeAttribute('scaleWithDoc', ($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false'));
862 60
        $objWriter->writeAttribute('alignWithMargins', ($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false'));
863
864 60
        $objWriter->writeElement('oddHeader', $pSheet->getHeaderFooter()->getOddHeader());
865 60
        $objWriter->writeElement('oddFooter', $pSheet->getHeaderFooter()->getOddFooter());
866 60
        $objWriter->writeElement('evenHeader', $pSheet->getHeaderFooter()->getEvenHeader());
867 60
        $objWriter->writeElement('evenFooter', $pSheet->getHeaderFooter()->getEvenFooter());
868 60
        $objWriter->writeElement('firstHeader', $pSheet->getHeaderFooter()->getFirstHeader());
869 60
        $objWriter->writeElement('firstFooter', $pSheet->getHeaderFooter()->getFirstFooter());
870 60
        $objWriter->endElement();
871 60
    }
872
873
    /**
874
     * Write Breaks.
875
     *
876
     * @param XMLWriter $objWriter XML Writer
877
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
878
     */
879 60
    private function writeBreaks(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
880
    {
881
        // Get row and column breaks
882 60
        $aRowBreaks = [];
883 60
        $aColumnBreaks = [];
884 60
        foreach ($pSheet->getBreaks() as $cell => $breakType) {
885 1
            if ($breakType == PhpspreadsheetWorksheet::BREAK_ROW) {
886 1
                $aRowBreaks[] = $cell;
887
            } elseif ($breakType == PhpspreadsheetWorksheet::BREAK_COLUMN) {
888 1
                $aColumnBreaks[] = $cell;
889
            }
890
        }
891
892
        // rowBreaks
893 60
        if (!empty($aRowBreaks)) {
894 1
            $objWriter->startElement('rowBreaks');
895 1
            $objWriter->writeAttribute('count', count($aRowBreaks));
896 1
            $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks));
897
898 1
            foreach ($aRowBreaks as $cell) {
899 1
                $coords = Coordinate::coordinateFromString($cell);
900
901 1
                $objWriter->startElement('brk');
902 1
                $objWriter->writeAttribute('id', $coords[1]);
903 1
                $objWriter->writeAttribute('man', '1');
904 1
                $objWriter->endElement();
905
            }
906
907 1
            $objWriter->endElement();
908
        }
909
910
        // Second, write column breaks
911 60
        if (!empty($aColumnBreaks)) {
912
            $objWriter->startElement('colBreaks');
913
            $objWriter->writeAttribute('count', count($aColumnBreaks));
914
            $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks));
915
916
            foreach ($aColumnBreaks as $cell) {
917
                $coords = Coordinate::coordinateFromString($cell);
918
919
                $objWriter->startElement('brk');
920
                $objWriter->writeAttribute('id', Coordinate::columnIndexFromString($coords[0]) - 1);
921
                $objWriter->writeAttribute('man', '1');
922
                $objWriter->endElement();
923
            }
924
925
            $objWriter->endElement();
926
        }
927 60
    }
928
929
    /**
930
     * Write SheetData.
931
     *
932
     * @param XMLWriter $objWriter XML Writer
933
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
934
     * @param string[] $pStringTable String table
935
     *
936
     * @throws WriterException
937
     */
938 60
    private function writeSheetData(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, array $pStringTable)
939
    {
940
        // Flipped stringtable, for faster index searching
941 60
        $aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->flipStringTable($pStringTable);
942
943
        // sheetData
944 60
        $objWriter->startElement('sheetData');
945
946
        // Get column count
947 60
        $colCount = Coordinate::columnIndexFromString($pSheet->getHighestColumn());
948
949
        // Highest row number
950 60
        $highestRow = $pSheet->getHighestRow();
951
952
        // Loop through cells
953 60
        $cellsByRow = [];
954 60
        foreach ($pSheet->getCoordinates() as $coordinate) {
955 59
            $cellAddress = Coordinate::coordinateFromString($coordinate);
956 59
            $cellsByRow[$cellAddress[1]][] = $coordinate;
957
        }
958
959 60
        $currentRow = 0;
960 60
        while ($currentRow++ < $highestRow) {
961
            // Get row dimension
962 60
            $rowDimension = $pSheet->getRowDimension($currentRow);
963
964
            // Write current row?
965 60
            $writeCurrentRow = isset($cellsByRow[$currentRow]) || $rowDimension->getRowHeight() >= 0 || $rowDimension->getVisible() == false || $rowDimension->getCollapsed() == true || $rowDimension->getOutlineLevel() > 0 || $rowDimension->getXfIndex() !== null;
966
967 60
            if ($writeCurrentRow) {
968
                // Start a new row
969 59
                $objWriter->startElement('row');
970 59
                $objWriter->writeAttribute('r', $currentRow);
971 59
                $objWriter->writeAttribute('spans', '1:' . $colCount);
972
973
                // Row dimensions
974 59
                if ($rowDimension->getRowHeight() >= 0) {
975 5
                    $objWriter->writeAttribute('customHeight', '1');
976 5
                    $objWriter->writeAttribute('ht', StringHelper::formatNumber($rowDimension->getRowHeight()));
977
                }
978
979
                // Row visibility
980 59
                if ($rowDimension->getVisible() == false) {
981 2
                    $objWriter->writeAttribute('hidden', 'true');
982
                }
983
984
                // Collapsed
985 59
                if ($rowDimension->getCollapsed() == true) {
986
                    $objWriter->writeAttribute('collapsed', 'true');
987
                }
988
989
                // Outline level
990 59
                if ($rowDimension->getOutlineLevel() > 0) {
991
                    $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel());
992
                }
993
994
                // Style
995 59
                if ($rowDimension->getXfIndex() !== null) {
996
                    $objWriter->writeAttribute('s', $rowDimension->getXfIndex());
997
                    $objWriter->writeAttribute('customFormat', '1');
998
                }
999
1000
                // Write cells
1001 59
                if (isset($cellsByRow[$currentRow])) {
1002 59
                    foreach ($cellsByRow[$currentRow] as $cellAddress) {
1003
                        // Write cell
1004 59
                        $this->writeCell($objWriter, $pSheet, $cellAddress, $aFlippedStringTable);
1005
                    }
1006
                }
1007
1008
                // End row
1009 59
                $objWriter->endElement();
1010
            }
1011
        }
1012
1013 60
        $objWriter->endElement();
1014 60
    }
1015
1016
    /**
1017
     * Write Cell.
1018
     *
1019
     * @param XMLWriter $objWriter XML Writer
1020
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1021
     * @param Cell $pCellAddress Cell Address
1022
     * @param string[] $pFlippedStringTable String table (flipped), for faster index searching
1023
     *
1024
     * @throws WriterException
1025
     */
1026 59
    private function writeCell(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, $pCellAddress, array $pFlippedStringTable)
1027
    {
1028
        // Cell
1029 59
        $pCell = $pSheet->getCell($pCellAddress);
1030 59
        $objWriter->startElement('c');
1031 59
        $objWriter->writeAttribute('r', $pCellAddress);
1032
1033
        // Sheet styles
1034 59
        if ($pCell->getXfIndex() != '') {
1035 32
            $objWriter->writeAttribute('s', $pCell->getXfIndex());
1036
        }
1037
1038
        // If cell value is supplied, write cell value
1039 59
        $cellValue = $pCell->getValue();
1040 59
        if (is_object($cellValue) || $cellValue !== '') {
1041
            // Map type
1042 59
            $mappedType = $pCell->getDataType();
1043
1044
            // Write data type depending on its type
1045 59
            switch (strtolower($mappedType)) {
1046 59
                case 'inlinestr':    // Inline string
1047 58
                case 's':            // String
1048 50
                case 'b':            // Boolean
1049 52
                    $objWriter->writeAttribute('t', $mappedType);
1050
1051 52
                    break;
1052 48
                case 'f':            // Formula
1053 18
                    $calculatedValue = ($this->getParentWriter()->getPreCalculateFormulas()) ?
1054 18
                        $pCell->getCalculatedValue() : $cellValue;
1055 18
                    if (is_string($calculatedValue)) {
1056 13
                        $objWriter->writeAttribute('t', 'str');
1057
                    }
1058
1059 18
                    break;
1060 47
                case 'e':            // Error
1061
                    $objWriter->writeAttribute('t', $mappedType);
1062
            }
1063
1064
            // Write data depending on its type
1065 59
            switch (strtolower($mappedType)) {
1066 59
                case 'inlinestr':    // Inline string
1067 8
                    if (!$cellValue instanceof RichText) {
1068
                        $objWriter->writeElement('t', StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue)));
1069 8
                    } elseif ($cellValue instanceof RichText) {
1070 8
                        $objWriter->startElement('is');
1071 8
                        $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $cellValue);
1072 8
                        $objWriter->endElement();
1073
                    }
1074
1075 8
                    break;
1076 58
                case 's':            // String
1077 51
                    if (!$cellValue instanceof RichText) {
1078 51
                        if (isset($pFlippedStringTable[$cellValue])) {
1079 51
                            $objWriter->writeElement('v', $pFlippedStringTable[$cellValue]);
1080
                        }
1081 2
                    } elseif ($cellValue instanceof RichText) {
1082 2
                        $objWriter->writeElement('v', $pFlippedStringTable[$cellValue->getHashCode()]);
1083
                    }
1084
1085 51
                    break;
1086 50
                case 'f':            // Formula
1087 18
                    $attributes = $pCell->getFormulaAttributes();
1088 18
                    if ($attributes['t'] == 'array') {
1089
                        $objWriter->startElement('f');
1090
                        $objWriter->writeAttribute('t', 'array');
1091
                        $objWriter->writeAttribute('ref', $pCellAddress);
1092
                        $objWriter->writeAttribute('aca', '1');
1093
                        $objWriter->writeAttribute('ca', '1');
1094
                        $objWriter->text(substr($cellValue, 1));
1095
                        $objWriter->endElement();
1096
                    } else {
1097 18
                        $objWriter->writeElement('f', substr($cellValue, 1));
1098
                    }
1099 18
                    if ($this->getParentWriter()->getOffice2003Compatibility() === false) {
1100 18
                        if ($this->getParentWriter()->getPreCalculateFormulas()) {
1101 18
                            if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') {
1102 18
                                $objWriter->writeElement('v', StringHelper::formatNumber($calculatedValue));
1103
                            } else {
1104 18
                                $objWriter->writeElement('v', '0');
1105
                            }
1106
                        } else {
1107
                            $objWriter->writeElement('v', '0');
1108
                        }
1109
                    }
1110
1111 18
                    break;
1112 49
                case 'n':            // Numeric
1113
                    // force point as decimal separator in case current locale uses comma
1114 41
                    $objWriter->writeElement('v', str_replace(',', '.', $cellValue));
1115
1116 41
                    break;
1117 26
                case 'b':            // Boolean
1118 8
                    $objWriter->writeElement('v', ($cellValue ? '1' : '0'));
1119
1120 8
                    break;
1121 22
                case 'e':            // Error
1122
                    if (substr($cellValue, 0, 1) == '=') {
1123
                        $objWriter->writeElement('f', substr($cellValue, 1));
1124
                        $objWriter->writeElement('v', substr($cellValue, 1));
1125
                    } else {
1126
                        $objWriter->writeElement('v', $cellValue);
1127
                    }
1128
1129
                    break;
1130
            }
1131
        }
1132
1133 59
        $objWriter->endElement();
1134 59
    }
1135
1136
    /**
1137
     * Write Drawings.
1138
     *
1139
     * @param XMLWriter $objWriter XML Writer
1140
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1141
     * @param bool $includeCharts Flag indicating if we should include drawing details for charts
1142
     */
1143 60
    private function writeDrawings(XMLWriter $objWriter = null, PhpspreadsheetWorksheet $pSheet = null, $includeCharts = false)
1144
    {
1145 60
        $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0;
1146
        // If sheet contains drawings, add the relationships
1147 60
        if (($pSheet->getDrawingCollection()->count() > 0) ||
1148 60
            ($chartCount > 0)) {
1149 22
            $objWriter->startElement('drawing');
1150 22
            $objWriter->writeAttribute('r:id', 'rId1');
1151 22
            $objWriter->endElement();
1152
        }
1153 60
    }
1154
1155
    /**
1156
     * Write LegacyDrawing.
1157
     *
1158
     * @param XMLWriter $objWriter XML Writer
1159
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1160
     */
1161 60
    private function writeLegacyDrawing(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
1162
    {
1163
        // If sheet contains comments, add the relationships
1164 60
        if (count($pSheet->getComments()) > 0) {
1165 9
            $objWriter->startElement('legacyDrawing');
1166 9
            $objWriter->writeAttribute('r:id', 'rId_comments_vml1');
1167 9
            $objWriter->endElement();
1168
        }
1169 60
    }
1170
1171
    /**
1172
     * Write LegacyDrawingHF.
1173
     *
1174
     * @param XMLWriter $objWriter XML Writer
1175
     * @param PhpspreadsheetWorksheet $pSheet Worksheet
1176
     */
1177 60
    private function writeLegacyDrawingHF(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
1178
    {
1179
        // If sheet contains images, add the relationships
1180 60
        if (count($pSheet->getHeaderFooter()->getImages()) > 0) {
1181 1
            $objWriter->startElement('legacyDrawingHF');
1182 1
            $objWriter->writeAttribute('r:id', 'rId_headerfooter_vml1');
1183 1
            $objWriter->endElement();
1184
        }
1185 60
    }
1186
}
1187