Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
namespace PhpOffice\PhpSpreadsheet\Writer;
4
 
5
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
6
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
7
use PhpOffice\PhpSpreadsheet\HashTable;
8
use PhpOffice\PhpSpreadsheet\Spreadsheet;
9
use PhpOffice\PhpSpreadsheet\Style\Borders;
10
use PhpOffice\PhpSpreadsheet\Style\Conditional;
11
use PhpOffice\PhpSpreadsheet\Style\Fill;
12
use PhpOffice\PhpSpreadsheet\Style\Font;
13
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
14
use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing;
15
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing as WorksheetDrawing;
16
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing;
17
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
18
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Chart;
19
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Comments;
20
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\ContentTypes;
21
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\DocProps;
22
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Drawing;
23
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Rels;
24
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\RelsRibbon;
25
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\RelsVBA;
26
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\StringTable;
27
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Style;
28
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Table;
29
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Theme;
30
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Workbook;
31
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Worksheet;
32
use ZipArchive;
33
use ZipStream\Exception\OverflowException;
34
use ZipStream\ZipStream;
35
 
36
class Xlsx extends BaseWriter
37
{
38
    /**
39
     * Office2003 compatibility.
40
     *
41
     * @var bool
42
     */
43
    private $office2003compatibility = false;
44
 
45
    /**
46
     * Private Spreadsheet.
47
     *
48
     * @var Spreadsheet
49
     */
50
    private $spreadSheet;
51
 
52
    /**
53
     * Private string table.
54
     *
55
     * @var string[]
56
     */
57
    private $stringTable = [];
58
 
59
    /**
60
     * Private unique Conditional HashTable.
61
     *
62
     * @var HashTable<Conditional>
63
     */
64
    private $stylesConditionalHashTable;
65
 
66
    /**
67
     * Private unique Style HashTable.
68
     *
69
     * @var HashTable<\PhpOffice\PhpSpreadsheet\Style\Style>
70
     */
71
    private $styleHashTable;
72
 
73
    /**
74
     * Private unique Fill HashTable.
75
     *
76
     * @var HashTable<Fill>
77
     */
78
    private $fillHashTable;
79
 
80
    /**
81
     * Private unique \PhpOffice\PhpSpreadsheet\Style\Font HashTable.
82
     *
83
     * @var HashTable<Font>
84
     */
85
    private $fontHashTable;
86
 
87
    /**
88
     * Private unique Borders HashTable.
89
     *
90
     * @var HashTable<Borders>
91
     */
92
    private $bordersHashTable;
93
 
94
    /**
95
     * Private unique NumberFormat HashTable.
96
     *
97
     * @var HashTable<NumberFormat>
98
     */
99
    private $numFmtHashTable;
100
 
101
    /**
102
     * Private unique \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\BaseDrawing HashTable.
103
     *
104
     * @var HashTable<BaseDrawing>
105
     */
106
    private $drawingHashTable;
107
 
108
    /**
109
     * Private handle for zip stream.
110
     *
111
     * @var ZipStream
112
     */
113
    private $zip;
114
 
115
    /**
116
     * @var Chart
117
     */
118
    private $writerPartChart;
119
 
120
    /**
121
     * @var Comments
122
     */
123
    private $writerPartComments;
124
 
125
    /**
126
     * @var ContentTypes
127
     */
128
    private $writerPartContentTypes;
129
 
130
    /**
131
     * @var DocProps
132
     */
133
    private $writerPartDocProps;
134
 
135
    /**
136
     * @var Drawing
137
     */
138
    private $writerPartDrawing;
139
 
140
    /**
141
     * @var Rels
142
     */
143
    private $writerPartRels;
144
 
145
    /**
146
     * @var RelsRibbon
147
     */
148
    private $writerPartRelsRibbon;
149
 
150
    /**
151
     * @var RelsVBA
152
     */
153
    private $writerPartRelsVBA;
154
 
155
    /**
156
     * @var StringTable
157
     */
158
    private $writerPartStringTable;
159
 
160
    /**
161
     * @var Style
162
     */
163
    private $writerPartStyle;
164
 
165
    /**
166
     * @var Theme
167
     */
168
    private $writerPartTheme;
169
 
170
    /**
171
     * @var Table
172
     */
173
    private $writerPartTable;
174
 
175
    /**
176
     * @var Workbook
177
     */
178
    private $writerPartWorkbook;
179
 
180
    /**
181
     * @var Worksheet
182
     */
183
    private $writerPartWorksheet;
184
 
185
    /**
186
     * Create a new Xlsx Writer.
187
     */
188
    public function __construct(Spreadsheet $spreadsheet)
189
    {
190
        // Assign PhpSpreadsheet
191
        $this->setSpreadsheet($spreadsheet);
192
 
193
        $this->writerPartChart = new Chart($this);
194
        $this->writerPartComments = new Comments($this);
195
        $this->writerPartContentTypes = new ContentTypes($this);
196
        $this->writerPartDocProps = new DocProps($this);
197
        $this->writerPartDrawing = new Drawing($this);
198
        $this->writerPartRels = new Rels($this);
199
        $this->writerPartRelsRibbon = new RelsRibbon($this);
200
        $this->writerPartRelsVBA = new RelsVBA($this);
201
        $this->writerPartStringTable = new StringTable($this);
202
        $this->writerPartStyle = new Style($this);
203
        $this->writerPartTheme = new Theme($this);
204
        $this->writerPartTable = new Table($this);
205
        $this->writerPartWorkbook = new Workbook($this);
206
        $this->writerPartWorksheet = new Worksheet($this);
207
 
208
        // Set HashTable variables
209
        // @phpstan-ignore-next-line
210
        $this->bordersHashTable = new HashTable();
211
        // @phpstan-ignore-next-line
212
        $this->drawingHashTable = new HashTable();
213
        // @phpstan-ignore-next-line
214
        $this->fillHashTable = new HashTable();
215
        // @phpstan-ignore-next-line
216
        $this->fontHashTable = new HashTable();
217
        // @phpstan-ignore-next-line
218
        $this->numFmtHashTable = new HashTable();
219
        // @phpstan-ignore-next-line
220
        $this->styleHashTable = new HashTable();
221
        // @phpstan-ignore-next-line
222
        $this->stylesConditionalHashTable = new HashTable();
223
    }
224
 
225
    public function getWriterPartChart(): Chart
226
    {
227
        return $this->writerPartChart;
228
    }
229
 
230
    public function getWriterPartComments(): Comments
231
    {
232
        return $this->writerPartComments;
233
    }
234
 
235
    public function getWriterPartContentTypes(): ContentTypes
236
    {
237
        return $this->writerPartContentTypes;
238
    }
239
 
240
    public function getWriterPartDocProps(): DocProps
241
    {
242
        return $this->writerPartDocProps;
243
    }
244
 
245
    public function getWriterPartDrawing(): Drawing
246
    {
247
        return $this->writerPartDrawing;
248
    }
249
 
250
    public function getWriterPartRels(): Rels
251
    {
252
        return $this->writerPartRels;
253
    }
254
 
255
    public function getWriterPartRelsRibbon(): RelsRibbon
256
    {
257
        return $this->writerPartRelsRibbon;
258
    }
259
 
260
    public function getWriterPartRelsVBA(): RelsVBA
261
    {
262
        return $this->writerPartRelsVBA;
263
    }
264
 
265
    public function getWriterPartStringTable(): StringTable
266
    {
267
        return $this->writerPartStringTable;
268
    }
269
 
270
    public function getWriterPartStyle(): Style
271
    {
272
        return $this->writerPartStyle;
273
    }
274
 
275
    public function getWriterPartTheme(): Theme
276
    {
277
        return $this->writerPartTheme;
278
    }
279
 
280
    public function getWriterPartTable(): Table
281
    {
282
        return $this->writerPartTable;
283
    }
284
 
285
    public function getWriterPartWorkbook(): Workbook
286
    {
287
        return $this->writerPartWorkbook;
288
    }
289
 
290
    public function getWriterPartWorksheet(): Worksheet
291
    {
292
        return $this->writerPartWorksheet;
293
    }
294
 
295
    /**
296
     * Save PhpSpreadsheet to file.
297
     *
298
     * @param resource|string $filename
299
     */
300
    public function save($filename, int $flags = 0): void
301
    {
302
        $this->processFlags($flags);
303
 
304
        // garbage collect
305
        $this->pathNames = [];
306
        $this->spreadSheet->garbageCollect();
307
 
308
        $saveDebugLog = Calculation::getInstance($this->spreadSheet)->getDebugLog()->getWriteDebugLog();
309
        Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog(false);
310
        $saveDateReturnType = Functions::getReturnDateType();
311
        Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
312
 
313
        // Create string lookup table
314
        $this->stringTable = [];
315
        for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
316
            $this->stringTable = $this->getWriterPartStringTable()->createStringTable($this->spreadSheet->getSheet($i), $this->stringTable);
317
        }
318
 
319
        // Create styles dictionaries
320
        $this->styleHashTable->addFromSource($this->getWriterPartStyle()->allStyles($this->spreadSheet));
321
        $this->stylesConditionalHashTable->addFromSource($this->getWriterPartStyle()->allConditionalStyles($this->spreadSheet));
322
        $this->fillHashTable->addFromSource($this->getWriterPartStyle()->allFills($this->spreadSheet));
323
        $this->fontHashTable->addFromSource($this->getWriterPartStyle()->allFonts($this->spreadSheet));
324
        $this->bordersHashTable->addFromSource($this->getWriterPartStyle()->allBorders($this->spreadSheet));
325
        $this->numFmtHashTable->addFromSource($this->getWriterPartStyle()->allNumberFormats($this->spreadSheet));
326
 
327
        // Create drawing dictionary
328
        $this->drawingHashTable->addFromSource($this->getWriterPartDrawing()->allDrawings($this->spreadSheet));
329
 
330
        $zipContent = [];
331
        // Add [Content_Types].xml to ZIP file
332
        $zipContent['[Content_Types].xml'] = $this->getWriterPartContentTypes()->writeContentTypes($this->spreadSheet, $this->includeCharts);
333
 
334
        //if hasMacros, add the vbaProject.bin file, Certificate file(if exists)
335
        if ($this->spreadSheet->hasMacros()) {
336
            $macrosCode = $this->spreadSheet->getMacrosCode();
337
            if ($macrosCode !== null) {
338
                // we have the code ?
339
                $zipContent['xl/vbaProject.bin'] = $macrosCode; //allways in 'xl', allways named vbaProject.bin
340
                if ($this->spreadSheet->hasMacrosCertificate()) {
341
                    //signed macros ?
342
                    // Yes : add the certificate file and the related rels file
343
                    $zipContent['xl/vbaProjectSignature.bin'] = $this->spreadSheet->getMacrosCertificate();
344
                    $zipContent['xl/_rels/vbaProject.bin.rels'] = $this->getWriterPartRelsVBA()->writeVBARelationships();
345
                }
346
            }
347
        }
348
        //a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels)
349
        if ($this->spreadSheet->hasRibbon()) {
350
            $tmpRibbonTarget = $this->spreadSheet->getRibbonXMLData('target');
351
            $tmpRibbonTarget = is_string($tmpRibbonTarget) ? $tmpRibbonTarget : '';
352
            $zipContent[$tmpRibbonTarget] = $this->spreadSheet->getRibbonXMLData('data');
353
            if ($this->spreadSheet->hasRibbonBinObjects()) {
354
                $tmpRootPath = dirname($tmpRibbonTarget) . '/';
355
                $ribbonBinObjects = $this->spreadSheet->getRibbonBinObjects('data'); //the files to write
356
                if (is_array($ribbonBinObjects)) {
357
                    foreach ($ribbonBinObjects as $aPath => $aContent) {
358
                        $zipContent[$tmpRootPath . $aPath] = $aContent;
359
                    }
360
                }
361
                //the rels for files
362
                $zipContent[$tmpRootPath . '_rels/' . basename($tmpRibbonTarget) . '.rels'] = $this->getWriterPartRelsRibbon()->writeRibbonRelationships($this->spreadSheet);
363
            }
364
        }
365
 
366
        // Add relationships to ZIP file
367
        $zipContent['_rels/.rels'] = $this->getWriterPartRels()->writeRelationships($this->spreadSheet);
368
        $zipContent['xl/_rels/workbook.xml.rels'] = $this->getWriterPartRels()->writeWorkbookRelationships($this->spreadSheet);
369
 
370
        // Add document properties to ZIP file
371
        $zipContent['docProps/app.xml'] = $this->getWriterPartDocProps()->writeDocPropsApp($this->spreadSheet);
372
        $zipContent['docProps/core.xml'] = $this->getWriterPartDocProps()->writeDocPropsCore($this->spreadSheet);
373
        $customPropertiesPart = $this->getWriterPartDocProps()->writeDocPropsCustom($this->spreadSheet);
374
        if ($customPropertiesPart !== null) {
375
            $zipContent['docProps/custom.xml'] = $customPropertiesPart;
376
        }
377
 
378
        // Add theme to ZIP file
379
        $zipContent['xl/theme/theme1.xml'] = $this->getWriterPartTheme()->writeTheme($this->spreadSheet);
380
 
381
        // Add string table to ZIP file
382
        $zipContent['xl/sharedStrings.xml'] = $this->getWriterPartStringTable()->writeStringTable($this->stringTable);
383
 
384
        // Add styles to ZIP file
385
        $zipContent['xl/styles.xml'] = $this->getWriterPartStyle()->writeStyles($this->spreadSheet);
386
 
387
        // Add workbook to ZIP file
388
        $zipContent['xl/workbook.xml'] = $this->getWriterPartWorkbook()->writeWorkbook($this->spreadSheet, $this->preCalculateFormulas);
389
 
390
        $chartCount = 0;
391
        // Add worksheets
392
        for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
393
            $zipContent['xl/worksheets/sheet' . ($i + 1) . '.xml'] = $this->getWriterPartWorksheet()->writeWorksheet($this->spreadSheet->getSheet($i), $this->stringTable, $this->includeCharts);
394
            if ($this->includeCharts) {
395
                $charts = $this->spreadSheet->getSheet($i)->getChartCollection();
396
                if (count($charts) > 0) {
397
                    foreach ($charts as $chart) {
398
                        $zipContent['xl/charts/chart' . ($chartCount + 1) . '.xml'] = $this->getWriterPartChart()->writeChart($chart, $this->preCalculateFormulas);
399
                        ++$chartCount;
400
                    }
401
                }
402
            }
403
        }
404
 
405
        $chartRef1 = 0;
406
        $tableRef1 = 1;
407
        // Add worksheet relationships (drawings, ...)
408
        for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
409
            // Add relationships
410
            $zipContent['xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels'] = $this->getWriterPartRels()->writeWorksheetRelationships($this->spreadSheet->getSheet($i), ($i + 1), $this->includeCharts, $tableRef1);
411
 
412
            // Add unparsedLoadedData
413
            $sheetCodeName = $this->spreadSheet->getSheet($i)->getCodeName();
414
            $unparsedLoadedData = $this->spreadSheet->getUnparsedLoadedData();
415
            if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['ctrlProps'])) {
416
                foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['ctrlProps'] as $ctrlProp) {
417
                    $zipContent[$ctrlProp['filePath']] = $ctrlProp['content'];
418
                }
419
            }
420
            if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'])) {
421
                foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'] as $ctrlProp) {
422
                    $zipContent[$ctrlProp['filePath']] = $ctrlProp['content'];
423
                }
424
            }
425
 
426
            $drawings = $this->spreadSheet->getSheet($i)->getDrawingCollection();
427
            $drawingCount = count($drawings);
428
            if ($this->includeCharts) {
429
                $chartCount = $this->spreadSheet->getSheet($i)->getChartCount();
430
            }
431
 
432
            // Add drawing and image relationship parts
433
            if (($drawingCount > 0) || ($chartCount > 0)) {
434
                // Drawing relationships
435
                $zipContent['xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels'] = $this->getWriterPartRels()->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts);
436
 
437
                // Drawings
438
                $zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'] = $this->getWriterPartDrawing()->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts);
439
            } elseif (isset($unparsedLoadedData['sheets'][$sheetCodeName]['drawingAlternateContents'])) {
440
                // Drawings
441
                $zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'] = $this->getWriterPartDrawing()->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts);
442
            }
443
 
444
            // Add unparsed drawings
445
            if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['Drawings'])) {
446
                foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['Drawings'] as $relId => $drawingXml) {
447
                    $drawingFile = array_search($relId, $unparsedLoadedData['sheets'][$sheetCodeName]['drawingOriginalIds']);
448
                    if ($drawingFile !== false) {
449
                        //$drawingFile = ltrim($drawingFile, '.');
450
                        //$zipContent['xl' . $drawingFile] = $drawingXml;
451
                        $zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'] = $drawingXml;
452
                    }
453
                }
454
            }
455
 
456
            // Add comment relationship parts
457
            $legacy = $unparsedLoadedData['sheets'][$this->spreadSheet->getSheet($i)->getCodeName()]['legacyDrawing'] ?? null;
458
            if (count($this->spreadSheet->getSheet($i)->getComments()) > 0 || $legacy !== null) {
459
                // VML Comments relationships
460
                $zipContent['xl/drawings/_rels/vmlDrawing' . ($i + 1) . '.vml.rels'] = $this->getWriterPartRels()->writeVMLDrawingRelationships($this->spreadSheet->getSheet($i));
461
 
462
                // VML Comments
463
                $zipContent['xl/drawings/vmlDrawing' . ($i + 1) . '.vml'] = $legacy ?? $this->getWriterPartComments()->writeVMLComments($this->spreadSheet->getSheet($i));
464
            }
465
 
466
            // Comments
467
            if (count($this->spreadSheet->getSheet($i)->getComments()) > 0) {
468
                $zipContent['xl/comments' . ($i + 1) . '.xml'] = $this->getWriterPartComments()->writeComments($this->spreadSheet->getSheet($i));
469
 
470
                // Media
471
                foreach ($this->spreadSheet->getSheet($i)->getComments() as $comment) {
472
                    if ($comment->hasBackgroundImage()) {
473
                        $image = $comment->getBackgroundImage();
474
                        $zipContent['xl/media/' . $image->getMediaFilename()] = $this->processDrawing($image);
475
                    }
476
                }
477
            }
478
 
479
            // Add unparsed relationship parts
480
            if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['vmlDrawings'])) {
481
                foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['vmlDrawings'] as $vmlDrawing) {
482
                    if (!isset($zipContent[$vmlDrawing['filePath']])) {
483
                        $zipContent[$vmlDrawing['filePath']] = $vmlDrawing['content'];
484
                    }
485
                }
486
            }
487
 
488
            // Add header/footer relationship parts
489
            if (count($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) {
490
                // VML Drawings
491
                $zipContent['xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml'] = $this->getWriterPartDrawing()->writeVMLHeaderFooterImages($this->spreadSheet->getSheet($i));
492
 
493
                // VML Drawing relationships
494
                $zipContent['xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels'] = $this->getWriterPartRels()->writeHeaderFooterDrawingRelationships($this->spreadSheet->getSheet($i));
495
 
496
                // Media
497
                foreach ($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) {
498
                    $zipContent['xl/media/' . $image->getIndexedFilename()] = file_get_contents($image->getPath());
499
                }
500
            }
501
 
502
            // Add Table parts
503
            $tables = $this->spreadSheet->getSheet($i)->getTableCollection();
504
            foreach ($tables as $table) {
505
                $zipContent['xl/tables/table' . $tableRef1 . '.xml'] = $this->getWriterPartTable()->writeTable($table, $tableRef1++);
506
            }
507
        }
508
 
509
        // Add media
510
        for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) {
511
            if ($this->getDrawingHashTable()->getByIndex($i) instanceof WorksheetDrawing) {
512
                $imageContents = null;
513
                $imagePath = $this->getDrawingHashTable()->getByIndex($i)->getPath();
514
                if (strpos($imagePath, 'zip://') !== false) {
515
                    $imagePath = substr($imagePath, 6);
516
                    $imagePathSplitted = explode('#', $imagePath);
517
 
518
                    $imageZip = new ZipArchive();
519
                    $imageZip->open($imagePathSplitted[0]);
520
                    $imageContents = $imageZip->getFromName($imagePathSplitted[1]);
521
                    $imageZip->close();
522
                    unset($imageZip);
523
                } else {
524
                    $imageContents = file_get_contents($imagePath);
525
                }
526
 
527
                $zipContent['xl/media/' . $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()] = $imageContents;
528
            } elseif ($this->getDrawingHashTable()->getByIndex($i) instanceof MemoryDrawing) {
529
                ob_start();
530
                /** @var callable */
531
                $callable = $this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction();
532
                call_user_func(
533
                    $callable,
534
                    $this->getDrawingHashTable()->getByIndex($i)->getImageResource()
535
                );
536
                $imageContents = ob_get_contents();
537
                ob_end_clean();
538
 
539
                $zipContent['xl/media/' . $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()] = $imageContents;
540
            }
541
        }
542
 
543
        Functions::setReturnDateType($saveDateReturnType);
544
        Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);
545
 
546
        $this->openFileHandle($filename);
547
 
548
        $this->zip = ZipStream0::newZipStream($this->fileHandle);
549
 
550
        $this->addZipFiles($zipContent);
551
 
552
        // Close file
553
        try {
554
            $this->zip->finish();
555
        } catch (OverflowException $e) {
556
            throw new WriterException('Could not close resource.');
557
        }
558
 
559
        $this->maybeCloseFileHandle();
560
    }
561
 
562
    /**
563
     * Get Spreadsheet object.
564
     *
565
     * @return Spreadsheet
566
     */
567
    public function getSpreadsheet()
568
    {
569
        return $this->spreadSheet;
570
    }
571
 
572
    /**
573
     * Set Spreadsheet object.
574
     *
575
     * @param Spreadsheet $spreadsheet PhpSpreadsheet object
576
     *
577
     * @return $this
578
     */
579
    public function setSpreadsheet(Spreadsheet $spreadsheet)
580
    {
581
        $this->spreadSheet = $spreadsheet;
582
 
583
        return $this;
584
    }
585
 
586
    /**
587
     * Get string table.
588
     *
589
     * @return string[]
590
     */
591
    public function getStringTable()
592
    {
593
        return $this->stringTable;
594
    }
595
 
596
    /**
597
     * Get Style HashTable.
598
     *
599
     * @return HashTable<\PhpOffice\PhpSpreadsheet\Style\Style>
600
     */
601
    public function getStyleHashTable()
602
    {
603
        return $this->styleHashTable;
604
    }
605
 
606
    /**
607
     * Get Conditional HashTable.
608
     *
609
     * @return HashTable<Conditional>
610
     */
611
    public function getStylesConditionalHashTable()
612
    {
613
        return $this->stylesConditionalHashTable;
614
    }
615
 
616
    /**
617
     * Get Fill HashTable.
618
     *
619
     * @return HashTable<Fill>
620
     */
621
    public function getFillHashTable()
622
    {
623
        return $this->fillHashTable;
624
    }
625
 
626
    /**
627
     * Get \PhpOffice\PhpSpreadsheet\Style\Font HashTable.
628
     *
629
     * @return HashTable<Font>
630
     */
631
    public function getFontHashTable()
632
    {
633
        return $this->fontHashTable;
634
    }
635
 
636
    /**
637
     * Get Borders HashTable.
638
     *
639
     * @return HashTable<Borders>
640
     */
641
    public function getBordersHashTable()
642
    {
643
        return $this->bordersHashTable;
644
    }
645
 
646
    /**
647
     * Get NumberFormat HashTable.
648
     *
649
     * @return HashTable<NumberFormat>
650
     */
651
    public function getNumFmtHashTable()
652
    {
653
        return $this->numFmtHashTable;
654
    }
655
 
656
    /**
657
     * Get \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\BaseDrawing HashTable.
658
     *
659
     * @return HashTable<BaseDrawing>
660
     */
661
    public function getDrawingHashTable()
662
    {
663
        return $this->drawingHashTable;
664
    }
665
 
666
    /**
667
     * Get Office2003 compatibility.
668
     *
669
     * @return bool
670
     */
671
    public function getOffice2003Compatibility()
672
    {
673
        return $this->office2003compatibility;
674
    }
675
 
676
    /**
677
     * Set Office2003 compatibility.
678
     *
679
     * @param bool $office2003compatibility Office2003 compatibility?
680
     *
681
     * @return $this
682
     */
683
    public function setOffice2003Compatibility($office2003compatibility)
684
    {
685
        $this->office2003compatibility = $office2003compatibility;
686
 
687
        return $this;
688
    }
689
 
690
    /** @var array */
691
    private $pathNames = [];
692
 
693
    private function addZipFile(string $path, string $content): void
694
    {
695
        if (!in_array($path, $this->pathNames)) {
696
            $this->pathNames[] = $path;
697
            $this->zip->addFile($path, $content);
698
        }
699
    }
700
 
701
    private function addZipFiles(array $zipContent): void
702
    {
703
        foreach ($zipContent as $path => $content) {
704
            $this->addZipFile($path, $content);
705
        }
706
    }
707
 
708
    /**
709
     * @return mixed
710
     */
711
    private function processDrawing(WorksheetDrawing $drawing)
712
    {
713
        $data = null;
714
        $filename = $drawing->getPath();
715
        $imageData = getimagesize($filename);
716
 
717
        if (!empty($imageData)) {
718
            switch ($imageData[2]) {
719
                case 1: // GIF, not supported by BIFF8, we convert to PNG
720
                    $image = imagecreatefromgif($filename);
721
                    if ($image !== false) {
722
                        ob_start();
723
                        imagepng($image);
724
                        $data = ob_get_contents();
725
                        ob_end_clean();
726
                    }
727
 
728
                    break;
729
 
730
                case 2: // JPEG
731
                    $data = file_get_contents($filename);
732
 
733
                    break;
734
 
735
                case 3: // PNG
736
                    $data = file_get_contents($filename);
737
 
738
                    break;
739
 
740
                case 6: // Windows DIB (BMP), we convert to PNG
741
                    $image = imagecreatefrombmp($filename);
742
                    if ($image !== false) {
743
                        ob_start();
744
                        imagepng($image);
745
                        $data = ob_get_contents();
746
                        ob_end_clean();
747
                    }
748
 
749
                    break;
750
            }
751
        }
752
 
753
        return $data;
754
    }
755
}