1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Box\Spout\Writer\Common\Internal; |
4
|
|
|
|
5
|
|
|
use Box\Spout\Writer\Exception\SheetNotFoundException; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Class Workbook |
9
|
|
|
* Represents a workbook within a spreadsheet file. |
10
|
|
|
* It provides the functions to work with worksheets. |
11
|
|
|
* |
12
|
|
|
* @package Box\Spout\Writer\Common |
13
|
|
|
*/ |
14
|
|
|
abstract class AbstractWorkbook implements WorkbookInterface |
15
|
|
|
{ |
16
|
|
|
/** @var bool Whether new sheets should be automatically created when the max rows limit per sheet is reached */ |
17
|
|
|
protected $shouldCreateNewSheetsAutomatically; |
18
|
|
|
|
19
|
|
|
/** @var WorksheetInterface[] Array containing the workbook's sheets */ |
20
|
|
|
protected $worksheets = []; |
21
|
|
|
|
22
|
|
|
/** @var WorksheetInterface The worksheet where data will be written to */ |
23
|
|
|
protected $currentWorksheet; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @param bool $shouldCreateNewSheetsAutomatically |
27
|
|
|
* @param \Box\Spout\Writer\Style\Style $defaultRowStyle |
28
|
|
|
* @throws \Box\Spout\Common\Exception\IOException If unable to create at least one of the base folders |
29
|
|
|
*/ |
30
|
249 |
|
public function __construct($shouldCreateNewSheetsAutomatically, $defaultRowStyle) |
31
|
|
|
{ |
32
|
249 |
|
$this->shouldCreateNewSheetsAutomatically = $shouldCreateNewSheetsAutomatically; |
33
|
249 |
|
} |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @return \Box\Spout\Writer\Common\Helper\AbstractStyleHelper The specific style helper |
37
|
|
|
*/ |
38
|
|
|
abstract protected function getStyleHelper(); |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @return int Maximum number of rows/columns a sheet can contain |
42
|
|
|
*/ |
43
|
|
|
abstract protected function getMaxRowsPerWorksheet(); |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Creates a new sheet in the workbook. The current sheet remains unchanged. |
47
|
|
|
* |
48
|
|
|
* @return WorksheetInterface The created sheet |
49
|
|
|
* @throws \Box\Spout\Common\Exception\IOException If unable to open the sheet for writing |
50
|
|
|
*/ |
51
|
|
|
abstract public function addNewSheet(); |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Creates a new sheet in the workbook and make it the current sheet. |
55
|
|
|
* The writing will resume where it stopped (i.e. data won't be truncated). |
56
|
|
|
* |
57
|
|
|
* @return WorksheetInterface The created sheet |
58
|
|
|
* @throws \Box\Spout\Common\Exception\IOException If unable to open the sheet for writing |
59
|
|
|
*/ |
60
|
249 |
|
public function addNewSheetAndMakeItCurrent() |
61
|
|
|
{ |
62
|
249 |
|
$worksheet = $this->addNewSheet(); |
63
|
249 |
|
$this->setCurrentWorksheet($worksheet); |
64
|
|
|
|
65
|
249 |
|
return $worksheet; |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* @return WorksheetInterface[] All the workbook's sheets |
70
|
|
|
*/ |
71
|
42 |
|
public function getWorksheets() |
72
|
|
|
{ |
73
|
42 |
|
return $this->worksheets; |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Returns the current sheet |
78
|
|
|
* |
79
|
|
|
* @return WorksheetInterface The current sheet |
80
|
|
|
*/ |
81
|
195 |
|
public function getCurrentWorksheet() |
82
|
|
|
{ |
83
|
195 |
|
return $this->currentWorksheet; |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Sets the given sheet as the current one. New data will be written to this sheet. |
88
|
|
|
* The writing will resume where it stopped (i.e. data won't be truncated). |
89
|
|
|
* |
90
|
|
|
* @param \Box\Spout\Writer\Common\Sheet $sheet The "external" sheet to set as current |
91
|
|
|
* @return void |
92
|
|
|
* @throws \Box\Spout\Writer\Exception\SheetNotFoundException If the given sheet does not exist in the workbook |
93
|
|
|
*/ |
94
|
12 |
|
public function setCurrentSheet($sheet) |
95
|
|
|
{ |
96
|
12 |
|
$worksheet = $this->getWorksheetFromExternalSheet($sheet); |
97
|
12 |
|
if ($worksheet !== null) { |
98
|
12 |
|
$this->currentWorksheet = $worksheet; |
99
|
12 |
|
} else { |
100
|
3 |
|
throw new SheetNotFoundException('The given sheet does not exist in the workbook.'); |
101
|
|
|
} |
102
|
12 |
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* @param WorksheetInterface $worksheet |
106
|
|
|
* @return void |
107
|
|
|
*/ |
108
|
249 |
|
protected function setCurrentWorksheet($worksheet) |
109
|
|
|
{ |
110
|
249 |
|
$this->currentWorksheet = $worksheet; |
111
|
249 |
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* Returns the worksheet associated to the given external sheet. |
115
|
|
|
* |
116
|
|
|
* @param \Box\Spout\Writer\Common\Sheet $sheet |
117
|
|
|
* @return WorksheetInterface|null The worksheet associated to the given external sheet or null if not found. |
118
|
|
|
*/ |
119
|
12 |
|
protected function getWorksheetFromExternalSheet($sheet) |
120
|
|
|
{ |
121
|
12 |
|
$worksheetFound = null; |
122
|
|
|
|
123
|
12 |
|
foreach ($this->worksheets as $worksheet) { |
124
|
12 |
|
if ($worksheet->getExternalSheet() === $sheet) { |
125
|
12 |
|
$worksheetFound = $worksheet; |
126
|
12 |
|
break; |
127
|
|
|
} |
128
|
12 |
|
} |
129
|
|
|
|
130
|
12 |
|
return $worksheetFound; |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Adds data to the current sheet. |
135
|
|
|
* If shouldCreateNewSheetsAutomatically option is set to true, it will handle pagination |
136
|
|
|
* with the creation of new worksheets if one worksheet has reached its maximum capicity. |
137
|
|
|
* |
138
|
|
|
* @param array $dataRow Array containing data to be written. Cannot be empty. |
139
|
|
|
* Example $dataRow = ['data1', 1234, null, '', 'data5']; |
140
|
|
|
* @param \Box\Spout\Writer\Style\Style $style Style to be applied to the row. |
141
|
|
|
* @return void |
142
|
|
|
* @throws \Box\Spout\Common\Exception\IOException If trying to create a new sheet and unable to open the sheet for writing |
143
|
|
|
* @throws \Box\Spout\Writer\Exception\WriterException If unable to write data |
144
|
|
|
*/ |
145
|
177 |
|
public function addRowToCurrentWorksheet($dataRow, $style) |
146
|
|
|
{ |
147
|
177 |
|
$currentWorksheet = $this->getCurrentWorksheet(); |
148
|
177 |
|
$hasReachedMaxRows = $this->hasCurrentWorkseetReachedMaxRows(); |
149
|
177 |
|
$styleHelper = $this->getStyleHelper(); |
150
|
|
|
|
151
|
|
|
// if we reached the maximum number of rows for the current sheet... |
152
|
177 |
|
if ($hasReachedMaxRows) { |
153
|
|
|
// ... continue writing in a new sheet if option set |
154
|
12 |
|
if ($this->shouldCreateNewSheetsAutomatically) { |
155
|
6 |
|
$currentWorksheet = $this->addNewSheetAndMakeItCurrent(); |
156
|
|
|
|
157
|
6 |
|
$updatedStyle = $styleHelper->applyExtraStylesIfNeeded($style, $dataRow); |
158
|
6 |
|
$registeredStyle = $styleHelper->registerStyle($updatedStyle); |
159
|
6 |
|
$currentWorksheet->addRow($dataRow, $registeredStyle); |
160
|
6 |
|
} else { |
161
|
|
|
// otherwise, do nothing as the data won't be read anyways |
162
|
|
|
} |
163
|
12 |
|
} else { |
164
|
177 |
|
$updatedStyle = $styleHelper->applyExtraStylesIfNeeded($style, $dataRow); |
165
|
177 |
|
$registeredStyle = $styleHelper->registerStyle($updatedStyle); |
166
|
177 |
|
$currentWorksheet->addRow($dataRow, $registeredStyle); |
167
|
|
|
} |
168
|
168 |
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* @return bool Whether the current worksheet has reached the maximum number of rows per sheet. |
172
|
|
|
*/ |
173
|
177 |
|
protected function hasCurrentWorkseetReachedMaxRows() |
174
|
|
|
{ |
175
|
177 |
|
$currentWorksheet = $this->getCurrentWorksheet(); |
176
|
177 |
|
return ($currentWorksheet->getLastWrittenRowIndex() >= $this->getMaxRowsPerWorksheet()); |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* Closes the workbook and all its associated sheets. |
181
|
|
|
* All the necessary files are written to disk and zipped together to create the ODS file. |
182
|
|
|
* All the temporary files are then deleted. |
183
|
|
|
* |
184
|
|
|
* @param resource $finalFilePointer Pointer to the ODS that will be created |
185
|
|
|
* @return void |
186
|
|
|
*/ |
187
|
|
|
abstract public function close($finalFilePointer); |
188
|
|
|
} |
189
|
|
|
|