ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Worksheet.php
Go to the documentation of this file.
1<?php
2
4
16use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet as PhpspreadsheetWorksheet;
17
18class Worksheet extends WriterPart
19{
28 public function writeWorksheet(PhpspreadsheetWorksheet $pSheet, $pStringTable = null, $includeCharts = false)
29 {
30 // Create XML writer
31 $objWriter = null;
32 if ($this->getParentWriter()->getUseDiskCaching()) {
34 } else {
35 $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
36 }
37
38 // XML header
39 $objWriter->startDocument('1.0', 'UTF-8', 'yes');
40
41 // Worksheet
42 $objWriter->startElement('worksheet');
43 $objWriter->writeAttribute('xml:space', 'preserve');
44 $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
45 $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
46
47 $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing');
48 $objWriter->writeAttribute('xmlns:x14', 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/main');
49 $objWriter->writeAttribute('xmlns:xm', 'http://schemas.microsoft.com/office/excel/2006/main');
50 $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006');
51 $objWriter->writeAttribute('mc:Ignorable', 'x14ac');
52 $objWriter->writeAttribute('xmlns:x14ac', 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac');
53
54 // sheetPr
55 $this->writeSheetPr($objWriter, $pSheet);
56
57 // Dimension
58 $this->writeDimension($objWriter, $pSheet);
59
60 // sheetViews
61 $this->writeSheetViews($objWriter, $pSheet);
62
63 // sheetFormatPr
64 $this->writeSheetFormatPr($objWriter, $pSheet);
65
66 // cols
67 $this->writeCols($objWriter, $pSheet);
68
69 // sheetData
70 $this->writeSheetData($objWriter, $pSheet, $pStringTable);
71
72 // sheetProtection
73 $this->writeSheetProtection($objWriter, $pSheet);
74
75 // protectedRanges
76 $this->writeProtectedRanges($objWriter, $pSheet);
77
78 // autoFilter
79 $this->writeAutoFilter($objWriter, $pSheet);
80
81 // mergeCells
82 $this->writeMergeCells($objWriter, $pSheet);
83
84 // conditionalFormatting
85 $this->writeConditionalFormatting($objWriter, $pSheet);
86
87 // dataValidations
88 $this->writeDataValidations($objWriter, $pSheet);
89
90 // hyperlinks
91 $this->writeHyperlinks($objWriter, $pSheet);
92
93 // Print options
94 $this->writePrintOptions($objWriter, $pSheet);
95
96 // Page margins
97 $this->writePageMargins($objWriter, $pSheet);
98
99 // Page setup
100 $this->writePageSetup($objWriter, $pSheet);
101
102 // Header / footer
103 $this->writeHeaderFooter($objWriter, $pSheet);
104
105 // Breaks
106 $this->writeBreaks($objWriter, $pSheet);
107
108 // Drawings and/or Charts
109 $this->writeDrawings($objWriter, $pSheet, $includeCharts);
110
111 // LegacyDrawing
112 $this->writeLegacyDrawing($objWriter, $pSheet);
113
114 // LegacyDrawingHF
115 $this->writeLegacyDrawingHF($objWriter, $pSheet);
116
117 // AlternateContent
118 $this->writeAlternateContent($objWriter, $pSheet);
119
120 // ConditionalFormattingRuleExtensionList
121 // (Must be inserted last. Not insert last, an Excel parse error will occur)
122 $this->writeExtLst($objWriter, $pSheet);
123
124 $objWriter->endElement();
125
126 // Return
127 return $objWriter->getData();
128 }
129
136 private function writeSheetPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
137 {
138 // sheetPr
139 $objWriter->startElement('sheetPr');
140 if ($pSheet->getParent()->hasMacros()) {
141 //if the workbook have macros, we need to have codeName for the sheet
142 if (!$pSheet->hasCodeName()) {
143 $pSheet->setCodeName($pSheet->getTitle());
144 }
145 $objWriter->writeAttribute('codeName', $pSheet->getCodeName());
146 }
147 $autoFilterRange = $pSheet->getAutoFilter()->getRange();
148 if (!empty($autoFilterRange)) {
149 $objWriter->writeAttribute('filterMode', 1);
150 $pSheet->getAutoFilter()->showHideRows();
151 }
152
153 // tabColor
154 if ($pSheet->isTabColorSet()) {
155 $objWriter->startElement('tabColor');
156 $objWriter->writeAttribute('rgb', $pSheet->getTabColor()->getARGB());
157 $objWriter->endElement();
158 }
159
160 // outlinePr
161 $objWriter->startElement('outlinePr');
162 $objWriter->writeAttribute('summaryBelow', ($pSheet->getShowSummaryBelow() ? '1' : '0'));
163 $objWriter->writeAttribute('summaryRight', ($pSheet->getShowSummaryRight() ? '1' : '0'));
164 $objWriter->endElement();
165
166 // pageSetUpPr
167 if ($pSheet->getPageSetup()->getFitToPage()) {
168 $objWriter->startElement('pageSetUpPr');
169 $objWriter->writeAttribute('fitToPage', '1');
170 $objWriter->endElement();
171 }
172
173 $objWriter->endElement();
174 }
175
182 private function writeDimension(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
183 {
184 // dimension
185 $objWriter->startElement('dimension');
186 $objWriter->writeAttribute('ref', $pSheet->calculateWorksheetDimension());
187 $objWriter->endElement();
188 }
189
196 private function writeSheetViews(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
197 {
198 // sheetViews
199 $objWriter->startElement('sheetViews');
200
201 // Sheet selected?
202 $sheetSelected = false;
203 if ($this->getParentWriter()->getSpreadsheet()->getIndex($pSheet) == $this->getParentWriter()->getSpreadsheet()->getActiveSheetIndex()) {
204 $sheetSelected = true;
205 }
206
207 // sheetView
208 $objWriter->startElement('sheetView');
209 $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0');
210 $objWriter->writeAttribute('workbookViewId', '0');
211
212 // Zoom scales
213 if ($pSheet->getSheetView()->getZoomScale() != 100) {
214 $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale());
215 }
216 if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) {
217 $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal());
218 }
219
220 // Show zeros (Excel also writes this attribute only if set to false)
221 if ($pSheet->getSheetView()->getShowZeros() === false) {
222 $objWriter->writeAttribute('showZeros', 0);
223 }
224
225 // View Layout Type
226 if ($pSheet->getSheetView()->getView() !== SheetView::SHEETVIEW_NORMAL) {
227 $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView());
228 }
229
230 // Gridlines
231 if ($pSheet->getShowGridlines()) {
232 $objWriter->writeAttribute('showGridLines', 'true');
233 } else {
234 $objWriter->writeAttribute('showGridLines', 'false');
235 }
236
237 // Row and column headers
238 if ($pSheet->getShowRowColHeaders()) {
239 $objWriter->writeAttribute('showRowColHeaders', '1');
240 } else {
241 $objWriter->writeAttribute('showRowColHeaders', '0');
242 }
243
244 // Right-to-left
245 if ($pSheet->getRightToLeft()) {
246 $objWriter->writeAttribute('rightToLeft', 'true');
247 }
248
249 $activeCell = $pSheet->getActiveCell();
250 $sqref = $pSheet->getSelectedCells();
251
252 // Pane
253 $pane = '';
254 if ($pSheet->getFreezePane()) {
255 [$xSplit, $ySplit] = Coordinate::coordinateFromString($pSheet->getFreezePane());
256 $xSplit = Coordinate::columnIndexFromString($xSplit);
257 --$xSplit;
258 --$ySplit;
259
260 $topLeftCell = $pSheet->getTopLeftCell();
261
262 // pane
263 $pane = 'topRight';
264 $objWriter->startElement('pane');
265 if ($xSplit > 0) {
266 $objWriter->writeAttribute('xSplit', $xSplit);
267 }
268 if ($ySplit > 0) {
269 $objWriter->writeAttribute('ySplit', $ySplit);
270 $pane = ($xSplit > 0) ? 'bottomRight' : 'bottomLeft';
271 }
272 $objWriter->writeAttribute('topLeftCell', $topLeftCell);
273 $objWriter->writeAttribute('activePane', $pane);
274 $objWriter->writeAttribute('state', 'frozen');
275 $objWriter->endElement();
276
277 if (($xSplit > 0) && ($ySplit > 0)) {
278 // Write additional selections if more than two panes (ie both an X and a Y split)
279 $objWriter->startElement('selection');
280 $objWriter->writeAttribute('pane', 'topRight');
281 $objWriter->endElement();
282 $objWriter->startElement('selection');
283 $objWriter->writeAttribute('pane', 'bottomLeft');
284 $objWriter->endElement();
285 }
286 }
287
288 // Selection
289 // Only need to write selection element if we have a split pane
290 // We cheat a little by over-riding the active cell selection, setting it to the split cell
291 $objWriter->startElement('selection');
292 if ($pane != '') {
293 $objWriter->writeAttribute('pane', $pane);
294 }
295 $objWriter->writeAttribute('activeCell', $activeCell);
296 $objWriter->writeAttribute('sqref', $sqref);
297 $objWriter->endElement();
298
299 $objWriter->endElement();
300
301 $objWriter->endElement();
302 }
303
310 private function writeSheetFormatPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
311 {
312 // sheetFormatPr
313 $objWriter->startElement('sheetFormatPr');
314
315 // Default row height
316 if ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) {
317 $objWriter->writeAttribute('customHeight', 'true');
318 $objWriter->writeAttribute('defaultRowHeight', StringHelper::formatNumber($pSheet->getDefaultRowDimension()->getRowHeight()));
319 } else {
320 $objWriter->writeAttribute('defaultRowHeight', '14.4');
321 }
322
323 // Set Zero Height row
324 if (
325 (string) $pSheet->getDefaultRowDimension()->getZeroHeight() === '1' ||
326 strtolower((string) $pSheet->getDefaultRowDimension()->getZeroHeight()) == 'true'
327 ) {
328 $objWriter->writeAttribute('zeroHeight', '1');
329 }
330
331 // Default column width
332 if ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) {
333 $objWriter->writeAttribute('defaultColWidth', StringHelper::formatNumber($pSheet->getDefaultColumnDimension()->getWidth()));
334 }
335
336 // Outline level - row
337 $outlineLevelRow = 0;
338 foreach ($pSheet->getRowDimensions() as $dimension) {
339 if ($dimension->getOutlineLevel() > $outlineLevelRow) {
340 $outlineLevelRow = $dimension->getOutlineLevel();
341 }
342 }
343 $objWriter->writeAttribute('outlineLevelRow', (int) $outlineLevelRow);
344
345 // Outline level - column
346 $outlineLevelCol = 0;
347 foreach ($pSheet->getColumnDimensions() as $dimension) {
348 if ($dimension->getOutlineLevel() > $outlineLevelCol) {
349 $outlineLevelCol = $dimension->getOutlineLevel();
350 }
351 }
352 $objWriter->writeAttribute('outlineLevelCol', (int) $outlineLevelCol);
353
354 $objWriter->endElement();
355 }
356
363 private function writeCols(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
364 {
365 // cols
366 if (count($pSheet->getColumnDimensions()) > 0) {
367 $objWriter->startElement('cols');
368
369 $pSheet->calculateColumnWidths();
370
371 // Loop through column dimensions
372 foreach ($pSheet->getColumnDimensions() as $colDimension) {
373 // col
374 $objWriter->startElement('col');
375 $objWriter->writeAttribute('min', Coordinate::columnIndexFromString($colDimension->getColumnIndex()));
376 $objWriter->writeAttribute('max', Coordinate::columnIndexFromString($colDimension->getColumnIndex()));
377
378 if ($colDimension->getWidth() < 0) {
379 // No width set, apply default of 10
380 $objWriter->writeAttribute('width', '9.10');
381 } else {
382 // Width set
383 $objWriter->writeAttribute('width', StringHelper::formatNumber($colDimension->getWidth()));
384 }
385
386 // Column visibility
387 if ($colDimension->getVisible() === false) {
388 $objWriter->writeAttribute('hidden', 'true');
389 }
390
391 // Auto size?
392 if ($colDimension->getAutoSize()) {
393 $objWriter->writeAttribute('bestFit', 'true');
394 }
395
396 // Custom width?
397 if ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) {
398 $objWriter->writeAttribute('customWidth', 'true');
399 }
400
401 // Collapsed
402 if ($colDimension->getCollapsed() === true) {
403 $objWriter->writeAttribute('collapsed', 'true');
404 }
405
406 // Outline level
407 if ($colDimension->getOutlineLevel() > 0) {
408 $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel());
409 }
410
411 // Style
412 $objWriter->writeAttribute('style', $colDimension->getXfIndex());
413
414 $objWriter->endElement();
415 }
416
417 $objWriter->endElement();
418 }
419 }
420
427 private function writeSheetProtection(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
428 {
429 // sheetProtection
430 $objWriter->startElement('sheetProtection');
431
432 $protection = $pSheet->getProtection();
433
434 if ($protection->getAlgorithm()) {
435 $objWriter->writeAttribute('algorithmName', $protection->getAlgorithm());
436 $objWriter->writeAttribute('hashValue', $protection->getPassword());
437 $objWriter->writeAttribute('saltValue', $protection->getSalt());
438 $objWriter->writeAttribute('spinCount', $protection->getSpinCount());
439 } elseif ($protection->getPassword() !== '') {
440 $objWriter->writeAttribute('password', $protection->getPassword());
441 }
442
443 $objWriter->writeAttribute('sheet', ($protection->getSheet() ? 'true' : 'false'));
444 $objWriter->writeAttribute('objects', ($protection->getObjects() ? 'true' : 'false'));
445 $objWriter->writeAttribute('scenarios', ($protection->getScenarios() ? 'true' : 'false'));
446 $objWriter->writeAttribute('formatCells', ($protection->getFormatCells() ? 'true' : 'false'));
447 $objWriter->writeAttribute('formatColumns', ($protection->getFormatColumns() ? 'true' : 'false'));
448 $objWriter->writeAttribute('formatRows', ($protection->getFormatRows() ? 'true' : 'false'));
449 $objWriter->writeAttribute('insertColumns', ($protection->getInsertColumns() ? 'true' : 'false'));
450 $objWriter->writeAttribute('insertRows', ($protection->getInsertRows() ? 'true' : 'false'));
451 $objWriter->writeAttribute('insertHyperlinks', ($protection->getInsertHyperlinks() ? 'true' : 'false'));
452 $objWriter->writeAttribute('deleteColumns', ($protection->getDeleteColumns() ? 'true' : 'false'));
453 $objWriter->writeAttribute('deleteRows', ($protection->getDeleteRows() ? 'true' : 'false'));
454 $objWriter->writeAttribute('selectLockedCells', ($protection->getSelectLockedCells() ? 'true' : 'false'));
455 $objWriter->writeAttribute('sort', ($protection->getSort() ? 'true' : 'false'));
456 $objWriter->writeAttribute('autoFilter', ($protection->getAutoFilter() ? 'true' : 'false'));
457 $objWriter->writeAttribute('pivotTables', ($protection->getPivotTables() ? 'true' : 'false'));
458 $objWriter->writeAttribute('selectUnlockedCells', ($protection->getSelectUnlockedCells() ? 'true' : 'false'));
459 $objWriter->endElement();
460 }
461
462 private static function writeAttributeIf(XMLWriter $objWriter, $condition, string $attr, string $val): void
463 {
464 if ($condition) {
465 $objWriter->writeAttribute($attr, $val);
466 }
467 }
468
469 private static function writeElementIf(XMLWriter $objWriter, $condition, string $attr, string $val): void
470 {
471 if ($condition) {
472 $objWriter->writeElement($attr, $val);
473 }
474 }
475
476 private static function writeOtherCondElements(XMLWriter $objWriter, Conditional $conditional, string $cellCoordinate): void
477 {
478 if (
479 $conditional->getConditionType() == Conditional::CONDITION_CELLIS
480 || $conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
481 || $conditional->getConditionType() == Conditional::CONDITION_EXPRESSION
482 ) {
483 foreach ($conditional->getConditions() as $formula) {
484 // Formula
485 $objWriter->writeElement('formula', Xlfn::addXlfn($formula));
486 }
487 } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSBLANKS) {
488 // formula copied from ms xlsx xml source file
489 $objWriter->writeElement('formula', 'LEN(TRIM(' . $cellCoordinate . '))=0');
490 } elseif ($conditional->getConditionType() == Conditional::CONDITION_NOTCONTAINSBLANKS) {
491 // formula copied from ms xlsx xml source file
492 $objWriter->writeElement('formula', 'LEN(TRIM(' . $cellCoordinate . '))>0');
493 }
494 }
495
496 private static function writeTextCondElements(XMLWriter $objWriter, Conditional $conditional, string $cellCoordinate): void
497 {
498 $txt = $conditional->getText();
499 if ($txt !== null) {
500 $objWriter->writeAttribute('text', $txt);
501 if ($conditional->getOperatorType() == Conditional::OPERATOR_CONTAINSTEXT) {
502 $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $txt . '",' . $cellCoordinate . ')))');
503 } elseif ($conditional->getOperatorType() == Conditional::OPERATOR_BEGINSWITH) {
504 $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($txt) . ')="' . $txt . '"');
505 } elseif ($conditional->getOperatorType() == Conditional::OPERATOR_ENDSWITH) {
506 $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($txt) . ')="' . $txt . '"');
507 } elseif ($conditional->getOperatorType() == Conditional::OPERATOR_NOTCONTAINS) {
508 $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $txt . '",' . $cellCoordinate . '))');
509 }
510 }
511 }
512
513 private static function writeExtConditionalFormattingElements(XMLWriter $objWriter, ConditionalFormattingRuleExtension $ruleExtension): void
514 {
515 $prefix = 'x14';
516 $objWriter->startElementNs($prefix, 'conditionalFormatting', null);
517
518 $objWriter->startElementNs($prefix, 'cfRule', null);
519 $objWriter->writeAttribute('type', $ruleExtension->getCfRule());
520 $objWriter->writeAttribute('id', $ruleExtension->getId());
521 $objWriter->startElementNs($prefix, 'dataBar', null);
522 $dataBar = $ruleExtension->getDataBarExt();
523 foreach ($dataBar->getXmlAttributes() as $attrKey => $val) {
524 $objWriter->writeAttribute($attrKey, $val);
525 }
526 $minCfvo = $dataBar->getMinimumConditionalFormatValueObject();
527 if ($minCfvo) {
528 $objWriter->startElementNs($prefix, 'cfvo', null);
529 $objWriter->writeAttribute('type', $minCfvo->getType());
530 if ($minCfvo->getCellFormula()) {
531 $objWriter->writeElement('xm:f', $minCfvo->getCellFormula());
532 }
533 $objWriter->endElement(); //end cfvo
534 }
535
536 $maxCfvo = $dataBar->getMaximumConditionalFormatValueObject();
537 if ($maxCfvo) {
538 $objWriter->startElementNs($prefix, 'cfvo', null);
539 $objWriter->writeAttribute('type', $maxCfvo->getType());
540 if ($maxCfvo->getCellFormula()) {
541 $objWriter->writeElement('xm:f', $maxCfvo->getCellFormula());
542 }
543 $objWriter->endElement(); //end cfvo
544 }
545
546 foreach ($dataBar->getXmlElements() as $elmKey => $elmAttr) {
547 $objWriter->startElementNs($prefix, $elmKey, null);
548 foreach ($elmAttr as $attrKey => $attrVal) {
549 $objWriter->writeAttribute($attrKey, $attrVal);
550 }
551 $objWriter->endElement(); //end elmKey
552 }
553 $objWriter->endElement(); //end dataBar
554 $objWriter->endElement(); //end cfRule
555 $objWriter->writeElement('xm:sqref', $ruleExtension->getSqref());
556 $objWriter->endElement(); //end conditionalFormatting
557 }
558
559 private static function writeDataBarElements(XMLWriter $objWriter, $dataBar): void
560 {
562 if ($dataBar) {
563 $objWriter->startElement('dataBar');
564 self::writeAttributeIf($objWriter, null !== $dataBar->getShowValue(), 'showValue', $dataBar->getShowValue() ? '1' : '0');
565
566 $minCfvo = $dataBar->getMinimumConditionalFormatValueObject();
567 if ($minCfvo) {
568 $objWriter->startElement('cfvo');
569 self::writeAttributeIf($objWriter, $minCfvo->getType(), 'type', (string) $minCfvo->getType());
570 self::writeAttributeIf($objWriter, $minCfvo->getValue(), 'val', (string) $minCfvo->getValue());
571 $objWriter->endElement();
572 }
573 $maxCfvo = $dataBar->getMaximumConditionalFormatValueObject();
574 if ($maxCfvo) {
575 $objWriter->startElement('cfvo');
576 self::writeAttributeIf($objWriter, $maxCfvo->getType(), 'type', (string) $maxCfvo->getType());
577 self::writeAttributeIf($objWriter, $maxCfvo->getValue(), 'val', (string) $maxCfvo->getValue());
578 $objWriter->endElement();
579 }
580 if ($dataBar->getColor()) {
581 $objWriter->startElement('color');
582 $objWriter->writeAttribute('rgb', $dataBar->getColor());
583 $objWriter->endElement();
584 }
585 $objWriter->endElement(); // end dataBar
586
587 if ($dataBar->getConditionalFormattingRuleExt()) {
588 $objWriter->startElement('extLst');
589 $extension = $dataBar->getConditionalFormattingRuleExt();
590 $objWriter->startElement('ext');
591 $objWriter->writeAttribute('uri', '{B025F937-C7B1-47D3-B67F-A62EFF666E3E}');
592 $objWriter->startElementNs('x14', 'id', null);
593 $objWriter->text($extension->getId());
594 $objWriter->endElement();
595 $objWriter->endElement();
596 $objWriter->endElement(); //end extLst
597 }
598 }
599 }
600
607 private function writeConditionalFormatting(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
608 {
609 // Conditional id
610 $id = 1;
611
612 // Loop through styles in the current worksheet
613 foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) {
614 foreach ($conditionalStyles as $conditional) {
615 // WHY was this again?
616 // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()) == '') {
617 // continue;
618 // }
619 if ($conditional->getConditionType() != Conditional::CONDITION_NONE) {
620 // conditionalFormatting
621 $objWriter->startElement('conditionalFormatting');
622 $objWriter->writeAttribute('sqref', $cellCoordinate);
623
624 // cfRule
625 $objWriter->startElement('cfRule');
626 $objWriter->writeAttribute('type', $conditional->getConditionType());
627 self::writeAttributeIf(
628 $objWriter,
629 ($conditional->getConditionType() != Conditional::CONDITION_DATABAR),
630 'dxfId',
631 $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode())
632 );
633 $objWriter->writeAttribute('priority', $id++);
634
635 self::writeAttributeif(
636 $objWriter,
637 (
638 $conditional->getConditionType() === Conditional::CONDITION_CELLIS
639 || $conditional->getConditionType() === Conditional::CONDITION_CONTAINSTEXT
640 || $conditional->getConditionType() === Conditional::CONDITION_NOTCONTAINSTEXT
641 ) && $conditional->getOperatorType() !== Conditional::OPERATOR_NONE,
642 'operator',
643 $conditional->getOperatorType()
644 );
645
646 self::writeAttributeIf($objWriter, $conditional->getStopIfTrue(), 'stopIfTrue', '1');
647
648 if (
649 $conditional->getConditionType() === Conditional::CONDITION_CONTAINSTEXT
650 || $conditional->getConditionType() === Conditional::CONDITION_NOTCONTAINSTEXT
651 ) {
652 self::writeTextCondElements($objWriter, $conditional, $cellCoordinate);
653 } else {
654 self::writeOtherCondElements($objWriter, $conditional, $cellCoordinate);
655 }
656
657 //<dataBar>
658 self::writeDataBarElements($objWriter, $conditional->getDataBar());
659
660 $objWriter->endElement(); //end cfRule
661
662 $objWriter->endElement();
663 }
664 }
665 }
666 }
667
674 private function writeDataValidations(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
675 {
676 // Datavalidation collection
677 $dataValidationCollection = $pSheet->getDataValidationCollection();
678
679 // Write data validations?
680 if (!empty($dataValidationCollection)) {
681 $dataValidationCollection = Coordinate::mergeRangesInCollection($dataValidationCollection);
682 $objWriter->startElement('dataValidations');
683 $objWriter->writeAttribute('count', count($dataValidationCollection));
684
685 foreach ($dataValidationCollection as $coordinate => $dv) {
686 $objWriter->startElement('dataValidation');
687
688 if ($dv->getType() != '') {
689 $objWriter->writeAttribute('type', $dv->getType());
690 }
691
692 if ($dv->getErrorStyle() != '') {
693 $objWriter->writeAttribute('errorStyle', $dv->getErrorStyle());
694 }
695
696 if ($dv->getOperator() != '') {
697 $objWriter->writeAttribute('operator', $dv->getOperator());
698 }
699
700 $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0'));
701 $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0'));
702 $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0'));
703 $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0'));
704
705 if ($dv->getErrorTitle() !== '') {
706 $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle());
707 }
708 if ($dv->getError() !== '') {
709 $objWriter->writeAttribute('error', $dv->getError());
710 }
711 if ($dv->getPromptTitle() !== '') {
712 $objWriter->writeAttribute('promptTitle', $dv->getPromptTitle());
713 }
714 if ($dv->getPrompt() !== '') {
715 $objWriter->writeAttribute('prompt', $dv->getPrompt());
716 }
717
718 $objWriter->writeAttribute('sqref', $coordinate);
719
720 if ($dv->getFormula1() !== '') {
721 $objWriter->writeElement('formula1', $dv->getFormula1());
722 }
723 if ($dv->getFormula2() !== '') {
724 $objWriter->writeElement('formula2', $dv->getFormula2());
725 }
726
727 $objWriter->endElement();
728 }
729
730 $objWriter->endElement();
731 }
732 }
733
740 private function writeHyperlinks(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
741 {
742 // Hyperlink collection
743 $hyperlinkCollection = $pSheet->getHyperlinkCollection();
744
745 // Relation ID
746 $relationId = 1;
747
748 // Write hyperlinks?
749 if (!empty($hyperlinkCollection)) {
750 $objWriter->startElement('hyperlinks');
751
752 foreach ($hyperlinkCollection as $coordinate => $hyperlink) {
753 $objWriter->startElement('hyperlink');
754
755 $objWriter->writeAttribute('ref', $coordinate);
756 if (!$hyperlink->isInternal()) {
757 $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId);
758 ++$relationId;
759 } else {
760 $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl()));
761 }
762
763 if ($hyperlink->getTooltip() !== '') {
764 $objWriter->writeAttribute('tooltip', $hyperlink->getTooltip());
765 $objWriter->writeAttribute('display', $hyperlink->getTooltip());
766 }
767
768 $objWriter->endElement();
769 }
770
771 $objWriter->endElement();
772 }
773 }
774
781 private function writeProtectedRanges(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
782 {
783 if (count($pSheet->getProtectedCells()) > 0) {
784 // protectedRanges
785 $objWriter->startElement('protectedRanges');
786
787 // Loop protectedRanges
788 foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) {
789 // protectedRange
790 $objWriter->startElement('protectedRange');
791 $objWriter->writeAttribute('name', 'p' . md5($protectedCell));
792 $objWriter->writeAttribute('sqref', $protectedCell);
793 if (!empty($passwordHash)) {
794 $objWriter->writeAttribute('password', $passwordHash);
795 }
796 $objWriter->endElement();
797 }
798
799 $objWriter->endElement();
800 }
801 }
802
809 private function writeMergeCells(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
810 {
811 if (count($pSheet->getMergeCells()) > 0) {
812 // mergeCells
813 $objWriter->startElement('mergeCells');
814
815 // Loop mergeCells
816 foreach ($pSheet->getMergeCells() as $mergeCell) {
817 // mergeCell
818 $objWriter->startElement('mergeCell');
819 $objWriter->writeAttribute('ref', $mergeCell);
820 $objWriter->endElement();
821 }
822
823 $objWriter->endElement();
824 }
825 }
826
833 private function writePrintOptions(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
834 {
835 // printOptions
836 $objWriter->startElement('printOptions');
837
838 $objWriter->writeAttribute('gridLines', ($pSheet->getPrintGridlines() ? 'true' : 'false'));
839 $objWriter->writeAttribute('gridLinesSet', 'true');
840
841 if ($pSheet->getPageSetup()->getHorizontalCentered()) {
842 $objWriter->writeAttribute('horizontalCentered', 'true');
843 }
844
845 if ($pSheet->getPageSetup()->getVerticalCentered()) {
846 $objWriter->writeAttribute('verticalCentered', 'true');
847 }
848
849 $objWriter->endElement();
850 }
851
858 private function writePageMargins(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
859 {
860 // pageMargins
861 $objWriter->startElement('pageMargins');
862 $objWriter->writeAttribute('left', StringHelper::formatNumber($pSheet->getPageMargins()->getLeft()));
863 $objWriter->writeAttribute('right', StringHelper::formatNumber($pSheet->getPageMargins()->getRight()));
864 $objWriter->writeAttribute('top', StringHelper::formatNumber($pSheet->getPageMargins()->getTop()));
865 $objWriter->writeAttribute('bottom', StringHelper::formatNumber($pSheet->getPageMargins()->getBottom()));
866 $objWriter->writeAttribute('header', StringHelper::formatNumber($pSheet->getPageMargins()->getHeader()));
867 $objWriter->writeAttribute('footer', StringHelper::formatNumber($pSheet->getPageMargins()->getFooter()));
868 $objWriter->endElement();
869 }
870
877 private function writeAutoFilter(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
878 {
879 $autoFilterRange = $pSheet->getAutoFilter()->getRange();
880 if (!empty($autoFilterRange)) {
881 // autoFilter
882 $objWriter->startElement('autoFilter');
883
884 // Strip any worksheet reference from the filter coordinates
885 $range = Coordinate::splitRange($autoFilterRange);
886 $range = $range[0];
887 // Strip any worksheet ref
888 [$ws, $range[0]] = PhpspreadsheetWorksheet::extractSheetTitle($range[0], true);
889 $range = implode(':', $range);
890
891 $objWriter->writeAttribute('ref', str_replace('$', '', $range));
892
893 $columns = $pSheet->getAutoFilter()->getColumns();
894 if (count($columns) > 0) {
895 foreach ($columns as $columnID => $column) {
896 $rules = $column->getRules();
897 if (count($rules) > 0) {
898 $objWriter->startElement('filterColumn');
899 $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID));
900
901 $objWriter->startElement($column->getFilterType());
902 if ($column->getJoin() == Column::AUTOFILTER_COLUMN_JOIN_AND) {
903 $objWriter->writeAttribute('and', 1);
904 }
905
906 foreach ($rules as $rule) {
907 if (
908 ($column->getFilterType() === Column::AUTOFILTER_FILTERTYPE_FILTER) &&
909 ($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_EQUAL) &&
910 ($rule->getValue() === '')
911 ) {
912 // Filter rule for Blanks
913 $objWriter->writeAttribute('blank', 1);
914 } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) {
915 // Dynamic Filter Rule
916 $objWriter->writeAttribute('type', $rule->getGrouping());
917 $val = $column->getAttribute('val');
918 if ($val !== null) {
919 $objWriter->writeAttribute('val', $val);
920 }
921 $maxVal = $column->getAttribute('maxVal');
922 if ($maxVal !== null) {
923 $objWriter->writeAttribute('maxVal', $maxVal);
924 }
925 } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) {
926 // Top 10 Filter Rule
927 $objWriter->writeAttribute('val', $rule->getValue());
928 $objWriter->writeAttribute('percent', (($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0'));
929 $objWriter->writeAttribute('top', (($rule->getGrouping() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1' : '0'));
930 } else {
931 // Filter, DateGroupItem or CustomFilter
932 $objWriter->startElement($rule->getRuleType());
933
934 if ($rule->getOperator() !== Rule::AUTOFILTER_COLUMN_RULE_EQUAL) {
935 $objWriter->writeAttribute('operator', $rule->getOperator());
936 }
937 if ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DATEGROUP) {
938 // Date Group filters
939 foreach ($rule->getValue() as $key => $value) {
940 if ($value > '') {
941 $objWriter->writeAttribute($key, $value);
942 }
943 }
944 $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping());
945 } else {
946 $objWriter->writeAttribute('val', $rule->getValue());
947 }
948
949 $objWriter->endElement();
950 }
951 }
952
953 $objWriter->endElement();
954
955 $objWriter->endElement();
956 }
957 }
958 }
959 $objWriter->endElement();
960 }
961 }
962
969 private function writePageSetup(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
970 {
971 // pageSetup
972 $objWriter->startElement('pageSetup');
973 $objWriter->writeAttribute('paperSize', $pSheet->getPageSetup()->getPaperSize());
974 $objWriter->writeAttribute('orientation', $pSheet->getPageSetup()->getOrientation());
975
976 if ($pSheet->getPageSetup()->getScale() !== null) {
977 $objWriter->writeAttribute('scale', $pSheet->getPageSetup()->getScale());
978 }
979 if ($pSheet->getPageSetup()->getFitToHeight() !== null) {
980 $objWriter->writeAttribute('fitToHeight', $pSheet->getPageSetup()->getFitToHeight());
981 } else {
982 $objWriter->writeAttribute('fitToHeight', '0');
983 }
984 if ($pSheet->getPageSetup()->getFitToWidth() !== null) {
985 $objWriter->writeAttribute('fitToWidth', $pSheet->getPageSetup()->getFitToWidth());
986 } else {
987 $objWriter->writeAttribute('fitToWidth', '0');
988 }
989 if ($pSheet->getPageSetup()->getFirstPageNumber() !== null) {
990 $objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber());
991 $objWriter->writeAttribute('useFirstPageNumber', '1');
992 }
993 $objWriter->writeAttribute('pageOrder', $pSheet->getPageSetup()->getPageOrder());
994
995 $getUnparsedLoadedData = $pSheet->getParent()->getUnparsedLoadedData();
996 if (isset($getUnparsedLoadedData['sheets'][$pSheet->getCodeName()]['pageSetupRelId'])) {
997 $objWriter->writeAttribute('r:id', $getUnparsedLoadedData['sheets'][$pSheet->getCodeName()]['pageSetupRelId']);
998 }
999
1000 $objWriter->endElement();
1001 }
1002
1009 private function writeHeaderFooter(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
1010 {
1011 // headerFooter
1012 $objWriter->startElement('headerFooter');
1013 $objWriter->writeAttribute('differentOddEven', ($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false'));
1014 $objWriter->writeAttribute('differentFirst', ($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false'));
1015 $objWriter->writeAttribute('scaleWithDoc', ($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false'));
1016 $objWriter->writeAttribute('alignWithMargins', ($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false'));
1017
1018 $objWriter->writeElement('oddHeader', $pSheet->getHeaderFooter()->getOddHeader());
1019 $objWriter->writeElement('oddFooter', $pSheet->getHeaderFooter()->getOddFooter());
1020 $objWriter->writeElement('evenHeader', $pSheet->getHeaderFooter()->getEvenHeader());
1021 $objWriter->writeElement('evenFooter', $pSheet->getHeaderFooter()->getEvenFooter());
1022 $objWriter->writeElement('firstHeader', $pSheet->getHeaderFooter()->getFirstHeader());
1023 $objWriter->writeElement('firstFooter', $pSheet->getHeaderFooter()->getFirstFooter());
1024 $objWriter->endElement();
1025 }
1026
1033 private function writeBreaks(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
1034 {
1035 // Get row and column breaks
1036 $aRowBreaks = [];
1037 $aColumnBreaks = [];
1038 foreach ($pSheet->getBreaks() as $cell => $breakType) {
1039 if ($breakType == PhpspreadsheetWorksheet::BREAK_ROW) {
1040 $aRowBreaks[] = $cell;
1041 } elseif ($breakType == PhpspreadsheetWorksheet::BREAK_COLUMN) {
1042 $aColumnBreaks[] = $cell;
1043 }
1044 }
1045
1046 // rowBreaks
1047 if (!empty($aRowBreaks)) {
1048 $objWriter->startElement('rowBreaks');
1049 $objWriter->writeAttribute('count', count($aRowBreaks));
1050 $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks));
1051
1052 foreach ($aRowBreaks as $cell) {
1054
1055 $objWriter->startElement('brk');
1056 $objWriter->writeAttribute('id', $coords[1]);
1057 $objWriter->writeAttribute('man', '1');
1058 $objWriter->endElement();
1059 }
1060
1061 $objWriter->endElement();
1062 }
1063
1064 // Second, write column breaks
1065 if (!empty($aColumnBreaks)) {
1066 $objWriter->startElement('colBreaks');
1067 $objWriter->writeAttribute('count', count($aColumnBreaks));
1068 $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks));
1069
1070 foreach ($aColumnBreaks as $cell) {
1072
1073 $objWriter->startElement('brk');
1074 $objWriter->writeAttribute('id', Coordinate::columnIndexFromString($coords[0]) - 1);
1075 $objWriter->writeAttribute('man', '1');
1076 $objWriter->endElement();
1077 }
1078
1079 $objWriter->endElement();
1080 }
1081 }
1082
1090 private function writeSheetData(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, array $pStringTable): void
1091 {
1092 // Flipped stringtable, for faster index searching
1093 $aFlippedStringTable = $this->getParentWriter()->getWriterPartstringtable()->flipStringTable($pStringTable);
1094
1095 // sheetData
1096 $objWriter->startElement('sheetData');
1097
1098 // Get column count
1099 $colCount = Coordinate::columnIndexFromString($pSheet->getHighestColumn());
1100
1101 // Highest row number
1102 $highestRow = $pSheet->getHighestRow();
1103
1104 // Loop through cells
1105 $cellsByRow = [];
1106 foreach ($pSheet->getCoordinates() as $coordinate) {
1107 $cellAddress = Coordinate::coordinateFromString($coordinate);
1108 $cellsByRow[$cellAddress[1]][] = $coordinate;
1109 }
1110
1111 $currentRow = 0;
1112 while ($currentRow++ < $highestRow) {
1113 // Get row dimension
1114 $rowDimension = $pSheet->getRowDimension($currentRow);
1115
1116 // Write current row?
1117 $writeCurrentRow = isset($cellsByRow[$currentRow]) || $rowDimension->getRowHeight() >= 0 || $rowDimension->getVisible() == false || $rowDimension->getCollapsed() == true || $rowDimension->getOutlineLevel() > 0 || $rowDimension->getXfIndex() !== null;
1118
1119 if ($writeCurrentRow) {
1120 // Start a new row
1121 $objWriter->startElement('row');
1122 $objWriter->writeAttribute('r', $currentRow);
1123 $objWriter->writeAttribute('spans', '1:' . $colCount);
1124
1125 // Row dimensions
1126 if ($rowDimension->getRowHeight() >= 0) {
1127 $objWriter->writeAttribute('customHeight', '1');
1128 $objWriter->writeAttribute('ht', StringHelper::formatNumber($rowDimension->getRowHeight()));
1129 }
1130
1131 // Row visibility
1132 if (!$rowDimension->getVisible() === true) {
1133 $objWriter->writeAttribute('hidden', 'true');
1134 }
1135
1136 // Collapsed
1137 if ($rowDimension->getCollapsed() === true) {
1138 $objWriter->writeAttribute('collapsed', 'true');
1139 }
1140
1141 // Outline level
1142 if ($rowDimension->getOutlineLevel() > 0) {
1143 $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel());
1144 }
1145
1146 // Style
1147 if ($rowDimension->getXfIndex() !== null) {
1148 $objWriter->writeAttribute('s', $rowDimension->getXfIndex());
1149 $objWriter->writeAttribute('customFormat', '1');
1150 }
1151
1152 // Write cells
1153 if (isset($cellsByRow[$currentRow])) {
1154 foreach ($cellsByRow[$currentRow] as $cellAddress) {
1155 // Write cell
1156 $this->writeCell($objWriter, $pSheet, $cellAddress, $aFlippedStringTable);
1157 }
1158 }
1159
1160 // End row
1161 $objWriter->endElement();
1162 }
1163 }
1164
1165 $objWriter->endElement();
1166 }
1167
1171 private function writeCellInlineStr(XMLWriter $objWriter, string $mappedType, $cellValue): void
1172 {
1173 $objWriter->writeAttribute('t', $mappedType);
1174 if (!$cellValue instanceof RichText) {
1175 $objWriter->writeElement('t', StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue)));
1176 } elseif ($cellValue instanceof RichText) {
1177 $objWriter->startElement('is');
1178 $this->getParentWriter()->getWriterPartstringtable()->writeRichText($objWriter, $cellValue);
1179 $objWriter->endElement();
1180 }
1181 }
1182
1187 private function writeCellString(XMLWriter $objWriter, string $mappedType, $cellValue, array $pFlippedStringTable): void
1188 {
1189 $objWriter->writeAttribute('t', $mappedType);
1190 if (!$cellValue instanceof RichText) {
1191 self::writeElementIf($objWriter, isset($pFlippedStringTable[$cellValue]), 'v', $pFlippedStringTable[$cellValue] ?? '');
1192 } else {
1193 $objWriter->writeElement('v', $pFlippedStringTable[$cellValue->getHashCode()]);
1194 }
1195 }
1196
1200 private function writeCellNumeric(XMLWriter $objWriter, $cellValue): void
1201 {
1202 //force a decimal to be written if the type is float
1203 if (is_float($cellValue)) {
1204 // force point as decimal separator in case current locale uses comma
1205 $cellValue = str_replace(',', '.', (string) $cellValue);
1206 if (strpos($cellValue, '.') === false) {
1207 $cellValue = $cellValue . '.0';
1208 }
1209 }
1210 $objWriter->writeElement('v', $cellValue);
1211 }
1212
1213 private function writeCellBoolean(XMLWriter $objWriter, string $mappedType, bool $cellValue): void
1214 {
1215 $objWriter->writeAttribute('t', $mappedType);
1216 $objWriter->writeElement('v', $cellValue ? '1' : '0');
1217 }
1218
1219 private function writeCellError(XMLWriter $objWriter, string $mappedType, string $cellValue, string $formulaerr = '#NULL!'): void
1220 {
1221 $objWriter->writeAttribute('t', $mappedType);
1222 $cellIsFormula = substr($cellValue, 0, 1) === '=';
1223 self::writeElementIf($objWriter, $cellIsFormula, 'f', Xlfn::addXlfnStripEquals($cellValue));
1224 $objWriter->writeElement('v', $cellIsFormula ? $formulaerr : $cellValue);
1225 }
1226
1227 private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell $pCell): void
1228 {
1229 $calculatedValue = $this->getParentWriter()->getPreCalculateFormulas() ? $pCell->getCalculatedValue() : $cellValue;
1230 if (is_string($calculatedValue)) {
1231 if (\PhpOffice\PhpSpreadsheet\Calculation\Functions::isError($calculatedValue)) {
1232 $this->writeCellError($objWriter, 'e', $cellValue, $calculatedValue);
1233
1234 return;
1235 }
1236 $objWriter->writeAttribute('t', 'str');
1237 } elseif (is_bool($calculatedValue)) {
1238 $objWriter->writeAttribute('t', 'b');
1239 $calculatedValue = (int) $calculatedValue;
1240 }
1241 // array values are not yet supported
1242 //$attributes = $pCell->getFormulaAttributes();
1243 //if (($attributes['t'] ?? null) === 'array') {
1244 // $objWriter->startElement('f');
1245 // $objWriter->writeAttribute('t', 'array');
1246 // $objWriter->writeAttribute('ref', $pCellAddress);
1247 // $objWriter->writeAttribute('aca', '1');
1248 // $objWriter->writeAttribute('ca', '1');
1249 // $objWriter->text(substr($cellValue, 1));
1250 // $objWriter->endElement();
1251 //} else {
1252 // $objWriter->writeElement('f', Xlfn::addXlfnStripEquals($cellValue));
1253 //}
1254 $objWriter->writeElement('f', Xlfn::addXlfnStripEquals($cellValue));
1255 self::writeElementIf(
1256 $objWriter,
1257 $this->getParentWriter()->getOffice2003Compatibility() === false,
1258 'v',
1259 ($this->getParentWriter()->getPreCalculateFormulas() && !is_array($calculatedValue) && substr($calculatedValue, 0, 1) !== '#')
1260 ? StringHelper::formatNumber($calculatedValue) : '0'
1261 );
1262 }
1263
1272 private function writeCell(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, string $pCellAddress, array $pFlippedStringTable): void
1273 {
1274 // Cell
1275 $pCell = $pSheet->getCell($pCellAddress);
1276 $objWriter->startElement('c');
1277 $objWriter->writeAttribute('r', $pCellAddress);
1278
1279 // Sheet styles
1280 $xfi = $pCell->getXfIndex();
1281 self::writeAttributeIf($objWriter, $xfi, 's', $xfi);
1282
1283 // If cell value is supplied, write cell value
1284 $cellValue = $pCell->getValue();
1285 if (is_object($cellValue) || $cellValue !== '') {
1286 // Map type
1287 $mappedType = $pCell->getDataType();
1288
1289 // Write data depending on its type
1290 switch (strtolower($mappedType)) {
1291 case 'inlinestr': // Inline string
1292 $this->writeCellInlineStr($objWriter, $mappedType, $cellValue);
1293
1294 break;
1295 case 's': // String
1296 $this->writeCellString($objWriter, $mappedType, $cellValue, $pFlippedStringTable);
1297
1298 break;
1299 case 'f': // Formula
1300 $this->writeCellFormula($objWriter, $cellValue, $pCell);
1301
1302 break;
1303 case 'n': // Numeric
1304 $this->writeCellNumeric($objWriter, $cellValue);
1305
1306 break;
1307 case 'b': // Boolean
1308 $this->writeCellBoolean($objWriter, $mappedType, $cellValue);
1309
1310 break;
1311 case 'e': // Error
1312 $this->writeCellError($objWriter, $mappedType, $cellValue);
1313 }
1314 }
1315
1316 $objWriter->endElement();
1317 }
1318
1326 private function writeDrawings(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, $includeCharts = false): void
1327 {
1328 $unparsedLoadedData = $pSheet->getParent()->getUnparsedLoadedData();
1329 $hasUnparsedDrawing = isset($unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds']);
1330 $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0;
1331 if ($chartCount == 0 && $pSheet->getDrawingCollection()->count() == 0 && !$hasUnparsedDrawing) {
1332 return;
1333 }
1334
1335 // If sheet contains drawings, add the relationships
1336 $objWriter->startElement('drawing');
1337
1338 $rId = 'rId1';
1339 if (isset($unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds'])) {
1340 $drawingOriginalIds = $unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds'];
1341 // take first. In future can be overriten
1342 // (! synchronize with \PhpOffice\PhpSpreadsheet\Writer\Xlsx\Rels::writeWorksheetRelationships)
1343 $rId = reset($drawingOriginalIds);
1344 }
1345
1346 $objWriter->writeAttribute('r:id', $rId);
1347 $objWriter->endElement();
1348 }
1349
1356 private function writeLegacyDrawing(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
1357 {
1358 // If sheet contains comments, add the relationships
1359 if (count($pSheet->getComments()) > 0) {
1360 $objWriter->startElement('legacyDrawing');
1361 $objWriter->writeAttribute('r:id', 'rId_comments_vml1');
1362 $objWriter->endElement();
1363 }
1364 }
1365
1372 private function writeLegacyDrawingHF(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
1373 {
1374 // If sheet contains images, add the relationships
1375 if (count($pSheet->getHeaderFooter()->getImages()) > 0) {
1376 $objWriter->startElement('legacyDrawingHF');
1377 $objWriter->writeAttribute('r:id', 'rId_headerfooter_vml1');
1378 $objWriter->endElement();
1379 }
1380 }
1381
1382 private function writeAlternateContent(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
1383 {
1384 if (empty($pSheet->getParent()->getUnparsedLoadedData()['sheets'][$pSheet->getCodeName()]['AlternateContents'])) {
1385 return;
1386 }
1387
1388 foreach ($pSheet->getParent()->getUnparsedLoadedData()['sheets'][$pSheet->getCodeName()]['AlternateContents'] as $alternateContent) {
1389 $objWriter->writeRaw($alternateContent);
1390 }
1391 }
1392
1399 private function writeExtLst(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
1400 {
1401 $conditionalFormattingRuleExtList = [];
1402 foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) {
1404 foreach ($conditionalStyles as $conditional) {
1405 $dataBar = $conditional->getDataBar();
1406 if ($dataBar && $dataBar->getConditionalFormattingRuleExt()) {
1407 $conditionalFormattingRuleExtList[] = $dataBar->getConditionalFormattingRuleExt();
1408 }
1409 }
1410 }
1411
1412 if (count($conditionalFormattingRuleExtList) > 0) {
1413 $conditionalFormattingRuleExtNsPrefix = 'x14';
1414 $objWriter->startElement('extLst');
1415 $objWriter->startElement('ext');
1416 $objWriter->writeAttribute('uri', '{78C0D931-6437-407d-A8EE-F0AAD7539E65}');
1417 $objWriter->startElementNs($conditionalFormattingRuleExtNsPrefix, 'conditionalFormattings', null);
1418 foreach ($conditionalFormattingRuleExtList as $extension) {
1419 self::writeExtConditionalFormattingElements($objWriter, $extension);
1420 }
1421 $objWriter->endElement(); //end conditionalFormattings
1422 $objWriter->endElement(); //end ext
1423 $objWriter->endElement(); //end extLst
1424 }
1425 }
1426}
if(! $in) $columns
Definition: Utf8Test.php:45
An exception for terminatinating execution or to throw for unit testing.
getCalculatedValue($resetLog=true)
Get calculated cell value.
Definition: Cell.php:251
Helper class to manipulate cell coordinates.
Definition: Coordinate.php:15
static coordinateFromString($pCoordinateString)
Coordinate from string.
Definition: Coordinate.php:32
static columnIndexFromString($pString)
Column index from string.
Definition: Coordinate.php:265
static mergeRangesInCollection(array $pCoordCollection)
Convert an associative array of single cell coordinates to values to an associative array of cell ran...
Definition: Coordinate.php:463
static splitRange($pRange)
Split range into coordinate strings.
Definition: Coordinate.php:140
static formatNumber($value)
Formats a numeric value as a string for output in various output writers forcing point as decimal sep...
static controlCharacterPHP2OOXML($value)
Convert from PHP control character to OpenXML escaped control character.
const STORAGE_MEMORY
Temporary storage method.
Definition: XMLWriter.php:10
getPreCalculateFormulas()
Get Pre-Calculate Formulas flag If this is true (the default), then the writer will recalculate all f...
Definition: BaseWriter.php:60
getDiskCachingDirectory()
Get disk caching directory.
Definition: BaseWriter.php:92
getUseDiskCaching()
Get use disk caching where possible?
Definition: BaseWriter.php:72
writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell $pCell)
Definition: Worksheet.php:1227
writeSheetPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write SheetPr.
Definition: Worksheet.php:136
writeCellInlineStr(XMLWriter $objWriter, string $mappedType, $cellValue)
Definition: Worksheet.php:1171
writeAutoFilter(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write AutoFilter.
Definition: Worksheet.php:877
writeCellNumeric(XMLWriter $objWriter, $cellValue)
Definition: Worksheet.php:1200
writeSheetData(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, array $pStringTable)
Write SheetData.
Definition: Worksheet.php:1090
writeBreaks(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write Breaks.
Definition: Worksheet.php:1033
writePageSetup(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write PageSetup.
Definition: Worksheet.php:969
writeDimension(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write Dimension.
Definition: Worksheet.php:182
writeSheetViews(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write SheetViews.
Definition: Worksheet.php:196
writePrintOptions(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write PrintOptions.
Definition: Worksheet.php:833
writeHeaderFooter(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write Header / Footer.
Definition: Worksheet.php:1009
writeMergeCells(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write MergeCells.
Definition: Worksheet.php:809
writeSheetProtection(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write SheetProtection.
Definition: Worksheet.php:427
static writeExtConditionalFormattingElements(XMLWriter $objWriter, ConditionalFormattingRuleExtension $ruleExtension)
Definition: Worksheet.php:513
writeDataValidations(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write DataValidations.
Definition: Worksheet.php:674
writeProtectedRanges(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write ProtectedRanges.
Definition: Worksheet.php:781
writeHyperlinks(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write Hyperlinks.
Definition: Worksheet.php:740
writeConditionalFormatting(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write ConditionalFormatting.
Definition: Worksheet.php:607
static writeElementIf(XMLWriter $objWriter, $condition, string $attr, string $val)
Definition: Worksheet.php:469
writeDrawings(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, $includeCharts=false)
Write Drawings.
Definition: Worksheet.php:1326
writeAlternateContent(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Definition: Worksheet.php:1382
writeCols(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write Cols.
Definition: Worksheet.php:363
writeCellError(XMLWriter $objWriter, string $mappedType, string $cellValue, string $formulaerr='#NULL!')
Definition: Worksheet.php:1219
writeCellString(XMLWriter $objWriter, string $mappedType, $cellValue, array $pFlippedStringTable)
Definition: Worksheet.php:1187
writeCell(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, string $pCellAddress, array $pFlippedStringTable)
Write Cell.
Definition: Worksheet.php:1272
writeLegacyDrawing(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write LegacyDrawing.
Definition: Worksheet.php:1356
writeSheetFormatPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write SheetFormatPr.
Definition: Worksheet.php:310
static writeOtherCondElements(XMLWriter $objWriter, Conditional $conditional, string $cellCoordinate)
Definition: Worksheet.php:476
static writeAttributeIf(XMLWriter $objWriter, $condition, string $attr, string $val)
Definition: Worksheet.php:462
writeCellBoolean(XMLWriter $objWriter, string $mappedType, bool $cellValue)
Definition: Worksheet.php:1213
static writeTextCondElements(XMLWriter $objWriter, Conditional $conditional, string $cellCoordinate)
Definition: Worksheet.php:496
writeLegacyDrawingHF(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write LegacyDrawingHF.
Definition: Worksheet.php:1372
writePageMargins(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet)
Write PageMargins.
Definition: Worksheet.php:858
writeWorksheet(PhpspreadsheetWorksheet $pSheet, $pStringTable=null, $includeCharts=false)
Write worksheet to XML format.
Definition: Worksheet.php:28
static addXlfn(string $funcstring)
Prefix function name in string with _xlfn.
Definition: Xlfn.php:153
static addXlfnStripEquals(string $funcstring)
Prefix function name in string with _xlfn.
Definition: Xlfn.php:162
getSpreadsheet()
Get Spreadsheet object.
Definition: Xlsx.php:529
getOffice2003Compatibility()
Get Office2003 compatibility.
Definition: Xlsx.php:633
$key
Definition: croninfo.php:18
$txt
Definition: error.php:11
$coords
Definition: example_030.php:88
if(!array_key_exists('StateId', $_REQUEST)) $id
$rule
Definition: showstats.php:43