chengkun
2025-09-11 364a083e94138f7ed2d8114bf6dbdfda4eaf2683
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<?php
 
namespace PhpOffice\PhpSpreadsheet\Writer;
 
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
use PhpOffice\PhpSpreadsheet\Writer\Ods\Content;
use PhpOffice\PhpSpreadsheet\Writer\Ods\Meta;
use PhpOffice\PhpSpreadsheet\Writer\Ods\MetaInf;
use PhpOffice\PhpSpreadsheet\Writer\Ods\Mimetype;
use PhpOffice\PhpSpreadsheet\Writer\Ods\Settings;
use PhpOffice\PhpSpreadsheet\Writer\Ods\Styles;
use PhpOffice\PhpSpreadsheet\Writer\Ods\Thumbnails;
use ZipStream\Exception\OverflowException;
use ZipStream\ZipStream;
 
class Ods extends BaseWriter
{
    /**
     * Private PhpSpreadsheet.
     */
    private Spreadsheet $spreadSheet;
 
    private Content $writerPartContent;
 
    private Meta $writerPartMeta;
 
    private MetaInf $writerPartMetaInf;
 
    private Mimetype $writerPartMimetype;
 
    private Settings $writerPartSettings;
 
    private Styles $writerPartStyles;
 
    private Thumbnails $writerPartThumbnails;
 
    /**
     * Create a new Ods.
     */
    public function __construct(Spreadsheet $spreadsheet)
    {
        $this->setSpreadsheet($spreadsheet);
 
        $this->writerPartContent = new Content($this);
        $this->writerPartMeta = new Meta($this);
        $this->writerPartMetaInf = new MetaInf($this);
        $this->writerPartMimetype = new Mimetype($this);
        $this->writerPartSettings = new Settings($this);
        $this->writerPartStyles = new Styles($this);
        $this->writerPartThumbnails = new Thumbnails($this);
    }
 
    public function getWriterPartContent(): Content
    {
        return $this->writerPartContent;
    }
 
    public function getWriterPartMeta(): Meta
    {
        return $this->writerPartMeta;
    }
 
    public function getWriterPartMetaInf(): MetaInf
    {
        return $this->writerPartMetaInf;
    }
 
    public function getWriterPartMimetype(): Mimetype
    {
        return $this->writerPartMimetype;
    }
 
    public function getWriterPartSettings(): Settings
    {
        return $this->writerPartSettings;
    }
 
    public function getWriterPartStyles(): Styles
    {
        return $this->writerPartStyles;
    }
 
    public function getWriterPartThumbnails(): Thumbnails
    {
        return $this->writerPartThumbnails;
    }
 
    /**
     * Save PhpSpreadsheet to file.
     *
     * @param resource|string $filename
     */
    public function save($filename, int $flags = 0): void
    {
        $this->processFlags($flags);
 
        // garbage collect
        $this->spreadSheet->garbageCollect();
 
        $this->openFileHandle($filename);
 
        $zip = $this->createZip();
 
        $zip->addFile('META-INF/manifest.xml', $this->getWriterPartMetaInf()->write());
        $zip->addFile('Thumbnails/thumbnail.png', $this->getWriterPartthumbnails()->write());
        // Settings always need to be written before Content; Styles after Content
        $zip->addFile('settings.xml', $this->getWriterPartsettings()->write());
        $zip->addFile('content.xml', $this->getWriterPartcontent()->write());
        $zip->addFile('meta.xml', $this->getWriterPartmeta()->write());
        $zip->addFile('mimetype', $this->getWriterPartmimetype()->write());
        $zip->addFile('styles.xml', $this->getWriterPartstyles()->write());
 
        // Close file
        try {
            $zip->finish();
        } catch (OverflowException) {
            throw new WriterException('Could not close resource.');
        }
 
        $this->maybeCloseFileHandle();
    }
 
    /**
     * Create zip object.
     */
    private function createZip(): ZipStream
    {
        // Try opening the ZIP file
        if (!is_resource($this->fileHandle)) {
            throw new WriterException('Could not open resource for writing.');
        }
 
        // Create new ZIP stream
        return ZipStream0::newZipStream($this->fileHandle);
    }
 
    /**
     * Get Spreadsheet object.
     */
    public function getSpreadsheet(): Spreadsheet
    {
        return $this->spreadSheet;
    }
 
    /**
     * Set Spreadsheet object.
     *
     * @param Spreadsheet $spreadsheet PhpSpreadsheet object
     *
     * @return $this
     */
    public function setSpreadsheet(Spreadsheet $spreadsheet): static
    {
        $this->spreadSheet = $spreadsheet;
 
        return $this;
    }
}