Total Complexity | 247 |
Total Lines | 1428 |
Duplicated Lines | 0 % |
Coverage | 94.12% |
Changes | 3 | ||
Bugs | 1 | Features | 0 |
Complex classes like Worksheet often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Worksheet, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
19 | class Worksheet extends WriterPart |
||
20 | { |
||
21 | /** |
||
22 | * Write worksheet to XML format. |
||
23 | * |
||
24 | * @param string[] $pStringTable |
||
25 | * @param bool $includeCharts Flag indicating if we should write charts |
||
26 | * |
||
27 | * @return string XML Output |
||
28 | */ |
||
29 | 159 | public function writeWorksheet(PhpspreadsheetWorksheet $worksheet, $pStringTable = null, $includeCharts = false) |
|
30 | { |
||
31 | // Create XML writer |
||
32 | 159 | $objWriter = null; |
|
33 | 159 | if ($this->getParentWriter()->getUseDiskCaching()) { |
|
34 | $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); |
||
35 | } else { |
||
36 | 159 | $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); |
|
37 | } |
||
38 | |||
39 | // XML header |
||
40 | 159 | $objWriter->startDocument('1.0', 'UTF-8', 'yes'); |
|
41 | |||
42 | // Worksheet |
||
43 | 159 | $objWriter->startElement('worksheet'); |
|
44 | 159 | $objWriter->writeAttribute('xml:space', 'preserve'); |
|
45 | 159 | $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); |
|
46 | 159 | $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); |
|
47 | |||
48 | 159 | $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing'); |
|
49 | 159 | $objWriter->writeAttribute('xmlns:x14', 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/main'); |
|
50 | 159 | $objWriter->writeAttribute('xmlns:xm', 'http://schemas.microsoft.com/office/excel/2006/main'); |
|
51 | 159 | $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006'); |
|
52 | 159 | $objWriter->writeAttribute('mc:Ignorable', 'x14ac'); |
|
53 | 159 | $objWriter->writeAttribute('xmlns:x14ac', 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac'); |
|
54 | |||
55 | // sheetPr |
||
56 | 159 | $this->writeSheetPr($objWriter, $worksheet); |
|
57 | |||
58 | // Dimension |
||
59 | 159 | $this->writeDimension($objWriter, $worksheet); |
|
60 | |||
61 | // sheetViews |
||
62 | 159 | $this->writeSheetViews($objWriter, $worksheet); |
|
63 | |||
64 | // sheetFormatPr |
||
65 | 159 | $this->writeSheetFormatPr($objWriter, $worksheet); |
|
66 | |||
67 | // cols |
||
68 | 159 | $this->writeCols($objWriter, $worksheet); |
|
69 | |||
70 | // sheetData |
||
71 | 159 | $this->writeSheetData($objWriter, $worksheet, $pStringTable); |
|
1 ignored issue
–
show
|
|||
72 | |||
73 | // sheetProtection |
||
74 | 159 | $this->writeSheetProtection($objWriter, $worksheet); |
|
75 | |||
76 | // protectedRanges |
||
77 | 159 | $this->writeProtectedRanges($objWriter, $worksheet); |
|
78 | |||
79 | // autoFilter |
||
80 | 159 | $this->writeAutoFilter($objWriter, $worksheet); |
|
81 | |||
82 | // mergeCells |
||
83 | 159 | $this->writeMergeCells($objWriter, $worksheet); |
|
84 | |||
85 | // conditionalFormatting |
||
86 | 159 | $this->writeConditionalFormatting($objWriter, $worksheet); |
|
87 | |||
88 | // dataValidations |
||
89 | 159 | $this->writeDataValidations($objWriter, $worksheet); |
|
90 | |||
91 | // hyperlinks |
||
92 | 159 | $this->writeHyperlinks($objWriter, $worksheet); |
|
93 | |||
94 | // Print options |
||
95 | 159 | $this->writePrintOptions($objWriter, $worksheet); |
|
96 | |||
97 | // Page margins |
||
98 | 159 | $this->writePageMargins($objWriter, $worksheet); |
|
99 | |||
100 | // Page setup |
||
101 | 159 | $this->writePageSetup($objWriter, $worksheet); |
|
102 | |||
103 | // Header / footer |
||
104 | 159 | $this->writeHeaderFooter($objWriter, $worksheet); |
|
105 | |||
106 | // Breaks |
||
107 | 159 | $this->writeBreaks($objWriter, $worksheet); |
|
108 | |||
109 | // Drawings and/or Charts |
||
110 | 159 | $this->writeDrawings($objWriter, $worksheet, $includeCharts); |
|
111 | |||
112 | // LegacyDrawing |
||
113 | 159 | $this->writeLegacyDrawing($objWriter, $worksheet); |
|
114 | |||
115 | // LegacyDrawingHF |
||
116 | 159 | $this->writeLegacyDrawingHF($objWriter, $worksheet); |
|
117 | |||
118 | // AlternateContent |
||
119 | 159 | $this->writeAlternateContent($objWriter, $worksheet); |
|
120 | |||
121 | // ConditionalFormattingRuleExtensionList |
||
122 | // (Must be inserted last. Not insert last, an Excel parse error will occur) |
||
123 | 159 | $this->writeExtLst($objWriter, $worksheet); |
|
124 | // dataValidations |
||
125 | 159 | $this->writeDataValidations($objWriter, $worksheet); |
|
126 | |||
127 | 159 | $objWriter->endElement(); |
|
128 | |||
129 | // Return |
||
130 | 159 | return $objWriter->getData(); |
|
131 | } |
||
132 | |||
133 | /** |
||
134 | * Write SheetPr. |
||
135 | * |
||
136 | * @param XMLWriter $objWriter XML Writer |
||
137 | * @param PhpspreadsheetWorksheet $worksheet Worksheet |
||
138 | */ |
||
139 | 159 | private function writeSheetPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
140 | { |
||
141 | // sheetPr |
||
142 | 159 | $objWriter->startElement('sheetPr'); |
|
143 | 159 | if ($worksheet->getParent()->hasMacros()) { |
|
144 | //if the workbook have macros, we need to have codeName for the sheet |
||
145 | 1 | if (!$worksheet->hasCodeName()) { |
|
146 | $worksheet->setCodeName($worksheet->getTitle()); |
||
147 | } |
||
148 | 1 | self::writeAttributeNotNull($objWriter, 'codeName', $worksheet->getCodeName()); |
|
149 | } |
||
150 | 159 | $autoFilterRange = $worksheet->getAutoFilter()->getRange(); |
|
151 | 159 | if (!empty($autoFilterRange)) { |
|
152 | 4 | $objWriter->writeAttribute('filterMode', 1); |
|
153 | 4 | $worksheet->getAutoFilter()->showHideRows(); |
|
154 | } |
||
155 | |||
156 | // tabColor |
||
157 | 159 | if ($worksheet->isTabColorSet()) { |
|
158 | 6 | $objWriter->startElement('tabColor'); |
|
159 | 6 | $objWriter->writeAttribute('rgb', $worksheet->getTabColor()->getARGB()); |
|
160 | 6 | $objWriter->endElement(); |
|
161 | } |
||
162 | |||
163 | // outlinePr |
||
164 | 159 | $objWriter->startElement('outlinePr'); |
|
165 | 159 | $objWriter->writeAttribute('summaryBelow', ($worksheet->getShowSummaryBelow() ? '1' : '0')); |
|
166 | 159 | $objWriter->writeAttribute('summaryRight', ($worksheet->getShowSummaryRight() ? '1' : '0')); |
|
167 | 159 | $objWriter->endElement(); |
|
168 | |||
169 | // pageSetUpPr |
||
170 | 159 | if ($worksheet->getPageSetup()->getFitToPage()) { |
|
171 | $objWriter->startElement('pageSetUpPr'); |
||
172 | $objWriter->writeAttribute('fitToPage', '1'); |
||
173 | $objWriter->endElement(); |
||
174 | } |
||
175 | |||
176 | 159 | $objWriter->endElement(); |
|
177 | 159 | } |
|
178 | |||
179 | /** |
||
180 | * Write Dimension. |
||
181 | * |
||
182 | * @param XMLWriter $objWriter XML Writer |
||
183 | */ |
||
184 | 159 | private function writeDimension(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
190 | 159 | } |
|
191 | |||
192 | /** |
||
193 | * Write SheetViews. |
||
194 | * |
||
195 | * @param XMLWriter $objWriter XML Writer |
||
196 | */ |
||
197 | 159 | private function writeSheetViews(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
198 | { |
||
199 | // sheetViews |
||
200 | 159 | $objWriter->startElement('sheetViews'); |
|
201 | |||
202 | // Sheet selected? |
||
203 | 159 | $sheetSelected = false; |
|
204 | 159 | if ($this->getParentWriter()->getSpreadsheet()->getIndex($worksheet) == $this->getParentWriter()->getSpreadsheet()->getActiveSheetIndex()) { |
|
205 | 159 | $sheetSelected = true; |
|
206 | } |
||
207 | |||
208 | // sheetView |
||
209 | 159 | $objWriter->startElement('sheetView'); |
|
210 | 159 | $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0'); |
|
211 | 159 | $objWriter->writeAttribute('workbookViewId', '0'); |
|
212 | |||
213 | // Zoom scales |
||
214 | 159 | if ($worksheet->getSheetView()->getZoomScale() != 100) { |
|
215 | $objWriter->writeAttribute('zoomScale', $worksheet->getSheetView()->getZoomScale()); |
||
216 | } |
||
217 | 159 | if ($worksheet->getSheetView()->getZoomScaleNormal() != 100) { |
|
218 | $objWriter->writeAttribute('zoomScaleNormal', $worksheet->getSheetView()->getZoomScaleNormal()); |
||
219 | } |
||
220 | |||
221 | // Show zeros (Excel also writes this attribute only if set to false) |
||
222 | 159 | if ($worksheet->getSheetView()->getShowZeros() === false) { |
|
223 | $objWriter->writeAttribute('showZeros', 0); |
||
224 | } |
||
225 | |||
226 | // View Layout Type |
||
227 | 159 | if ($worksheet->getSheetView()->getView() !== SheetView::SHEETVIEW_NORMAL) { |
|
228 | 1 | $objWriter->writeAttribute('view', $worksheet->getSheetView()->getView()); |
|
229 | } |
||
230 | |||
231 | // Gridlines |
||
232 | 159 | if ($worksheet->getShowGridlines()) { |
|
233 | 159 | $objWriter->writeAttribute('showGridLines', 'true'); |
|
234 | } else { |
||
235 | $objWriter->writeAttribute('showGridLines', 'false'); |
||
236 | } |
||
237 | |||
238 | // Row and column headers |
||
239 | 159 | if ($worksheet->getShowRowColHeaders()) { |
|
240 | 159 | $objWriter->writeAttribute('showRowColHeaders', '1'); |
|
241 | } else { |
||
242 | $objWriter->writeAttribute('showRowColHeaders', '0'); |
||
243 | } |
||
244 | |||
245 | // Right-to-left |
||
246 | 159 | if ($worksheet->getRightToLeft()) { |
|
247 | $objWriter->writeAttribute('rightToLeft', 'true'); |
||
248 | } |
||
249 | |||
250 | 159 | $topLeftCell = $worksheet->getTopLeftCell(); |
|
251 | 159 | $activeCell = $worksheet->getActiveCell(); |
|
252 | 159 | $sqref = $worksheet->getSelectedCells(); |
|
253 | |||
254 | // Pane |
||
255 | 159 | $pane = ''; |
|
256 | 159 | if ($worksheet->getFreezePane()) { |
|
257 | 6 | [$xSplit, $ySplit] = Coordinate::coordinateFromString($worksheet->getFreezePane() ?? ''); |
|
258 | 6 | $xSplit = Coordinate::columnIndexFromString($xSplit); |
|
259 | 6 | --$xSplit; |
|
260 | 6 | --$ySplit; |
|
261 | |||
262 | // pane |
||
263 | 6 | $pane = 'topRight'; |
|
264 | 6 | $objWriter->startElement('pane'); |
|
265 | 6 | if ($xSplit > 0) { |
|
266 | 1 | $objWriter->writeAttribute('xSplit', $xSplit); |
|
267 | } |
||
268 | 6 | if ($ySplit > 0) { |
|
269 | 6 | $objWriter->writeAttribute('ySplit', $ySplit); |
|
270 | 6 | $pane = ($xSplit > 0) ? 'bottomRight' : 'bottomLeft'; |
|
271 | } |
||
272 | 6 | self::writeAttributeNotNull($objWriter, 'topLeftCell', $topLeftCell); |
|
273 | 6 | $objWriter->writeAttribute('activePane', $pane); |
|
274 | 6 | $objWriter->writeAttribute('state', 'frozen'); |
|
275 | 6 | $objWriter->endElement(); |
|
276 | |||
277 | 6 | if (($xSplit > 0) && ($ySplit > 0)) { |
|
278 | // Write additional selections if more than two panes (ie both an X and a Y split) |
||
279 | 1 | $objWriter->startElement('selection'); |
|
280 | 1 | $objWriter->writeAttribute('pane', 'topRight'); |
|
281 | 1 | $objWriter->endElement(); |
|
282 | 1 | $objWriter->startElement('selection'); |
|
283 | 1 | $objWriter->writeAttribute('pane', 'bottomLeft'); |
|
284 | 6 | $objWriter->endElement(); |
|
285 | } |
||
286 | } else { |
||
287 | 153 | self::writeAttributeNotNull($objWriter, 'topLeftCell', $topLeftCell); |
|
288 | } |
||
289 | |||
290 | // Selection |
||
291 | // Only need to write selection element if we have a split pane |
||
292 | // We cheat a little by over-riding the active cell selection, setting it to the split cell |
||
293 | 159 | $objWriter->startElement('selection'); |
|
294 | 159 | if ($pane != '') { |
|
295 | 6 | $objWriter->writeAttribute('pane', $pane); |
|
296 | } |
||
297 | 159 | $objWriter->writeAttribute('activeCell', $activeCell); |
|
298 | 159 | $objWriter->writeAttribute('sqref', $sqref); |
|
299 | 159 | $objWriter->endElement(); |
|
300 | |||
301 | 159 | $objWriter->endElement(); |
|
302 | |||
303 | 159 | $objWriter->endElement(); |
|
304 | 159 | } |
|
305 | |||
306 | /** |
||
307 | * Write SheetFormatPr. |
||
308 | * |
||
309 | * @param XMLWriter $objWriter XML Writer |
||
310 | */ |
||
311 | 159 | private function writeSheetFormatPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
312 | { |
||
313 | // sheetFormatPr |
||
314 | 159 | $objWriter->startElement('sheetFormatPr'); |
|
315 | |||
316 | // Default row height |
||
317 | 159 | if ($worksheet->getDefaultRowDimension()->getRowHeight() >= 0) { |
|
318 | 9 | $objWriter->writeAttribute('customHeight', 'true'); |
|
319 | 9 | $objWriter->writeAttribute('defaultRowHeight', StringHelper::formatNumber($worksheet->getDefaultRowDimension()->getRowHeight())); |
|
320 | } else { |
||
321 | 150 | $objWriter->writeAttribute('defaultRowHeight', '14.4'); |
|
322 | } |
||
323 | |||
324 | // Set Zero Height row |
||
325 | if ( |
||
326 | 159 | (string) $worksheet->getDefaultRowDimension()->getZeroHeight() === '1' || |
|
327 | 159 | strtolower((string) $worksheet->getDefaultRowDimension()->getZeroHeight()) == 'true' |
|
328 | ) { |
||
329 | $objWriter->writeAttribute('zeroHeight', '1'); |
||
330 | } |
||
331 | |||
332 | // Default column width |
||
333 | 159 | if ($worksheet->getDefaultColumnDimension()->getWidth() >= 0) { |
|
334 | 9 | $objWriter->writeAttribute('defaultColWidth', StringHelper::formatNumber($worksheet->getDefaultColumnDimension()->getWidth())); |
|
335 | } |
||
336 | |||
337 | // Outline level - row |
||
338 | 159 | $outlineLevelRow = 0; |
|
339 | 159 | foreach ($worksheet->getRowDimensions() as $dimension) { |
|
340 | 23 | if ($dimension->getOutlineLevel() > $outlineLevelRow) { |
|
341 | $outlineLevelRow = $dimension->getOutlineLevel(); |
||
342 | } |
||
343 | } |
||
344 | 159 | $objWriter->writeAttribute('outlineLevelRow', (int) $outlineLevelRow); |
|
345 | |||
346 | // Outline level - column |
||
347 | 159 | $outlineLevelCol = 0; |
|
348 | 159 | foreach ($worksheet->getColumnDimensions() as $dimension) { |
|
349 | 36 | if ($dimension->getOutlineLevel() > $outlineLevelCol) { |
|
350 | 1 | $outlineLevelCol = $dimension->getOutlineLevel(); |
|
351 | } |
||
352 | } |
||
353 | 159 | $objWriter->writeAttribute('outlineLevelCol', (int) $outlineLevelCol); |
|
354 | |||
355 | 159 | $objWriter->endElement(); |
|
356 | 159 | } |
|
357 | |||
358 | /** |
||
359 | * Write Cols. |
||
360 | * |
||
361 | * @param XMLWriter $objWriter XML Writer |
||
362 | * @param PhpspreadsheetWorksheet $worksheet Worksheet |
||
363 | */ |
||
364 | 159 | private function writeCols(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
365 | { |
||
366 | // cols |
||
367 | 159 | if (count($worksheet->getColumnDimensions()) > 0) { |
|
368 | 36 | $objWriter->startElement('cols'); |
|
369 | |||
370 | 36 | $worksheet->calculateColumnWidths(); |
|
371 | |||
372 | // Loop through column dimensions |
||
373 | 36 | foreach ($worksheet->getColumnDimensions() as $colDimension) { |
|
374 | // col |
||
375 | 36 | $objWriter->startElement('col'); |
|
376 | 36 | $objWriter->writeAttribute('min', Coordinate::columnIndexFromString($colDimension->getColumnIndex())); |
|
377 | 36 | $objWriter->writeAttribute('max', Coordinate::columnIndexFromString($colDimension->getColumnIndex())); |
|
378 | |||
379 | 36 | if ($colDimension->getWidth() < 0) { |
|
380 | // No width set, apply default of 10 |
||
381 | 3 | $objWriter->writeAttribute('width', '9.10'); |
|
382 | } else { |
||
383 | // Width set |
||
384 | 35 | $objWriter->writeAttribute('width', StringHelper::formatNumber($colDimension->getWidth())); |
|
385 | } |
||
386 | |||
387 | // Column visibility |
||
388 | 36 | if ($colDimension->getVisible() === false) { |
|
389 | 4 | $objWriter->writeAttribute('hidden', 'true'); |
|
390 | } |
||
391 | |||
392 | // Auto size? |
||
393 | 36 | if ($colDimension->getAutoSize()) { |
|
394 | 14 | $objWriter->writeAttribute('bestFit', 'true'); |
|
395 | } |
||
396 | |||
397 | // Custom width? |
||
398 | 36 | if ($colDimension->getWidth() != $worksheet->getDefaultColumnDimension()->getWidth()) { |
|
399 | 35 | $objWriter->writeAttribute('customWidth', 'true'); |
|
400 | } |
||
401 | |||
402 | // Collapsed |
||
403 | 36 | if ($colDimension->getCollapsed() === true) { |
|
404 | 1 | $objWriter->writeAttribute('collapsed', 'true'); |
|
405 | } |
||
406 | |||
407 | // Outline level |
||
408 | 36 | if ($colDimension->getOutlineLevel() > 0) { |
|
409 | 1 | $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel()); |
|
410 | } |
||
411 | |||
412 | // Style |
||
413 | 36 | $objWriter->writeAttribute('style', $colDimension->getXfIndex()); |
|
414 | |||
415 | 36 | $objWriter->endElement(); |
|
416 | } |
||
417 | |||
418 | 36 | $objWriter->endElement(); |
|
419 | } |
||
420 | 159 | } |
|
421 | |||
422 | /** |
||
423 | * Write SheetProtection. |
||
424 | * |
||
425 | * @param XMLWriter $objWriter XML Writer |
||
426 | */ |
||
427 | 159 | private function writeSheetProtection(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
428 | { |
||
429 | // sheetProtection |
||
430 | 159 | $objWriter->startElement('sheetProtection'); |
|
431 | |||
432 | 159 | $protection = $worksheet->getProtection(); |
|
433 | |||
434 | 159 | if ($protection->getAlgorithm()) { |
|
435 | 1 | $objWriter->writeAttribute('algorithmName', $protection->getAlgorithm()); |
|
436 | 1 | $objWriter->writeAttribute('hashValue', $protection->getPassword()); |
|
437 | 1 | $objWriter->writeAttribute('saltValue', $protection->getSalt()); |
|
438 | 1 | $objWriter->writeAttribute('spinCount', $protection->getSpinCount()); |
|
439 | 158 | } elseif ($protection->getPassword() !== '') { |
|
440 | 3 | $objWriter->writeAttribute('password', $protection->getPassword()); |
|
441 | } |
||
442 | |||
443 | 159 | $objWriter->writeAttribute('sheet', ($protection->getSheet() ? 'true' : 'false')); |
|
444 | 159 | $objWriter->writeAttribute('objects', ($protection->getObjects() ? 'true' : 'false')); |
|
445 | 159 | $objWriter->writeAttribute('scenarios', ($protection->getScenarios() ? 'true' : 'false')); |
|
446 | 159 | $objWriter->writeAttribute('formatCells', ($protection->getFormatCells() ? 'true' : 'false')); |
|
447 | 159 | $objWriter->writeAttribute('formatColumns', ($protection->getFormatColumns() ? 'true' : 'false')); |
|
448 | 159 | $objWriter->writeAttribute('formatRows', ($protection->getFormatRows() ? 'true' : 'false')); |
|
449 | 159 | $objWriter->writeAttribute('insertColumns', ($protection->getInsertColumns() ? 'true' : 'false')); |
|
450 | 159 | $objWriter->writeAttribute('insertRows', ($protection->getInsertRows() ? 'true' : 'false')); |
|
451 | 159 | $objWriter->writeAttribute('insertHyperlinks', ($protection->getInsertHyperlinks() ? 'true' : 'false')); |
|
452 | 159 | $objWriter->writeAttribute('deleteColumns', ($protection->getDeleteColumns() ? 'true' : 'false')); |
|
453 | 159 | $objWriter->writeAttribute('deleteRows', ($protection->getDeleteRows() ? 'true' : 'false')); |
|
454 | 159 | $objWriter->writeAttribute('selectLockedCells', ($protection->getSelectLockedCells() ? 'true' : 'false')); |
|
455 | 159 | $objWriter->writeAttribute('sort', ($protection->getSort() ? 'true' : 'false')); |
|
456 | 159 | $objWriter->writeAttribute('autoFilter', ($protection->getAutoFilter() ? 'true' : 'false')); |
|
457 | 159 | $objWriter->writeAttribute('pivotTables', ($protection->getPivotTables() ? 'true' : 'false')); |
|
458 | 159 | $objWriter->writeAttribute('selectUnlockedCells', ($protection->getSelectUnlockedCells() ? 'true' : 'false')); |
|
459 | 159 | $objWriter->endElement(); |
|
460 | 159 | } |
|
461 | |||
462 | 152 | private static function writeAttributeIf(XMLWriter $objWriter, $condition, string $attr, string $val): void |
|
466 | } |
||
467 | 152 | } |
|
468 | |||
469 | 159 | private static function writeAttributeNotNull(XMLWriter $objWriter, string $attr, ?string $val): void |
|
470 | { |
||
471 | 159 | if ($val !== null) { |
|
472 | 8 | $objWriter->writeAttribute($attr, $val); |
|
473 | } |
||
474 | 159 | } |
|
475 | |||
476 | 110 | private static function writeElementIf(XMLWriter $objWriter, $condition, string $attr, string $val): void |
|
477 | { |
||
478 | 110 | if ($condition) { |
|
479 | 110 | $objWriter->writeElement($attr, $val); |
|
480 | } |
||
481 | 110 | } |
|
482 | |||
483 | 9 | private static function writeOtherCondElements(XMLWriter $objWriter, Conditional $conditional, string $cellCoordinate): void |
|
484 | { |
||
485 | if ( |
||
486 | 9 | $conditional->getConditionType() == Conditional::CONDITION_CELLIS |
|
487 | 9 | || $conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT |
|
488 | 9 | || $conditional->getConditionType() == Conditional::CONDITION_EXPRESSION |
|
489 | ) { |
||
490 | 6 | foreach ($conditional->getConditions() as $formula) { |
|
491 | // Formula |
||
492 | 6 | $objWriter->writeElement('formula', Xlfn::addXlfn($formula)); |
|
493 | } |
||
494 | 4 | } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSBLANKS) { |
|
495 | // formula copied from ms xlsx xml source file |
||
496 | 2 | $objWriter->writeElement('formula', 'LEN(TRIM(' . $cellCoordinate . '))=0'); |
|
497 | 3 | } elseif ($conditional->getConditionType() == Conditional::CONDITION_NOTCONTAINSBLANKS) { |
|
498 | // formula copied from ms xlsx xml source file |
||
499 | 1 | $objWriter->writeElement('formula', 'LEN(TRIM(' . $cellCoordinate . '))>0'); |
|
500 | } |
||
501 | 9 | } |
|
502 | |||
503 | 2 | private static function writeTextCondElements(XMLWriter $objWriter, Conditional $conditional, string $cellCoordinate): void |
|
504 | { |
||
505 | 2 | $txt = $conditional->getText(); |
|
506 | 2 | if ($txt !== null) { |
|
507 | 2 | $objWriter->writeAttribute('text', $txt); |
|
508 | 2 | if ($conditional->getOperatorType() == Conditional::OPERATOR_CONTAINSTEXT) { |
|
509 | 1 | $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $txt . '",' . $cellCoordinate . ')))'); |
|
510 | 2 | } elseif ($conditional->getOperatorType() == Conditional::OPERATOR_BEGINSWITH) { |
|
511 | 1 | $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($txt) . ')="' . $txt . '"'); |
|
512 | 2 | } elseif ($conditional->getOperatorType() == Conditional::OPERATOR_ENDSWITH) { |
|
513 | 1 | $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($txt) . ')="' . $txt . '"'); |
|
514 | 2 | } elseif ($conditional->getOperatorType() == Conditional::OPERATOR_NOTCONTAINS) { |
|
515 | 2 | $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $txt . '",' . $cellCoordinate . '))'); |
|
516 | } |
||
517 | } |
||
518 | 2 | } |
|
519 | |||
520 | 1 | private static function writeExtConditionalFormattingElements(XMLWriter $objWriter, ConditionalFormattingRuleExtension $ruleExtension): void |
|
521 | { |
||
522 | 1 | $prefix = 'x14'; |
|
523 | 1 | $objWriter->startElementNs($prefix, 'conditionalFormatting', null); |
|
524 | |||
525 | 1 | $objWriter->startElementNs($prefix, 'cfRule', null); |
|
526 | 1 | $objWriter->writeAttribute('type', $ruleExtension->getCfRule()); |
|
527 | 1 | $objWriter->writeAttribute('id', $ruleExtension->getId()); |
|
528 | 1 | $objWriter->startElementNs($prefix, 'dataBar', null); |
|
529 | 1 | $dataBar = $ruleExtension->getDataBarExt(); |
|
530 | 1 | foreach ($dataBar->getXmlAttributes() as $attrKey => $val) { |
|
531 | 1 | $objWriter->writeAttribute($attrKey, $val); |
|
532 | } |
||
533 | 1 | $minCfvo = $dataBar->getMinimumConditionalFormatValueObject(); |
|
534 | 1 | if ($minCfvo) { |
|
535 | 1 | $objWriter->startElementNs($prefix, 'cfvo', null); |
|
536 | 1 | $objWriter->writeAttribute('type', $minCfvo->getType()); |
|
537 | 1 | if ($minCfvo->getCellFormula()) { |
|
538 | 1 | $objWriter->writeElement('xm:f', $minCfvo->getCellFormula()); |
|
539 | } |
||
540 | 1 | $objWriter->endElement(); //end cfvo |
|
541 | } |
||
542 | |||
543 | 1 | $maxCfvo = $dataBar->getMaximumConditionalFormatValueObject(); |
|
544 | 1 | if ($maxCfvo) { |
|
545 | 1 | $objWriter->startElementNs($prefix, 'cfvo', null); |
|
546 | 1 | $objWriter->writeAttribute('type', $maxCfvo->getType()); |
|
547 | 1 | if ($maxCfvo->getCellFormula()) { |
|
548 | 1 | $objWriter->writeElement('xm:f', $maxCfvo->getCellFormula()); |
|
549 | } |
||
550 | 1 | $objWriter->endElement(); //end cfvo |
|
551 | } |
||
552 | |||
553 | 1 | foreach ($dataBar->getXmlElements() as $elmKey => $elmAttr) { |
|
554 | 1 | $objWriter->startElementNs($prefix, $elmKey, null); |
|
555 | 1 | foreach ($elmAttr as $attrKey => $attrVal) { |
|
556 | 1 | $objWriter->writeAttribute($attrKey, $attrVal); |
|
557 | } |
||
558 | 1 | $objWriter->endElement(); //end elmKey |
|
559 | } |
||
560 | 1 | $objWriter->endElement(); //end dataBar |
|
561 | 1 | $objWriter->endElement(); //end cfRule |
|
562 | 1 | $objWriter->writeElement('xm:sqref', $ruleExtension->getSqref()); |
|
563 | 1 | $objWriter->endElement(); //end conditionalFormatting |
|
564 | 1 | } |
|
565 | |||
566 | 11 | private static function writeDataBarElements(XMLWriter $objWriter, $dataBar): void |
|
567 | { |
||
568 | /** @var ConditionalDataBar $dataBar */ |
||
569 | 11 | if ($dataBar) { |
|
570 | 2 | $objWriter->startElement('dataBar'); |
|
571 | 2 | self::writeAttributeIf($objWriter, null !== $dataBar->getShowValue(), 'showValue', $dataBar->getShowValue() ? '1' : '0'); |
|
572 | |||
573 | 2 | $minCfvo = $dataBar->getMinimumConditionalFormatValueObject(); |
|
574 | 2 | if ($minCfvo) { |
|
575 | 2 | $objWriter->startElement('cfvo'); |
|
576 | 2 | self::writeAttributeIf($objWriter, $minCfvo->getType(), 'type', (string) $minCfvo->getType()); |
|
577 | 2 | self::writeAttributeIf($objWriter, $minCfvo->getValue(), 'val', (string) $minCfvo->getValue()); |
|
578 | 2 | $objWriter->endElement(); |
|
579 | } |
||
580 | 2 | $maxCfvo = $dataBar->getMaximumConditionalFormatValueObject(); |
|
581 | 2 | if ($maxCfvo) { |
|
582 | 2 | $objWriter->startElement('cfvo'); |
|
583 | 2 | self::writeAttributeIf($objWriter, $maxCfvo->getType(), 'type', (string) $maxCfvo->getType()); |
|
584 | 2 | self::writeAttributeIf($objWriter, $maxCfvo->getValue(), 'val', (string) $maxCfvo->getValue()); |
|
585 | 2 | $objWriter->endElement(); |
|
586 | } |
||
587 | 2 | if ($dataBar->getColor()) { |
|
588 | 2 | $objWriter->startElement('color'); |
|
589 | 2 | $objWriter->writeAttribute('rgb', $dataBar->getColor()); |
|
590 | 2 | $objWriter->endElement(); |
|
591 | } |
||
592 | 2 | $objWriter->endElement(); // end dataBar |
|
593 | |||
594 | 2 | if ($dataBar->getConditionalFormattingRuleExt()) { |
|
595 | 1 | $objWriter->startElement('extLst'); |
|
596 | 1 | $extension = $dataBar->getConditionalFormattingRuleExt(); |
|
597 | 1 | $objWriter->startElement('ext'); |
|
598 | 1 | $objWriter->writeAttribute('uri', '{B025F937-C7B1-47D3-B67F-A62EFF666E3E}'); |
|
599 | 1 | $objWriter->startElementNs('x14', 'id', null); |
|
600 | 1 | $objWriter->text($extension->getId()); |
|
601 | 1 | $objWriter->endElement(); |
|
602 | 1 | $objWriter->endElement(); |
|
603 | 1 | $objWriter->endElement(); //end extLst |
|
604 | } |
||
605 | } |
||
606 | 11 | } |
|
607 | |||
608 | /** |
||
609 | * Write ConditionalFormatting. |
||
610 | * |
||
611 | * @param XMLWriter $objWriter XML Writer |
||
612 | */ |
||
613 | 159 | private function writeConditionalFormatting(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
614 | { |
||
615 | // Conditional id |
||
616 | 159 | $id = 1; |
|
617 | |||
618 | // Loop through styles in the current worksheet |
||
619 | 159 | foreach ($worksheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { |
|
620 | 11 | foreach ($conditionalStyles as $conditional) { |
|
621 | // WHY was this again? |
||
622 | // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()) == '') { |
||
623 | // continue; |
||
624 | // } |
||
625 | 11 | if ($conditional->getConditionType() != Conditional::CONDITION_NONE) { |
|
626 | // conditionalFormatting |
||
627 | 11 | $objWriter->startElement('conditionalFormatting'); |
|
628 | 11 | $objWriter->writeAttribute('sqref', $cellCoordinate); |
|
629 | |||
630 | // cfRule |
||
631 | 11 | $objWriter->startElement('cfRule'); |
|
632 | 11 | $objWriter->writeAttribute('type', $conditional->getConditionType()); |
|
633 | 11 | self::writeAttributeIf( |
|
634 | 11 | $objWriter, |
|
635 | 11 | ($conditional->getConditionType() != Conditional::CONDITION_DATABAR), |
|
636 | 'dxfId', |
||
637 | 11 | (string) $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()) |
|
638 | ); |
||
639 | 11 | $objWriter->writeAttribute('priority', $id++); |
|
640 | |||
641 | 11 | self::writeAttributeif( |
|
642 | 11 | $objWriter, |
|
643 | ( |
||
644 | 11 | $conditional->getConditionType() === Conditional::CONDITION_CELLIS |
|
645 | 11 | || $conditional->getConditionType() === Conditional::CONDITION_CONTAINSTEXT |
|
646 | 11 | || $conditional->getConditionType() === Conditional::CONDITION_NOTCONTAINSTEXT |
|
647 | 7 | ) && $conditional->getOperatorType() !== Conditional::OPERATOR_NONE, |
|
648 | 'operator', |
||
649 | 11 | $conditional->getOperatorType() |
|
650 | ); |
||
651 | |||
652 | 11 | self::writeAttributeIf($objWriter, $conditional->getStopIfTrue(), 'stopIfTrue', '1'); |
|
653 | |||
654 | if ( |
||
655 | 11 | $conditional->getConditionType() === Conditional::CONDITION_CONTAINSTEXT |
|
656 | 11 | || $conditional->getConditionType() === Conditional::CONDITION_NOTCONTAINSTEXT |
|
657 | ) { |
||
658 | 2 | self::writeTextCondElements($objWriter, $conditional, $cellCoordinate); |
|
659 | } else { |
||
660 | 9 | self::writeOtherCondElements($objWriter, $conditional, $cellCoordinate); |
|
661 | } |
||
662 | |||
663 | //<dataBar> |
||
664 | 11 | self::writeDataBarElements($objWriter, $conditional->getDataBar()); |
|
665 | |||
666 | 11 | $objWriter->endElement(); //end cfRule |
|
667 | |||
668 | 11 | $objWriter->endElement(); |
|
669 | } |
||
670 | } |
||
671 | } |
||
672 | 159 | } |
|
673 | |||
674 | /** |
||
675 | * Write DataValidations. |
||
676 | * |
||
677 | * @param XMLWriter $objWriter XML Writer |
||
678 | */ |
||
679 | 159 | private function writeDataValidations(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
680 | { |
||
681 | // Datavalidation collection |
||
682 | 159 | $dataValidationCollection = $worksheet->getDataValidationCollection(); |
|
683 | |||
684 | // Write data validations? |
||
685 | 159 | if (!empty($dataValidationCollection)) { |
|
686 | 3 | $dataValidationCollection = Coordinate::mergeRangesInCollection($dataValidationCollection); |
|
687 | 3 | $objWriter->startElement('extLst'); |
|
688 | 3 | $objWriter->startElement('ext'); |
|
689 | 3 | $objWriter->writeAttribute('uri', '{CCE6A557-97BC-4b89-ADB6-D9C93CAAB3DF}'); |
|
690 | 3 | $objWriter->writeAttribute('xmlns:x14', 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/main'); |
|
691 | 3 | $objWriter->startElement('x14:dataValidations'); |
|
692 | 3 | $objWriter->writeAttribute('count', count($dataValidationCollection)); |
|
693 | 3 | $objWriter->writeAttribute('xmlns:xm', 'http://schemas.microsoft.com/office/excel/2006/main'); |
|
694 | |||
695 | 3 | foreach ($dataValidationCollection as $coordinate => $dv) { |
|
696 | 3 | $objWriter->startElement('x14:dataValidation'); |
|
697 | |||
698 | 3 | if ($dv->getType() != '') { |
|
699 | 3 | $objWriter->writeAttribute('type', $dv->getType()); |
|
700 | } |
||
701 | |||
702 | 3 | if ($dv->getErrorStyle() != '') { |
|
703 | 2 | $objWriter->writeAttribute('errorStyle', $dv->getErrorStyle()); |
|
704 | } |
||
705 | |||
706 | 3 | if ($dv->getOperator() != '') { |
|
707 | 2 | $objWriter->writeAttribute('operator', $dv->getOperator()); |
|
708 | } |
||
709 | |||
710 | 3 | $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0')); |
|
711 | // showDropDown is really hideDropDown Excel renders as true = hide, false = show |
||
712 | 3 | $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0')); |
|
713 | 3 | $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0')); |
|
714 | 3 | $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0')); |
|
715 | |||
716 | 3 | if ($dv->getErrorTitle() !== '') { |
|
717 | 3 | $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle()); |
|
718 | } |
||
719 | 3 | if ($dv->getError() !== '') { |
|
720 | 3 | $objWriter->writeAttribute('error', $dv->getError()); |
|
721 | } |
||
722 | 3 | if ($dv->getPromptTitle() !== '') { |
|
723 | 3 | $objWriter->writeAttribute('promptTitle', $dv->getPromptTitle()); |
|
724 | } |
||
725 | 3 | if ($dv->getPrompt() !== '') { |
|
726 | 3 | $objWriter->writeAttribute('prompt', $dv->getPrompt()); |
|
727 | } |
||
728 | |||
729 | 3 | if ($dv->getFormula1() !== '') { |
|
730 | 3 | $objWriter->startElement('x14:formula1'); |
|
731 | 3 | $objWriter->writeElement('xm:f', $dv->getFormula1()); |
|
732 | 3 | $objWriter->endElement(); |
|
733 | } |
||
734 | 3 | if ($dv->getFormula2() !== '') { |
|
735 | 1 | $objWriter->startElement('x14:formula2'); |
|
736 | 1 | $objWriter->writeElement('xm:f', $dv->getFormula2()); |
|
737 | 1 | $objWriter->endElement(); |
|
738 | } |
||
739 | 3 | $objWriter->writeElement('xm:sqref', $dv->getSqref() ?? $coordinate); |
|
740 | |||
741 | 3 | $objWriter->endElement(); |
|
742 | } |
||
743 | |||
744 | 3 | $objWriter->endElement(); // dataValidations |
|
745 | 3 | $objWriter->endElement(); // ext |
|
746 | 3 | $objWriter->endElement(); // extLst |
|
747 | } |
||
748 | 159 | } |
|
749 | |||
750 | /** |
||
751 | * Write Hyperlinks. |
||
752 | * |
||
753 | * @param XMLWriter $objWriter XML Writer |
||
754 | */ |
||
755 | 159 | private function writeHyperlinks(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
756 | { |
||
757 | // Hyperlink collection |
||
758 | 159 | $hyperlinkCollection = $worksheet->getHyperlinkCollection(); |
|
759 | |||
760 | // Relation ID |
||
761 | 159 | $relationId = 1; |
|
762 | |||
763 | // Write hyperlinks? |
||
764 | 159 | if (!empty($hyperlinkCollection)) { |
|
765 | 10 | $objWriter->startElement('hyperlinks'); |
|
766 | |||
767 | 10 | foreach ($hyperlinkCollection as $coordinate => $hyperlink) { |
|
768 | 10 | $objWriter->startElement('hyperlink'); |
|
769 | |||
770 | 10 | $objWriter->writeAttribute('ref', $coordinate); |
|
771 | 10 | if (!$hyperlink->isInternal()) { |
|
772 | 10 | $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId); |
|
773 | 10 | ++$relationId; |
|
774 | } else { |
||
775 | 6 | $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl())); |
|
776 | } |
||
777 | |||
778 | 10 | if ($hyperlink->getTooltip() !== '') { |
|
779 | 6 | $objWriter->writeAttribute('tooltip', $hyperlink->getTooltip()); |
|
780 | 6 | $objWriter->writeAttribute('display', $hyperlink->getTooltip()); |
|
781 | } |
||
782 | |||
783 | 10 | $objWriter->endElement(); |
|
784 | } |
||
785 | |||
786 | 10 | $objWriter->endElement(); |
|
787 | } |
||
788 | 159 | } |
|
789 | |||
790 | /** |
||
791 | * Write ProtectedRanges. |
||
792 | * |
||
793 | * @param XMLWriter $objWriter XML Writer |
||
794 | */ |
||
795 | 159 | private function writeProtectedRanges(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
796 | { |
||
797 | 159 | if (count($worksheet->getProtectedCells()) > 0) { |
|
798 | // protectedRanges |
||
799 | 6 | $objWriter->startElement('protectedRanges'); |
|
800 | |||
801 | // Loop protectedRanges |
||
802 | 6 | foreach ($worksheet->getProtectedCells() as $protectedCell => $passwordHash) { |
|
803 | // protectedRange |
||
804 | 6 | $objWriter->startElement('protectedRange'); |
|
805 | 6 | $objWriter->writeAttribute('name', 'p' . md5($protectedCell)); |
|
806 | 6 | $objWriter->writeAttribute('sqref', $protectedCell); |
|
807 | 6 | if (!empty($passwordHash)) { |
|
808 | 6 | $objWriter->writeAttribute('password', $passwordHash); |
|
809 | } |
||
810 | 6 | $objWriter->endElement(); |
|
811 | } |
||
812 | |||
813 | 6 | $objWriter->endElement(); |
|
814 | } |
||
815 | 159 | } |
|
816 | |||
817 | /** |
||
818 | * Write MergeCells. |
||
819 | * |
||
820 | * @param XMLWriter $objWriter XML Writer |
||
821 | */ |
||
822 | 159 | private function writeMergeCells(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
823 | { |
||
824 | 159 | if (count($worksheet->getMergeCells()) > 0) { |
|
825 | // mergeCells |
||
826 | 14 | $objWriter->startElement('mergeCells'); |
|
827 | |||
828 | // Loop mergeCells |
||
829 | 14 | foreach ($worksheet->getMergeCells() as $mergeCell) { |
|
830 | // mergeCell |
||
831 | 14 | $objWriter->startElement('mergeCell'); |
|
832 | 14 | $objWriter->writeAttribute('ref', $mergeCell); |
|
833 | 14 | $objWriter->endElement(); |
|
834 | } |
||
835 | |||
836 | 14 | $objWriter->endElement(); |
|
837 | } |
||
838 | 159 | } |
|
839 | |||
840 | /** |
||
841 | * Write PrintOptions. |
||
842 | * |
||
843 | * @param XMLWriter $objWriter XML Writer |
||
844 | */ |
||
845 | 159 | private function writePrintOptions(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
846 | { |
||
847 | // printOptions |
||
848 | 159 | $objWriter->startElement('printOptions'); |
|
849 | |||
850 | 159 | $objWriter->writeAttribute('gridLines', ($worksheet->getPrintGridlines() ? 'true' : 'false')); |
|
851 | 159 | $objWriter->writeAttribute('gridLinesSet', 'true'); |
|
852 | |||
853 | 159 | if ($worksheet->getPageSetup()->getHorizontalCentered()) { |
|
854 | $objWriter->writeAttribute('horizontalCentered', 'true'); |
||
855 | } |
||
856 | |||
857 | 159 | if ($worksheet->getPageSetup()->getVerticalCentered()) { |
|
858 | $objWriter->writeAttribute('verticalCentered', 'true'); |
||
859 | } |
||
860 | |||
861 | 159 | $objWriter->endElement(); |
|
862 | 159 | } |
|
863 | |||
864 | /** |
||
865 | * Write PageMargins. |
||
866 | * |
||
867 | * @param XMLWriter $objWriter XML Writer |
||
868 | */ |
||
869 | 159 | private function writePageMargins(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
870 | { |
||
871 | // pageMargins |
||
872 | 159 | $objWriter->startElement('pageMargins'); |
|
873 | 159 | $objWriter->writeAttribute('left', StringHelper::formatNumber($worksheet->getPageMargins()->getLeft())); |
|
874 | 159 | $objWriter->writeAttribute('right', StringHelper::formatNumber($worksheet->getPageMargins()->getRight())); |
|
875 | 159 | $objWriter->writeAttribute('top', StringHelper::formatNumber($worksheet->getPageMargins()->getTop())); |
|
876 | 159 | $objWriter->writeAttribute('bottom', StringHelper::formatNumber($worksheet->getPageMargins()->getBottom())); |
|
877 | 159 | $objWriter->writeAttribute('header', StringHelper::formatNumber($worksheet->getPageMargins()->getHeader())); |
|
878 | 159 | $objWriter->writeAttribute('footer', StringHelper::formatNumber($worksheet->getPageMargins()->getFooter())); |
|
879 | 159 | $objWriter->endElement(); |
|
880 | 159 | } |
|
881 | |||
882 | /** |
||
883 | * Write AutoFilter. |
||
884 | * |
||
885 | * @param XMLWriter $objWriter XML Writer |
||
886 | * @param PhpspreadsheetWorksheet $worksheet Worksheet |
||
887 | */ |
||
888 | 159 | private function writeAutoFilter(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
978 | } |
||
979 | 159 | } |
|
980 | |||
981 | /** |
||
982 | * Write PageSetup. |
||
983 | * |
||
984 | * @param XMLWriter $objWriter XML Writer |
||
985 | * @param PhpspreadsheetWorksheet $worksheet Worksheet |
||
986 | */ |
||
987 | 159 | private function writePageSetup(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
988 | { |
||
989 | // pageSetup |
||
990 | 159 | $objWriter->startElement('pageSetup'); |
|
991 | 159 | $objWriter->writeAttribute('paperSize', $worksheet->getPageSetup()->getPaperSize()); |
|
992 | 159 | $objWriter->writeAttribute('orientation', $worksheet->getPageSetup()->getOrientation()); |
|
993 | |||
994 | 159 | if ($worksheet->getPageSetup()->getScale() !== null) { |
|
995 | 159 | $objWriter->writeAttribute('scale', $worksheet->getPageSetup()->getScale()); |
|
996 | } |
||
997 | 159 | if ($worksheet->getPageSetup()->getFitToHeight() !== null) { |
|
998 | 159 | $objWriter->writeAttribute('fitToHeight', $worksheet->getPageSetup()->getFitToHeight()); |
|
999 | } else { |
||
1000 | $objWriter->writeAttribute('fitToHeight', '0'); |
||
1001 | } |
||
1002 | 159 | if ($worksheet->getPageSetup()->getFitToWidth() !== null) { |
|
1003 | 159 | $objWriter->writeAttribute('fitToWidth', $worksheet->getPageSetup()->getFitToWidth()); |
|
1004 | } else { |
||
1005 | $objWriter->writeAttribute('fitToWidth', '0'); |
||
1006 | } |
||
1007 | 159 | if ($worksheet->getPageSetup()->getFirstPageNumber() !== null) { |
|
1008 | $objWriter->writeAttribute('firstPageNumber', $worksheet->getPageSetup()->getFirstPageNumber()); |
||
1009 | $objWriter->writeAttribute('useFirstPageNumber', '1'); |
||
1010 | } |
||
1011 | 159 | $objWriter->writeAttribute('pageOrder', $worksheet->getPageSetup()->getPageOrder()); |
|
1012 | |||
1013 | 159 | $getUnparsedLoadedData = $worksheet->getParent()->getUnparsedLoadedData(); |
|
1014 | 159 | if (isset($getUnparsedLoadedData['sheets'][$worksheet->getCodeName()]['pageSetupRelId'])) { |
|
1015 | 8 | $objWriter->writeAttribute('r:id', $getUnparsedLoadedData['sheets'][$worksheet->getCodeName()]['pageSetupRelId']); |
|
1016 | } |
||
1017 | |||
1018 | 159 | $objWriter->endElement(); |
|
1019 | 159 | } |
|
1020 | |||
1021 | /** |
||
1022 | * Write Header / Footer. |
||
1023 | * |
||
1024 | * @param XMLWriter $objWriter XML Writer |
||
1025 | * @param PhpspreadsheetWorksheet $worksheet Worksheet |
||
1026 | */ |
||
1027 | 159 | private function writeHeaderFooter(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
1028 | { |
||
1029 | // headerFooter |
||
1030 | 159 | $objWriter->startElement('headerFooter'); |
|
1031 | 159 | $objWriter->writeAttribute('differentOddEven', ($worksheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false')); |
|
1032 | 159 | $objWriter->writeAttribute('differentFirst', ($worksheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false')); |
|
1033 | 159 | $objWriter->writeAttribute('scaleWithDoc', ($worksheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false')); |
|
1034 | 159 | $objWriter->writeAttribute('alignWithMargins', ($worksheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false')); |
|
1035 | |||
1036 | 159 | $objWriter->writeElement('oddHeader', $worksheet->getHeaderFooter()->getOddHeader()); |
|
1037 | 159 | $objWriter->writeElement('oddFooter', $worksheet->getHeaderFooter()->getOddFooter()); |
|
1038 | 159 | $objWriter->writeElement('evenHeader', $worksheet->getHeaderFooter()->getEvenHeader()); |
|
1039 | 159 | $objWriter->writeElement('evenFooter', $worksheet->getHeaderFooter()->getEvenFooter()); |
|
1040 | 159 | $objWriter->writeElement('firstHeader', $worksheet->getHeaderFooter()->getFirstHeader()); |
|
1041 | 159 | $objWriter->writeElement('firstFooter', $worksheet->getHeaderFooter()->getFirstFooter()); |
|
1042 | 159 | $objWriter->endElement(); |
|
1043 | 159 | } |
|
1044 | |||
1045 | /** |
||
1046 | * Write Breaks. |
||
1047 | * |
||
1048 | * @param XMLWriter $objWriter XML Writer |
||
1049 | * @param PhpspreadsheetWorksheet $worksheet Worksheet |
||
1050 | */ |
||
1051 | 159 | private function writeBreaks(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
1052 | { |
||
1053 | // Get row and column breaks |
||
1054 | 159 | $aRowBreaks = []; |
|
1055 | 159 | $aColumnBreaks = []; |
|
1056 | 159 | foreach ($worksheet->getBreaks() as $cell => $breakType) { |
|
1057 | 1 | if ($breakType == PhpspreadsheetWorksheet::BREAK_ROW) { |
|
1058 | 1 | $aRowBreaks[] = $cell; |
|
1059 | } elseif ($breakType == PhpspreadsheetWorksheet::BREAK_COLUMN) { |
||
1060 | $aColumnBreaks[] = $cell; |
||
1061 | } |
||
1062 | } |
||
1063 | |||
1064 | // rowBreaks |
||
1065 | 159 | if (!empty($aRowBreaks)) { |
|
1066 | 1 | $objWriter->startElement('rowBreaks'); |
|
1067 | 1 | $objWriter->writeAttribute('count', count($aRowBreaks)); |
|
1068 | 1 | $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks)); |
|
1069 | |||
1070 | 1 | foreach ($aRowBreaks as $cell) { |
|
1071 | 1 | $coords = Coordinate::coordinateFromString($cell); |
|
1072 | |||
1073 | 1 | $objWriter->startElement('brk'); |
|
1074 | 1 | $objWriter->writeAttribute('id', $coords[1]); |
|
1075 | 1 | $objWriter->writeAttribute('man', '1'); |
|
1076 | 1 | $objWriter->endElement(); |
|
1077 | } |
||
1078 | |||
1079 | 1 | $objWriter->endElement(); |
|
1080 | } |
||
1081 | |||
1082 | // Second, write column breaks |
||
1083 | 159 | if (!empty($aColumnBreaks)) { |
|
1084 | $objWriter->startElement('colBreaks'); |
||
1085 | $objWriter->writeAttribute('count', count($aColumnBreaks)); |
||
1086 | $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks)); |
||
1087 | |||
1088 | foreach ($aColumnBreaks as $cell) { |
||
1089 | $coords = Coordinate::coordinateFromString($cell); |
||
1090 | |||
1091 | $objWriter->startElement('brk'); |
||
1092 | $objWriter->writeAttribute('id', Coordinate::columnIndexFromString($coords[0]) - 1); |
||
1093 | $objWriter->writeAttribute('man', '1'); |
||
1094 | $objWriter->endElement(); |
||
1095 | } |
||
1096 | |||
1097 | $objWriter->endElement(); |
||
1098 | } |
||
1099 | 159 | } |
|
1100 | |||
1101 | /** |
||
1102 | * Write SheetData. |
||
1103 | * |
||
1104 | * @param XMLWriter $objWriter XML Writer |
||
1105 | * @param PhpspreadsheetWorksheet $worksheet Worksheet |
||
1106 | * @param string[] $pStringTable String table |
||
1107 | */ |
||
1108 | 159 | private function writeSheetData(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet, array $pStringTable): void |
|
1109 | { |
||
1110 | // Flipped stringtable, for faster index searching |
||
1111 | 159 | $aFlippedStringTable = $this->getParentWriter()->getWriterPartstringtable()->flipStringTable($pStringTable); |
|
1112 | |||
1113 | // sheetData |
||
1114 | 159 | $objWriter->startElement('sheetData'); |
|
1115 | |||
1116 | // Get column count |
||
1117 | 159 | $colCount = Coordinate::columnIndexFromString($worksheet->getHighestColumn()); |
|
1118 | |||
1119 | // Highest row number |
||
1120 | 159 | $highestRow = $worksheet->getHighestRow(); |
|
1121 | |||
1122 | // Loop through cells |
||
1123 | 159 | $cellsByRow = []; |
|
1124 | 159 | foreach ($worksheet->getCoordinates() as $coordinate) { |
|
1125 | 151 | $cellAddress = Coordinate::coordinateFromString($coordinate); |
|
1126 | 151 | $cellsByRow[$cellAddress[1]][] = $coordinate; |
|
1127 | } |
||
1128 | |||
1129 | 159 | $currentRow = 0; |
|
1130 | 159 | while ($currentRow++ < $highestRow) { |
|
1131 | // Get row dimension |
||
1132 | 159 | $rowDimension = $worksheet->getRowDimension($currentRow); |
|
1133 | |||
1134 | // Write current row? |
||
1135 | 159 | $writeCurrentRow = isset($cellsByRow[$currentRow]) || $rowDimension->getRowHeight() >= 0 || $rowDimension->getVisible() == false || $rowDimension->getCollapsed() == true || $rowDimension->getOutlineLevel() > 0 || $rowDimension->getXfIndex() !== null; |
|
1136 | |||
1137 | 159 | if ($writeCurrentRow) { |
|
1138 | // Start a new row |
||
1139 | 151 | $objWriter->startElement('row'); |
|
1140 | 151 | $objWriter->writeAttribute('r', $currentRow); |
|
1141 | 151 | $objWriter->writeAttribute('spans', '1:' . $colCount); |
|
1142 | |||
1143 | // Row dimensions |
||
1144 | 151 | if ($rowDimension->getRowHeight() >= 0) { |
|
1145 | 12 | $objWriter->writeAttribute('customHeight', '1'); |
|
1146 | 12 | $objWriter->writeAttribute('ht', StringHelper::formatNumber($rowDimension->getRowHeight())); |
|
1147 | } |
||
1148 | |||
1149 | // Row visibility |
||
1150 | 151 | if (!$rowDimension->getVisible() === true) { |
|
1151 | 5 | $objWriter->writeAttribute('hidden', 'true'); |
|
1152 | } |
||
1153 | |||
1154 | // Collapsed |
||
1155 | 151 | if ($rowDimension->getCollapsed() === true) { |
|
1156 | $objWriter->writeAttribute('collapsed', 'true'); |
||
1157 | } |
||
1158 | |||
1159 | // Outline level |
||
1160 | 151 | if ($rowDimension->getOutlineLevel() > 0) { |
|
1161 | $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel()); |
||
1162 | } |
||
1163 | |||
1164 | // Style |
||
1165 | 151 | if ($rowDimension->getXfIndex() !== null) { |
|
1166 | $objWriter->writeAttribute('s', $rowDimension->getXfIndex()); |
||
1167 | $objWriter->writeAttribute('customFormat', '1'); |
||
1168 | } |
||
1169 | |||
1170 | // Write cells |
||
1171 | 151 | if (isset($cellsByRow[$currentRow])) { |
|
1172 | 151 | foreach ($cellsByRow[$currentRow] as $cellAddress) { |
|
1173 | // Write cell |
||
1174 | 151 | $this->writeCell($objWriter, $worksheet, $cellAddress, $aFlippedStringTable); |
|
1175 | } |
||
1176 | } |
||
1177 | |||
1178 | // End row |
||
1179 | 151 | $objWriter->endElement(); |
|
1180 | } |
||
1181 | } |
||
1182 | |||
1183 | 159 | $objWriter->endElement(); |
|
1184 | 159 | } |
|
1185 | |||
1186 | /** |
||
1187 | * @param RichText|string $cellValue |
||
1188 | */ |
||
1189 | 8 | private function writeCellInlineStr(XMLWriter $objWriter, string $mappedType, $cellValue): void |
|
1190 | { |
||
1191 | 8 | $objWriter->writeAttribute('t', $mappedType); |
|
1192 | 8 | if (!$cellValue instanceof RichText) { |
|
1193 | $objWriter->writeElement( |
||
1194 | 't', |
||
1195 | StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue, Settings::htmlEntityFlags())) |
||
1196 | ); |
||
1197 | 8 | } elseif ($cellValue instanceof RichText) { |
|
1198 | 8 | $objWriter->startElement('is'); |
|
1199 | 8 | $this->getParentWriter()->getWriterPartstringtable()->writeRichText($objWriter, $cellValue); |
|
1200 | 8 | $objWriter->endElement(); |
|
1201 | } |
||
1202 | 8 | } |
|
1203 | |||
1204 | /** |
||
1205 | * @param RichText|string $cellValue |
||
1206 | * @param string[] $pFlippedStringTable |
||
1207 | */ |
||
1208 | 105 | private function writeCellString(XMLWriter $objWriter, string $mappedType, $cellValue, array $pFlippedStringTable): void |
|
1215 | } |
||
1216 | 105 | } |
|
1217 | |||
1218 | /** |
||
1219 | * @param float|int $cellValue |
||
1220 | */ |
||
1221 | 91 | private function writeCellNumeric(XMLWriter $objWriter, $cellValue): void |
|
1222 | { |
||
1223 | //force a decimal to be written if the type is float |
||
1224 | 91 | if (is_float($cellValue)) { |
|
1225 | // force point as decimal separator in case current locale uses comma |
||
1226 | 41 | $cellValue = str_replace(',', '.', (string) $cellValue); |
|
1227 | 41 | if (strpos($cellValue, '.') === false) { |
|
1228 | 26 | $cellValue = $cellValue . '.0'; |
|
1229 | } |
||
1230 | } |
||
1231 | 91 | $objWriter->writeElement('v', $cellValue); |
|
1232 | 91 | } |
|
1233 | |||
1234 | 9 | private function writeCellBoolean(XMLWriter $objWriter, string $mappedType, bool $cellValue): void |
|
1235 | { |
||
1236 | 9 | $objWriter->writeAttribute('t', $mappedType); |
|
1237 | 9 | $objWriter->writeElement('v', $cellValue ? '1' : '0'); |
|
1238 | 9 | } |
|
1239 | |||
1240 | 7 | private function writeCellError(XMLWriter $objWriter, string $mappedType, string $cellValue, string $formulaerr = '#NULL!'): void |
|
1241 | { |
||
1242 | 7 | $objWriter->writeAttribute('t', $mappedType); |
|
1243 | 7 | $cellIsFormula = substr($cellValue, 0, 1) === '='; |
|
1244 | 7 | self::writeElementIf($objWriter, $cellIsFormula, 'f', Xlfn::addXlfnStripEquals($cellValue)); |
|
1245 | 7 | $objWriter->writeElement('v', $cellIsFormula ? $formulaerr : $cellValue); |
|
1246 | 7 | } |
|
1247 | |||
1248 | 43 | private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell $pCell): void |
|
1249 | { |
||
1250 | 43 | $calculatedValue = $this->getParentWriter()->getPreCalculateFormulas() ? $pCell->getCalculatedValue() : $cellValue; |
|
1251 | 43 | if (is_string($calculatedValue)) { |
|
1252 | 21 | if (\PhpOffice\PhpSpreadsheet\Calculation\Functions::isError($calculatedValue)) { |
|
1253 | 6 | $this->writeCellError($objWriter, 'e', $cellValue, $calculatedValue); |
|
1254 | |||
1255 | 6 | return; |
|
1256 | } |
||
1257 | 21 | $objWriter->writeAttribute('t', 'str'); |
|
1258 | 21 | $calculatedValue = StringHelper::controlCharacterPHP2OOXML($calculatedValue); |
|
1259 | 36 | } elseif (is_bool($calculatedValue)) { |
|
1260 | 6 | $objWriter->writeAttribute('t', 'b'); |
|
1261 | 6 | $calculatedValue = (int) $calculatedValue; |
|
1262 | } |
||
1263 | // array values are not yet supported |
||
1264 | //$attributes = $pCell->getFormulaAttributes(); |
||
1265 | //if (($attributes['t'] ?? null) === 'array') { |
||
1266 | // $objWriter->startElement('f'); |
||
1267 | // $objWriter->writeAttribute('t', 'array'); |
||
1268 | // $objWriter->writeAttribute('ref', $pCellAddress); |
||
1269 | // $objWriter->writeAttribute('aca', '1'); |
||
1270 | // $objWriter->writeAttribute('ca', '1'); |
||
1271 | // $objWriter->text(substr($cellValue, 1)); |
||
1272 | // $objWriter->endElement(); |
||
1273 | //} else { |
||
1274 | // $objWriter->writeElement('f', Xlfn::addXlfnStripEquals($cellValue)); |
||
1275 | //} |
||
1276 | 43 | $objWriter->writeElement('f', Xlfn::addXlfnStripEquals($cellValue)); |
|
1277 | 43 | self::writeElementIf( |
|
1278 | 43 | $objWriter, |
|
1279 | 43 | $this->getParentWriter()->getOffice2003Compatibility() === false, |
|
1280 | 'v', |
||
1281 | 43 | ($this->getParentWriter()->getPreCalculateFormulas() && !is_array($calculatedValue) && substr($calculatedValue ?? '', 0, 1) !== '#') |
|
1282 | 43 | ? StringHelper::formatNumber($calculatedValue) : '0' |
|
1283 | ); |
||
1284 | 43 | } |
|
1285 | |||
1286 | /** |
||
1287 | * Write Cell. |
||
1288 | * |
||
1289 | * @param XMLWriter $objWriter XML Writer |
||
1290 | * @param PhpspreadsheetWorksheet $worksheet Worksheet |
||
1291 | * @param string $pCellAddress Cell Address |
||
1292 | * @param string[] $pFlippedStringTable String table (flipped), for faster index searching |
||
1293 | */ |
||
1294 | 151 | private function writeCell(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet, string $pCellAddress, array $pFlippedStringTable): void |
|
1295 | { |
||
1296 | // Cell |
||
1297 | 151 | $pCell = $worksheet->getCell($pCellAddress); |
|
1298 | 151 | $objWriter->startElement('c'); |
|
1299 | 151 | $objWriter->writeAttribute('r', $pCellAddress); |
|
1300 | |||
1301 | // Sheet styles |
||
1302 | 151 | $xfi = $pCell->getXfIndex(); |
|
1303 | 151 | self::writeAttributeIf($objWriter, $xfi, 's', $xfi); |
|
1304 | |||
1305 | // If cell value is supplied, write cell value |
||
1306 | 151 | $cellValue = $pCell->getValue(); |
|
1307 | 151 | if (is_object($cellValue) || $cellValue !== '') { |
|
1308 | // Map type |
||
1309 | 151 | $mappedType = $pCell->getDataType(); |
|
1310 | |||
1311 | // Write data depending on its type |
||
1312 | 151 | switch (strtolower($mappedType)) { |
|
1313 | 151 | case 'inlinestr': // Inline string |
|
1314 | 8 | $this->writeCellInlineStr($objWriter, $mappedType, $cellValue); |
|
1315 | |||
1316 | 8 | break; |
|
1317 | 150 | case 's': // String |
|
1318 | 105 | $this->writeCellString($objWriter, $mappedType, $cellValue, $pFlippedStringTable); |
|
1319 | |||
1320 | 105 | break; |
|
1321 | 120 | case 'f': // Formula |
|
1322 | 43 | $this->writeCellFormula($objWriter, $cellValue, $pCell); |
|
1323 | |||
1324 | 43 | break; |
|
1325 | 107 | case 'n': // Numeric |
|
1326 | 91 | $this->writeCellNumeric($objWriter, $cellValue); |
|
1327 | |||
1328 | 91 | break; |
|
1329 | 37 | case 'b': // Boolean |
|
1330 | 9 | $this->writeCellBoolean($objWriter, $mappedType, $cellValue); |
|
1331 | |||
1332 | 9 | break; |
|
1333 | 32 | case 'e': // Error |
|
1334 | 1 | $this->writeCellError($objWriter, $mappedType, $cellValue); |
|
1335 | } |
||
1336 | } |
||
1337 | |||
1338 | 151 | $objWriter->endElement(); |
|
1339 | 151 | } |
|
1340 | |||
1341 | /** |
||
1342 | * Write Drawings. |
||
1343 | * |
||
1344 | * @param XMLWriter $objWriter XML Writer |
||
1345 | * @param PhpspreadsheetWorksheet $worksheet Worksheet |
||
1346 | * @param bool $includeCharts Flag indicating if we should include drawing details for charts |
||
1347 | */ |
||
1348 | 159 | private function writeDrawings(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet, $includeCharts = false): void |
|
1349 | { |
||
1350 | 159 | $unparsedLoadedData = $worksheet->getParent()->getUnparsedLoadedData(); |
|
1351 | 159 | $hasUnparsedDrawing = isset($unparsedLoadedData['sheets'][$worksheet->getCodeName()]['drawingOriginalIds']); |
|
1352 | 159 | $chartCount = ($includeCharts) ? $worksheet->getChartCollection()->count() : 0; |
|
1353 | 159 | if ($chartCount == 0 && $worksheet->getDrawingCollection()->count() == 0 && !$hasUnparsedDrawing) { |
|
1354 | 132 | return; |
|
1355 | } |
||
1356 | |||
1357 | // If sheet contains drawings, add the relationships |
||
1358 | 32 | $objWriter->startElement('drawing'); |
|
1359 | |||
1360 | 32 | $rId = 'rId1'; |
|
1361 | 32 | if (isset($unparsedLoadedData['sheets'][$worksheet->getCodeName()]['drawingOriginalIds'])) { |
|
1362 | 9 | $drawingOriginalIds = $unparsedLoadedData['sheets'][$worksheet->getCodeName()]['drawingOriginalIds']; |
|
1363 | // take first. In future can be overriten |
||
1364 | // (! synchronize with \PhpOffice\PhpSpreadsheet\Writer\Xlsx\Rels::writeWorksheetRelationships) |
||
1365 | 9 | $rId = reset($drawingOriginalIds); |
|
1366 | } |
||
1367 | |||
1368 | 32 | $objWriter->writeAttribute('r:id', $rId); |
|
1369 | 32 | $objWriter->endElement(); |
|
1370 | 32 | } |
|
1371 | |||
1372 | /** |
||
1373 | * Write LegacyDrawing. |
||
1374 | * |
||
1375 | * @param XMLWriter $objWriter XML Writer |
||
1376 | * @param PhpspreadsheetWorksheet $worksheet Worksheet |
||
1377 | */ |
||
1378 | 159 | private function writeLegacyDrawing(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
1379 | { |
||
1380 | // If sheet contains comments, add the relationships |
||
1381 | 159 | if (count($worksheet->getComments()) > 0) { |
|
1382 | 11 | $objWriter->startElement('legacyDrawing'); |
|
1383 | 11 | $objWriter->writeAttribute('r:id', 'rId_comments_vml1'); |
|
1384 | 11 | $objWriter->endElement(); |
|
1385 | } |
||
1386 | 159 | } |
|
1387 | |||
1388 | /** |
||
1389 | * Write LegacyDrawingHF. |
||
1390 | * |
||
1391 | * @param XMLWriter $objWriter XML Writer |
||
1392 | * @param PhpspreadsheetWorksheet $worksheet Worksheet |
||
1393 | */ |
||
1394 | 159 | private function writeLegacyDrawingHF(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
1395 | { |
||
1396 | // If sheet contains images, add the relationships |
||
1397 | 159 | if (count($worksheet->getHeaderFooter()->getImages()) > 0) { |
|
1398 | 1 | $objWriter->startElement('legacyDrawingHF'); |
|
1399 | 1 | $objWriter->writeAttribute('r:id', 'rId_headerfooter_vml1'); |
|
1400 | 1 | $objWriter->endElement(); |
|
1401 | } |
||
1402 | 159 | } |
|
1403 | |||
1404 | 159 | private function writeAlternateContent(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
1412 | } |
||
1413 | 1 | } |
|
1414 | |||
1415 | /** |
||
1416 | * write <ExtLst> |
||
1417 | * only implementation conditionalFormattings. |
||
1418 | * |
||
1419 | * @url https://docs.microsoft.com/en-us/openspecs/office_standards/ms-xlsx/07d607af-5618-4ca2-b683-6a78dc0d9627 |
||
1420 | */ |
||
1421 | 159 | private function writeExtLst(XMLWriter $objWriter, PhpspreadsheetWorksheet $worksheet): void |
|
1422 | { |
||
1423 | 159 | $conditionalFormattingRuleExtList = []; |
|
1424 | 159 | foreach ($worksheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { |
|
1425 | /** @var Conditional $conditional */ |
||
1426 | 11 | foreach ($conditionalStyles as $conditional) { |
|
1427 | 11 | $dataBar = $conditional->getDataBar(); |
|
1428 | // @phpstan-ignore-next-line |
||
1429 | 11 | if ($dataBar && $dataBar->getConditionalFormattingRuleExt()) { |
|
1430 | 1 | $conditionalFormattingRuleExtList[] = $dataBar->getConditionalFormattingRuleExt(); |
|
1431 | } |
||
1432 | } |
||
1433 | } |
||
1434 | |||
1435 | 159 | if (count($conditionalFormattingRuleExtList) > 0) { |
|
1436 | 1 | $conditionalFormattingRuleExtNsPrefix = 'x14'; |
|
1437 | 1 | $objWriter->startElement('extLst'); |
|
1438 | 1 | $objWriter->startElement('ext'); |
|
1447 | } |
||
1448 | 159 | } |
|
1449 | } |
||
1450 |