1 | <?php |
||
20 | class WorksheetManager implements WorksheetManagerInterface |
||
21 | { |
||
22 | /** @var \Box\Spout\Common\Helper\Escaper\ODS Strings escaper */ |
||
23 | private $stringsEscaper; |
||
24 | |||
25 | /** @var StringHelper String helper */ |
||
26 | private $stringHelper; |
||
27 | |||
28 | /** @var StyleManager Manages styles */ |
||
29 | private $styleManager; |
||
30 | |||
31 | /** |
||
32 | * WorksheetManager constructor. |
||
33 | * @param StyleManager $styleManager |
||
34 | * @param ODSEscaper $stringsEscaper |
||
35 | * @param StringHelper $stringHelper |
||
36 | */ |
||
37 | 41 | public function __construct( |
|
46 | |||
47 | /** |
||
48 | * Prepares the worksheet to accept data |
||
49 | * |
||
50 | * @param Worksheet $worksheet The worksheet to start |
||
51 | * @throws \Box\Spout\Common\Exception\IOException If the sheet data file cannot be opened for writing |
||
52 | * @return void |
||
53 | */ |
||
54 | 41 | public function startSheet(Worksheet $worksheet) |
|
61 | |||
62 | /** |
||
63 | * Checks if the sheet has been sucessfully created. Throws an exception if not. |
||
64 | * |
||
65 | * @param bool|resource $sheetFilePointer Pointer to the sheet data file or FALSE if unable to open the file |
||
66 | * @throws IOException If the sheet data file cannot be opened for writing |
||
67 | * @return void |
||
68 | */ |
||
69 | 41 | private function throwIfSheetFilePointerIsNotAvailable($sheetFilePointer) |
|
75 | |||
76 | /** |
||
77 | * Returns the table XML root node as string. |
||
78 | * |
||
79 | * @param Worksheet $worksheet |
||
80 | * @return string <table> node as string |
||
81 | */ |
||
82 | 34 | public function getTableElementStartAsString(Worksheet $worksheet) |
|
93 | |||
94 | /** |
||
95 | * Adds a row to the worksheet. |
||
96 | * |
||
97 | * @param Worksheet $worksheet The worksheet to add the row to |
||
98 | * @param Row $row The row to be added |
||
99 | * @return void |
||
100 | * |
||
101 | * @throws IOException If the data cannot be written |
||
102 | * @throws InvalidArgumentException If a cell value's type is not supported |
||
103 | * @return void |
||
104 | */ |
||
105 | 30 | public function addRow(Worksheet $worksheet, Row $row) |
|
106 | { |
||
107 | |||
108 | 30 | $cells = $row->getCells(); |
|
109 | 30 | $cellsCount = count($cells); |
|
110 | |||
111 | 30 | $data = '<table:table-row table:style-name="ro1">'; |
|
112 | |||
113 | 30 | $currentCellIndex = 0; |
|
114 | 30 | $nextCellIndex = 1; |
|
115 | |||
116 | 30 | for ($i = 0; $i < $cellsCount; $i++) { |
|
117 | |||
118 | /** @var Cell $cell */ |
||
119 | 30 | $cell = $cells[$currentCellIndex]; |
|
120 | /** @var Cell|null $nextCell */ |
||
121 | 30 | $nextCell = isset($cells[$nextCellIndex]) ? $cells[$nextCellIndex] : null; |
|
122 | |||
123 | // @TODO refactoring: move this to its own method |
||
124 | 30 | if (null === $nextCell || $cell->getValue() !== $nextCell->getValue()) { |
|
125 | |||
126 | // Apply styles - the row style is merged at this point |
||
127 | 30 | $cell->applyStyle($row->getStyle()); |
|
128 | 30 | $this->styleManager->applyExtraStylesIfNeeded($cell); |
|
129 | 30 | $registeredStyle = $this->styleManager->registerStyle($cell->getStyle()); |
|
|
|||
130 | 30 | $styleIndex = $registeredStyle->getId() + 1; // 1-based |
|
131 | |||
132 | 30 | $numTimesValueRepeated = ($nextCellIndex - $currentCellIndex); |
|
133 | 30 | $data .= $this->getCellXML($cell, $styleIndex, $numTimesValueRepeated); |
|
134 | 29 | $currentCellIndex = $nextCellIndex; |
|
135 | } |
||
136 | |||
137 | 29 | $nextCellIndex++; |
|
138 | } |
||
139 | |||
140 | 29 | $data .= '</table:table-row>'; |
|
141 | |||
142 | 29 | $wasWriteSuccessful = fwrite($worksheet->getFilePointer(), $data); |
|
143 | 29 | if ($wasWriteSuccessful === false) { |
|
144 | throw new IOException("Unable to write data in {$worksheet->getFilePath()}"); |
||
145 | } |
||
146 | |||
147 | // only update the count if the write worked |
||
148 | 29 | $lastWrittenRowIndex = $worksheet->getLastWrittenRowIndex(); |
|
149 | 29 | $worksheet->setLastWrittenRowIndex($lastWrittenRowIndex + 1); |
|
150 | 29 | } |
|
151 | |||
152 | /** |
||
153 | * Returns the cell XML content, given its value. |
||
154 | * |
||
155 | * @param Cell $cell The cell to be written |
||
156 | * @param int $styleIndex Index of the used style |
||
157 | * @param int $numTimesValueRepeated Number of times the value is consecutively repeated |
||
158 | * @throws \Box\Spout\Common\Exception\InvalidArgumentException If a cell value's type is not supported |
||
159 | * @return string The cell XML content |
||
160 | */ |
||
161 | 30 | protected function getCellXML(Cell $cell, $styleIndex, $numTimesValueRepeated) |
|
162 | { |
||
163 | 30 | $data = '<table:table-cell table:style-name="ce' . $styleIndex . '"'; |
|
164 | |||
165 | 30 | if ($numTimesValueRepeated !== 1) { |
|
166 | 4 | $data .= ' table:number-columns-repeated="' . $numTimesValueRepeated . '"'; |
|
167 | } |
||
168 | |||
169 | 30 | if ($cell->isString()) { |
|
170 | 26 | $data .= ' office:value-type="string" calcext:value-type="string">'; |
|
171 | |||
172 | 26 | $cellValueLines = explode("\n", $cell->getValue()); |
|
173 | 26 | foreach ($cellValueLines as $cellValueLine) { |
|
174 | 26 | $data .= '<text:p>' . $this->stringsEscaper->escape($cellValueLine) . '</text:p>'; |
|
175 | } |
||
176 | |||
177 | 26 | $data .= '</table:table-cell>'; |
|
178 | 6 | } elseif ($cell->isBoolean()) { |
|
179 | 3 | $data .= ' office:value-type="boolean" calcext:value-type="boolean" office:boolean-value="' . $cell->getValue() . '">'; |
|
180 | 3 | $data .= '<text:p>' . $cell->getValue() . '</text:p>'; |
|
181 | 3 | $data .= '</table:table-cell>'; |
|
182 | 5 | } elseif ($cell->isNumeric()) { |
|
183 | 3 | $data .= ' office:value-type="float" calcext:value-type="float" office:value="' . $cell->getValue() . '">'; |
|
184 | 3 | $data .= '<text:p>' . $cell->getValue() . '</text:p>'; |
|
185 | 3 | $data .= '</table:table-cell>'; |
|
186 | 3 | } elseif ($cell->isEmpty()) { |
|
187 | 2 | $data .= '/>'; |
|
188 | } else { |
||
189 | 1 | throw new InvalidArgumentException('Trying to add a value with an unsupported type: ' . gettype($cell->getValue())); |
|
190 | } |
||
191 | |||
192 | 29 | return $data; |
|
193 | } |
||
194 | |||
195 | /** |
||
196 | * Closes the worksheet |
||
197 | * |
||
198 | * @param Worksheet $worksheet |
||
199 | * @return void |
||
200 | */ |
||
201 | 34 | public function close(Worksheet $worksheet) |
|
211 | } |
||
212 |
Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code: