1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Simple hacky xlsx writer. Since performance and memory usage were the |
4
|
|
|
* main drivers, DOM and SimpleXml where out of the question. Same goes |
5
|
|
|
* for Cell and even Row objects. |
6
|
|
|
* While it might have been nice for a sheet to hold a row collection |
7
|
|
|
* and rows to hold cell collections etc ... it was a total no-go |
8
|
|
|
* memory and performance wise. |
9
|
|
|
* |
10
|
|
|
* This library was built to satisfy the following needs: |
11
|
|
|
* - Write a single sheet with up to 2^20 rows fast and with a small |
12
|
|
|
* memory footprint. |
13
|
|
|
* - Freeze the first [n] rows to have a fixed table header/headline. |
14
|
|
|
* - Option to use different fonts, styles and background colors on |
15
|
|
|
* a row level. |
16
|
|
|
* |
17
|
|
|
* Current major drawback(s): |
18
|
|
|
* - No cell individualisation, everything is applied at a row level |
19
|
|
|
* and its intended to keep it that way. |
20
|
|
|
* - No calculated/formula cells. Only inlineStr and simple number type |
21
|
|
|
* cells and it will probably stay that way. |
22
|
|
|
* - No control character escaping todo: RowHelper::addEscapeRow() |
23
|
|
|
* |
24
|
|
|
* @author neun |
25
|
|
|
* @since 2016-07-03 |
26
|
|
|
*/ |
27
|
|
|
|
28
|
|
|
namespace OneSheet; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Class Writer |
32
|
|
|
* @package OneSheet |
33
|
|
|
*/ |
34
|
|
|
class Writer |
35
|
|
|
{ |
36
|
|
|
/** |
37
|
|
|
* @var \ZipArchive |
38
|
|
|
*/ |
39
|
|
|
private $zip; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @var Sheet |
43
|
|
|
*/ |
44
|
|
|
private $sheet; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* XmlWriter constructor. |
48
|
|
|
* @param Sheet $sheet |
49
|
|
|
* @param string $fileName |
50
|
|
|
*/ |
51
|
2 |
|
public function __construct(Sheet $sheet, $fileName = 'dummy.xlsx') |
52
|
|
|
{ |
53
|
2 |
|
$this->zip = new \ZipArchive(); |
54
|
2 |
|
$this->zip->open($fileName, \ZipArchive::CREATE + \ZipArchive::CM_STORE); |
55
|
2 |
|
$this->sheet = $sheet; |
56
|
2 |
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* Return sheet instance. |
60
|
|
|
* |
61
|
|
|
* @return Sheet |
62
|
|
|
*/ |
63
|
1 |
|
public function sheet() |
64
|
|
|
{ |
65
|
1 |
|
return $this->sheet; |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Write xml style sheet into zip. |
70
|
|
|
*/ |
71
|
1 |
|
private function writeStyleXmlFile() |
72
|
|
|
{ |
73
|
1 |
|
$this->zip->addFromString('xl/styles.xml', |
74
|
|
|
'<?xml version="1.0" encoding="UTF-8" standalone="yes"?><styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">' |
75
|
1 |
|
. StyleHelper::getFontsXml() |
76
|
1 |
|
. StyleHelper::getFillsXml() |
77
|
1 |
|
. '<borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count="1"><xf borderId="0" fillId="0" fontId="0" numFmtId="0"/></cellStyleXfs>' |
78
|
1 |
|
. StyleHelper::getCellXfsXml() |
79
|
1 |
|
. '<cellStyles count="1"><cellStyle builtinId="0" name="Normal" xfId="0"/></cellStyles><tableStyles count="0" defaultTableStyle="TableStyleMedium2" defaultPivotStyle="PivotStyleLight16"/></styleSheet>' |
80
|
1 |
|
); |
81
|
1 |
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Add required default xml files to zip archive. |
85
|
|
|
*/ |
86
|
1 |
|
private function writeDefaultXmls() |
87
|
|
|
{ |
88
|
1 |
|
$this->zip->addFromString('[Content_Types].xml', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default ContentType="application/xml" Extension="xml"/><Default ContentType="application/vnd.openxmlformats-package.relationships+xml" Extension="rels"/><Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" PartName="/xl/workbook.xml"/><Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" PartName="/xl/worksheets/sheet1.xml"/><Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" PartName="/xl/styles.xml"/><Override ContentType="application/vnd.openxmlformats-package.core-properties+xml" PartName="/docProps/core.xml"/><Override ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" PartName="/docProps/app.xml"/></Types>'); |
89
|
1 |
|
$this->zip->addFromString('docProps/core.xml', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dcterms:created xsi:type="dcterms:W3CDTF">' . date(DATE_ISO8601) . '</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">' . date(DATE_ISO8601) . '</dcterms:modified><cp:revision>0</cp:revision></cp:coreProperties>'); |
90
|
1 |
|
$this->zip->addFromString('docProps/app.xml', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"><Application>OneSheetOld</Application><TotalTime>0</TotalTime></Properties>'); |
91
|
1 |
|
$this->zip->addFromString('_rels/.rels', '<?xml version="1.0" encoding="UTF-8"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdWorkbook" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/><Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/officedocument/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rIdApp" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/></Relationships>'); |
92
|
1 |
|
$this->zip->addFromString('xl/_rels/workbook.xml.rels', '<?xml version="1.0" encoding="UTF-8"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdStyles" Target="styles.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"/><Relationship Id="rIdSheet1" Target="worksheets/sheet1.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"/></Relationships>'); |
93
|
1 |
|
$this->zip->addFromString('xl/workbook.xml', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><sheets><sheet name="Sheet1" sheetId="1" r:id="rIdSheet1"/></sheets></workbook>'); |
94
|
1 |
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* Write/add the style + sheet xml files and close/write |
98
|
|
|
* the xlsx file. |
99
|
|
|
*/ |
100
|
1 |
|
public function close() |
101
|
|
|
{ |
102
|
1 |
|
$this->zip->addFile($this->sheet->sheetFilePath(), 'xl/worksheets/sheet1.xml'); |
103
|
1 |
|
$this->writeStyleXmlFile(); |
104
|
1 |
|
$this->writeDefaultXmls(); |
105
|
1 |
|
$this->zip->close(); |
106
|
1 |
|
} |
107
|
|
|
} |
108
|
|
|
|