2390 |
jpm |
1 |
<?php
|
|
|
2 |
/**
|
|
|
3 |
* PHPExcel
|
|
|
4 |
*
|
|
|
5 |
* Copyright (c) 2006 - 2013 PHPExcel
|
|
|
6 |
*
|
|
|
7 |
* This library is free software; you can redistribute it and/or
|
|
|
8 |
* modify it under the terms of the GNU Lesser General Public
|
|
|
9 |
* License as published by the Free Software Foundation; either
|
|
|
10 |
* version 2.1 of the License, or (at your option) any later version.
|
|
|
11 |
*
|
|
|
12 |
* This library is distributed in the hope that it will be useful,
|
|
|
13 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
14 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
15 |
* Lesser General Public License for more details.
|
|
|
16 |
*
|
|
|
17 |
* You should have received a copy of the GNU Lesser General Public
|
|
|
18 |
* License along with this library; if not, write to the Free Software
|
|
|
19 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
20 |
*
|
|
|
21 |
* @category PHPExcel
|
|
|
22 |
* @package PHPExcel_Reader
|
|
|
23 |
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)
|
|
|
24 |
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
|
|
25 |
* @version ##VERSION##, ##DATE##
|
|
|
26 |
*/
|
|
|
27 |
|
|
|
28 |
|
|
|
29 |
/** PHPExcel root directory */
|
|
|
30 |
if (!defined('PHPEXCEL_ROOT')) {
|
|
|
31 |
/**
|
|
|
32 |
* @ignore
|
|
|
33 |
*/
|
|
|
34 |
define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');
|
|
|
35 |
require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
|
|
|
36 |
}
|
|
|
37 |
|
|
|
38 |
/**
|
|
|
39 |
* PHPExcel_Reader_OOCalc
|
|
|
40 |
*
|
|
|
41 |
* @category PHPExcel
|
|
|
42 |
* @package PHPExcel_Reader
|
|
|
43 |
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)
|
|
|
44 |
*/
|
|
|
45 |
class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader
|
|
|
46 |
{
|
|
|
47 |
/**
|
|
|
48 |
* Formats
|
|
|
49 |
*
|
|
|
50 |
* @var array
|
|
|
51 |
*/
|
|
|
52 |
private $_styles = array();
|
|
|
53 |
|
|
|
54 |
|
|
|
55 |
/**
|
|
|
56 |
* Create a new PHPExcel_Reader_OOCalc
|
|
|
57 |
*/
|
|
|
58 |
public function __construct() {
|
|
|
59 |
$this->_readFilter = new PHPExcel_Reader_DefaultReadFilter();
|
|
|
60 |
}
|
|
|
61 |
|
|
|
62 |
|
|
|
63 |
/**
|
|
|
64 |
* Can the current PHPExcel_Reader_IReader read the file?
|
|
|
65 |
*
|
|
|
66 |
* @param string $pFilename
|
|
|
67 |
* @return boolean
|
|
|
68 |
* @throws PHPExcel_Reader_Exception
|
|
|
69 |
*/
|
|
|
70 |
public function canRead($pFilename)
|
|
|
71 |
{
|
|
|
72 |
// Check if file exists
|
|
|
73 |
if (!file_exists($pFilename)) {
|
|
|
74 |
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
|
|
|
75 |
}
|
|
|
76 |
|
|
|
77 |
// Check if zip class exists
|
|
|
78 |
if (!class_exists('ZipArchive',FALSE)) {
|
|
|
79 |
throw new PHPExcel_Reader_Exception("ZipArchive library is not enabled");
|
|
|
80 |
}
|
|
|
81 |
|
|
|
82 |
$mimeType = 'UNKNOWN';
|
|
|
83 |
// Load file
|
|
|
84 |
$zip = new ZipArchive;
|
|
|
85 |
if ($zip->open($pFilename) === true) {
|
|
|
86 |
// check if it is an OOXML archive
|
|
|
87 |
$stat = $zip->statName('mimetype');
|
|
|
88 |
if ($stat && ($stat['size'] <= 255)) {
|
|
|
89 |
$mimeType = $zip->getFromName($stat['name']);
|
|
|
90 |
} elseif($stat = $zip->statName('META-INF/manifest.xml')) {
|
|
|
91 |
$xml = simplexml_load_string($zip->getFromName('META-INF/manifest.xml'));
|
|
|
92 |
$namespacesContent = $xml->getNamespaces(true);
|
|
|
93 |
if (isset($namespacesContent['manifest'])) {
|
|
|
94 |
$manifest = $xml->children($namespacesContent['manifest']);
|
|
|
95 |
foreach($manifest as $manifestDataSet) {
|
|
|
96 |
$manifestAttributes = $manifestDataSet->attributes($namespacesContent['manifest']);
|
|
|
97 |
if ($manifestAttributes->{'full-path'} == '/') {
|
|
|
98 |
$mimeType = (string) $manifestAttributes->{'media-type'};
|
|
|
99 |
break;
|
|
|
100 |
}
|
|
|
101 |
}
|
|
|
102 |
}
|
|
|
103 |
}
|
|
|
104 |
|
|
|
105 |
$zip->close();
|
|
|
106 |
|
|
|
107 |
return ($mimeType === 'application/vnd.oasis.opendocument.spreadsheet');
|
|
|
108 |
}
|
|
|
109 |
|
|
|
110 |
return FALSE;
|
|
|
111 |
}
|
|
|
112 |
|
|
|
113 |
|
|
|
114 |
/**
|
|
|
115 |
* Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object
|
|
|
116 |
*
|
|
|
117 |
* @param string $pFilename
|
|
|
118 |
* @throws PHPExcel_Reader_Exception
|
|
|
119 |
*/
|
|
|
120 |
public function listWorksheetNames($pFilename)
|
|
|
121 |
{
|
|
|
122 |
// Check if file exists
|
|
|
123 |
if (!file_exists($pFilename)) {
|
|
|
124 |
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
|
|
|
125 |
}
|
|
|
126 |
|
|
|
127 |
$zip = new ZipArchive;
|
|
|
128 |
if (!$zip->open($pFilename)) {
|
|
|
129 |
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file.");
|
|
|
130 |
}
|
|
|
131 |
|
|
|
132 |
$worksheetNames = array();
|
|
|
133 |
|
|
|
134 |
$xml = new XMLReader();
|
|
|
135 |
$res = $xml->open('zip://'.realpath($pFilename).'#content.xml');
|
|
|
136 |
$xml->setParserProperty(2,true);
|
|
|
137 |
|
|
|
138 |
// Step into the first level of content of the XML
|
|
|
139 |
$xml->read();
|
|
|
140 |
while ($xml->read()) {
|
|
|
141 |
// Quickly jump through to the office:body node
|
|
|
142 |
while ($xml->name !== 'office:body') {
|
|
|
143 |
if ($xml->isEmptyElement)
|
|
|
144 |
$xml->read();
|
|
|
145 |
else
|
|
|
146 |
$xml->next();
|
|
|
147 |
}
|
|
|
148 |
// Now read each node until we find our first table:table node
|
|
|
149 |
while ($xml->read()) {
|
|
|
150 |
if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {
|
|
|
151 |
// Loop through each table:table node reading the table:name attribute for each worksheet name
|
|
|
152 |
do {
|
|
|
153 |
$worksheetNames[] = $xml->getAttribute('table:name');
|
|
|
154 |
$xml->next();
|
|
|
155 |
} while ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT);
|
|
|
156 |
}
|
|
|
157 |
}
|
|
|
158 |
}
|
|
|
159 |
|
|
|
160 |
return $worksheetNames;
|
|
|
161 |
}
|
|
|
162 |
|
|
|
163 |
|
|
|
164 |
/**
|
|
|
165 |
* Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)
|
|
|
166 |
*
|
|
|
167 |
* @param string $pFilename
|
|
|
168 |
* @throws PHPExcel_Reader_Exception
|
|
|
169 |
*/
|
|
|
170 |
public function listWorksheetInfo($pFilename)
|
|
|
171 |
{
|
|
|
172 |
// Check if file exists
|
|
|
173 |
if (!file_exists($pFilename)) {
|
|
|
174 |
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
|
|
|
175 |
}
|
|
|
176 |
|
|
|
177 |
$worksheetInfo = array();
|
|
|
178 |
|
|
|
179 |
$zip = new ZipArchive;
|
|
|
180 |
if (!$zip->open($pFilename)) {
|
|
|
181 |
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file.");
|
|
|
182 |
}
|
|
|
183 |
|
|
|
184 |
$xml = new XMLReader();
|
|
|
185 |
$res = $xml->open('zip://'.realpath($pFilename).'#content.xml');
|
|
|
186 |
$xml->setParserProperty(2,true);
|
|
|
187 |
|
|
|
188 |
// Step into the first level of content of the XML
|
|
|
189 |
$xml->read();
|
|
|
190 |
while ($xml->read()) {
|
|
|
191 |
// Quickly jump through to the office:body node
|
|
|
192 |
while ($xml->name !== 'office:body') {
|
|
|
193 |
if ($xml->isEmptyElement)
|
|
|
194 |
$xml->read();
|
|
|
195 |
else
|
|
|
196 |
$xml->next();
|
|
|
197 |
}
|
|
|
198 |
// Now read each node until we find our first table:table node
|
|
|
199 |
while ($xml->read()) {
|
|
|
200 |
if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {
|
|
|
201 |
$worksheetNames[] = $xml->getAttribute('table:name');
|
|
|
202 |
|
|
|
203 |
$tmpInfo = array(
|
|
|
204 |
'worksheetName' => $xml->getAttribute('table:name'),
|
|
|
205 |
'lastColumnLetter' => 'A',
|
|
|
206 |
'lastColumnIndex' => 0,
|
|
|
207 |
'totalRows' => 0,
|
|
|
208 |
'totalColumns' => 0,
|
|
|
209 |
);
|
|
|
210 |
|
|
|
211 |
// Loop through each child node of the table:table element reading
|
|
|
212 |
$currCells = 0;
|
|
|
213 |
do {
|
|
|
214 |
$xml->read();
|
|
|
215 |
if ($xml->name == 'table:table-row' && $xml->nodeType == XMLReader::ELEMENT) {
|
|
|
216 |
$rowspan = $xml->getAttribute('table:number-rows-repeated');
|
|
|
217 |
$rowspan = empty($rowspan) ? 1 : $rowspan;
|
|
|
218 |
$tmpInfo['totalRows'] += $rowspan;
|
|
|
219 |
$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells);
|
|
|
220 |
$currCells = 0;
|
|
|
221 |
// Step into the row
|
|
|
222 |
$xml->read();
|
|
|
223 |
do {
|
|
|
224 |
if ($xml->name == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
|
|
|
225 |
if (!$xml->isEmptyElement) {
|
|
|
226 |
$currCells++;
|
|
|
227 |
$xml->next();
|
|
|
228 |
} else {
|
|
|
229 |
$xml->read();
|
|
|
230 |
}
|
|
|
231 |
} elseif ($xml->name == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
|
|
|
232 |
$mergeSize = $xml->getAttribute('table:number-columns-repeated');
|
|
|
233 |
$currCells += $mergeSize;
|
|
|
234 |
$xml->read();
|
|
|
235 |
}
|
|
|
236 |
} while ($xml->name != 'table:table-row');
|
|
|
237 |
}
|
|
|
238 |
} while ($xml->name != 'table:table');
|
|
|
239 |
|
|
|
240 |
$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells);
|
|
|
241 |
$tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1;
|
|
|
242 |
$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
|
|
|
243 |
$worksheetInfo[] = $tmpInfo;
|
|
|
244 |
}
|
|
|
245 |
}
|
|
|
246 |
|
|
|
247 |
// foreach($workbookData->table as $worksheetDataSet) {
|
|
|
248 |
// $worksheetData = $worksheetDataSet->children($namespacesContent['table']);
|
|
|
249 |
// $worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']);
|
|
|
250 |
//
|
|
|
251 |
// $rowIndex = 0;
|
|
|
252 |
// foreach ($worksheetData as $key => $rowData) {
|
|
|
253 |
// switch ($key) {
|
|
|
254 |
// case 'table-row' :
|
|
|
255 |
// $rowDataTableAttributes = $rowData->attributes($namespacesContent['table']);
|
|
|
256 |
// $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ?
|
|
|
257 |
// $rowDataTableAttributes['number-rows-repeated'] : 1;
|
|
|
258 |
// $columnIndex = 0;
|
|
|
259 |
//
|
|
|
260 |
// foreach ($rowData as $key => $cellData) {
|
|
|
261 |
// $cellDataTableAttributes = $cellData->attributes($namespacesContent['table']);
|
|
|
262 |
// $colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ?
|
|
|
263 |
// $cellDataTableAttributes['number-columns-repeated'] : 1;
|
|
|
264 |
// $cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']);
|
|
|
265 |
// if (isset($cellDataOfficeAttributes['value-type'])) {
|
|
|
266 |
// $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex + $colRepeats - 1);
|
|
|
267 |
// $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex + $rowRepeats);
|
|
|
268 |
// }
|
|
|
269 |
// $columnIndex += $colRepeats;
|
|
|
270 |
// }
|
|
|
271 |
// $rowIndex += $rowRepeats;
|
|
|
272 |
// break;
|
|
|
273 |
// }
|
|
|
274 |
// }
|
|
|
275 |
//
|
|
|
276 |
// $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
|
|
|
277 |
// $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;
|
|
|
278 |
//
|
|
|
279 |
// }
|
|
|
280 |
// }
|
|
|
281 |
}
|
|
|
282 |
|
|
|
283 |
return $worksheetInfo;
|
|
|
284 |
}
|
|
|
285 |
|
|
|
286 |
|
|
|
287 |
/**
|
|
|
288 |
* Loads PHPExcel from file
|
|
|
289 |
*
|
|
|
290 |
* @param string $pFilename
|
|
|
291 |
* @return PHPExcel
|
|
|
292 |
* @throws PHPExcel_Reader_Exception
|
|
|
293 |
*/
|
|
|
294 |
public function load($pFilename)
|
|
|
295 |
{
|
|
|
296 |
// Create new PHPExcel
|
|
|
297 |
$objPHPExcel = new PHPExcel();
|
|
|
298 |
|
|
|
299 |
// Load into this instance
|
|
|
300 |
return $this->loadIntoExisting($pFilename, $objPHPExcel);
|
|
|
301 |
}
|
|
|
302 |
|
|
|
303 |
|
|
|
304 |
private static function identifyFixedStyleValue($styleList,&$styleAttributeValue) {
|
|
|
305 |
$styleAttributeValue = strtolower($styleAttributeValue);
|
|
|
306 |
foreach($styleList as $style) {
|
|
|
307 |
if ($styleAttributeValue == strtolower($style)) {
|
|
|
308 |
$styleAttributeValue = $style;
|
|
|
309 |
return true;
|
|
|
310 |
}
|
|
|
311 |
}
|
|
|
312 |
return false;
|
|
|
313 |
}
|
|
|
314 |
|
|
|
315 |
|
|
|
316 |
/**
|
|
|
317 |
* Loads PHPExcel from file into PHPExcel instance
|
|
|
318 |
*
|
|
|
319 |
* @param string $pFilename
|
|
|
320 |
* @param PHPExcel $objPHPExcel
|
|
|
321 |
* @return PHPExcel
|
|
|
322 |
* @throws PHPExcel_Reader_Exception
|
|
|
323 |
*/
|
|
|
324 |
public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
|
|
|
325 |
{
|
|
|
326 |
// Check if file exists
|
|
|
327 |
if (!file_exists($pFilename)) {
|
|
|
328 |
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
|
|
|
329 |
}
|
|
|
330 |
|
|
|
331 |
$timezoneObj = new DateTimeZone('Europe/London');
|
|
|
332 |
$GMT = new DateTimeZone('UTC');
|
|
|
333 |
|
|
|
334 |
$zip = new ZipArchive;
|
|
|
335 |
if (!$zip->open($pFilename)) {
|
|
|
336 |
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file.");
|
|
|
337 |
}
|
|
|
338 |
|
|
|
339 |
// echo '<h1>Meta Information</h1>';
|
|
|
340 |
$xml = simplexml_load_string($zip->getFromName("meta.xml"));
|
|
|
341 |
$namespacesMeta = $xml->getNamespaces(true);
|
|
|
342 |
// echo '<pre>';
|
|
|
343 |
// print_r($namespacesMeta);
|
|
|
344 |
// echo '</pre><hr />';
|
|
|
345 |
|
|
|
346 |
$docProps = $objPHPExcel->getProperties();
|
|
|
347 |
$officeProperty = $xml->children($namespacesMeta['office']);
|
|
|
348 |
foreach($officeProperty as $officePropertyData) {
|
|
|
349 |
$officePropertyDC = array();
|
|
|
350 |
if (isset($namespacesMeta['dc'])) {
|
|
|
351 |
$officePropertyDC = $officePropertyData->children($namespacesMeta['dc']);
|
|
|
352 |
}
|
|
|
353 |
foreach($officePropertyDC as $propertyName => $propertyValue) {
|
|
|
354 |
switch ($propertyName) {
|
|
|
355 |
case 'title' :
|
|
|
356 |
$docProps->setTitle($propertyValue);
|
|
|
357 |
break;
|
|
|
358 |
case 'subject' :
|
|
|
359 |
$docProps->setSubject($propertyValue);
|
|
|
360 |
break;
|
|
|
361 |
case 'creator' :
|
|
|
362 |
$docProps->setCreator($propertyValue);
|
|
|
363 |
$docProps->setLastModifiedBy($propertyValue);
|
|
|
364 |
break;
|
|
|
365 |
case 'date' :
|
|
|
366 |
$creationDate = strtotime($propertyValue);
|
|
|
367 |
$docProps->setCreated($creationDate);
|
|
|
368 |
$docProps->setModified($creationDate);
|
|
|
369 |
break;
|
|
|
370 |
case 'description' :
|
|
|
371 |
$docProps->setDescription($propertyValue);
|
|
|
372 |
break;
|
|
|
373 |
}
|
|
|
374 |
}
|
|
|
375 |
$officePropertyMeta = array();
|
|
|
376 |
if (isset($namespacesMeta['dc'])) {
|
|
|
377 |
$officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);
|
|
|
378 |
}
|
|
|
379 |
foreach($officePropertyMeta as $propertyName => $propertyValue) {
|
|
|
380 |
$propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']);
|
|
|
381 |
switch ($propertyName) {
|
|
|
382 |
case 'initial-creator' :
|
|
|
383 |
$docProps->setCreator($propertyValue);
|
|
|
384 |
break;
|
|
|
385 |
case 'keyword' :
|
|
|
386 |
$docProps->setKeywords($propertyValue);
|
|
|
387 |
break;
|
|
|
388 |
case 'creation-date' :
|
|
|
389 |
$creationDate = strtotime($propertyValue);
|
|
|
390 |
$docProps->setCreated($creationDate);
|
|
|
391 |
break;
|
|
|
392 |
case 'user-defined' :
|
|
|
393 |
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING;
|
|
|
394 |
foreach ($propertyValueAttributes as $key => $value) {
|
|
|
395 |
if ($key == 'name') {
|
|
|
396 |
$propertyValueName = (string) $value;
|
|
|
397 |
} elseif($key == 'value-type') {
|
|
|
398 |
switch ($value) {
|
|
|
399 |
case 'date' :
|
|
|
400 |
$propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'date');
|
|
|
401 |
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE;
|
|
|
402 |
break;
|
|
|
403 |
case 'boolean' :
|
|
|
404 |
$propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'bool');
|
|
|
405 |
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN;
|
|
|
406 |
break;
|
|
|
407 |
case 'float' :
|
|
|
408 |
$propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'r4');
|
|
|
409 |
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT;
|
|
|
410 |
break;
|
|
|
411 |
default :
|
|
|
412 |
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING;
|
|
|
413 |
}
|
|
|
414 |
}
|
|
|
415 |
}
|
|
|
416 |
$docProps->setCustomProperty($propertyValueName,$propertyValue,$propertyValueType);
|
|
|
417 |
break;
|
|
|
418 |
}
|
|
|
419 |
}
|
|
|
420 |
}
|
|
|
421 |
|
|
|
422 |
|
|
|
423 |
// echo '<h1>Workbook Content</h1>';
|
|
|
424 |
$xml = simplexml_load_string($zip->getFromName("content.xml"));
|
|
|
425 |
$namespacesContent = $xml->getNamespaces(true);
|
|
|
426 |
// echo '<pre>';
|
|
|
427 |
// print_r($namespacesContent);
|
|
|
428 |
// echo '</pre><hr />';
|
|
|
429 |
|
|
|
430 |
$workbook = $xml->children($namespacesContent['office']);
|
|
|
431 |
foreach($workbook->body->spreadsheet as $workbookData) {
|
|
|
432 |
$workbookData = $workbookData->children($namespacesContent['table']);
|
|
|
433 |
$worksheetID = 0;
|
|
|
434 |
foreach($workbookData->table as $worksheetDataSet) {
|
|
|
435 |
$worksheetData = $worksheetDataSet->children($namespacesContent['table']);
|
|
|
436 |
// print_r($worksheetData);
|
|
|
437 |
// echo '<br />';
|
|
|
438 |
$worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']);
|
|
|
439 |
// print_r($worksheetDataAttributes);
|
|
|
440 |
// echo '<br />';
|
|
|
441 |
if ((isset($this->_loadSheetsOnly)) && (isset($worksheetDataAttributes['name'])) &&
|
|
|
442 |
(!in_array($worksheetDataAttributes['name'], $this->_loadSheetsOnly))) {
|
|
|
443 |
continue;
|
|
|
444 |
}
|
|
|
445 |
|
|
|
446 |
// echo '<h2>Worksheet '.$worksheetDataAttributes['name'].'</h2>';
|
|
|
447 |
// Create new Worksheet
|
|
|
448 |
$objPHPExcel->createSheet();
|
|
|
449 |
$objPHPExcel->setActiveSheetIndex($worksheetID);
|
|
|
450 |
if (isset($worksheetDataAttributes['name'])) {
|
|
|
451 |
$worksheetName = (string) $worksheetDataAttributes['name'];
|
|
|
452 |
// Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in
|
|
|
453 |
// formula cells... during the load, all formulae should be correct, and we're simply
|
|
|
454 |
// bringing the worksheet name in line with the formula, not the reverse
|
|
|
455 |
$objPHPExcel->getActiveSheet()->setTitle($worksheetName,false);
|
|
|
456 |
}
|
|
|
457 |
|
|
|
458 |
$rowID = 1;
|
|
|
459 |
foreach($worksheetData as $key => $rowData) {
|
|
|
460 |
// echo '<b>'.$key.'</b><br />';
|
|
|
461 |
switch ($key) {
|
|
|
462 |
case 'table-header-rows':
|
|
|
463 |
foreach ($rowData as $key=>$cellData) {
|
|
|
464 |
$rowData = $cellData;
|
|
|
465 |
break;
|
|
|
466 |
}
|
|
|
467 |
case 'table-row' :
|
|
|
468 |
$rowDataTableAttributes = $rowData->attributes($namespacesContent['table']);
|
|
|
469 |
$rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ?
|
|
|
470 |
$rowDataTableAttributes['number-rows-repeated'] : 1;
|
|
|
471 |
$columnID = 'A';
|
|
|
472 |
foreach($rowData as $key => $cellData) {
|
|
|
473 |
if ($this->getReadFilter() !== NULL) {
|
|
|
474 |
if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) {
|
|
|
475 |
continue;
|
|
|
476 |
}
|
|
|
477 |
}
|
|
|
478 |
|
|
|
479 |
// echo '<b>'.$columnID.$rowID.'</b><br />';
|
|
|
480 |
$cellDataText = (isset($namespacesContent['text'])) ?
|
|
|
481 |
$cellData->children($namespacesContent['text']) :
|
|
|
482 |
'';
|
|
|
483 |
$cellDataOffice = $cellData->children($namespacesContent['office']);
|
|
|
484 |
$cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']);
|
|
|
485 |
$cellDataTableAttributes = $cellData->attributes($namespacesContent['table']);
|
|
|
486 |
|
|
|
487 |
// echo 'Office Attributes: ';
|
|
|
488 |
// print_r($cellDataOfficeAttributes);
|
|
|
489 |
// echo '<br />Table Attributes: ';
|
|
|
490 |
// print_r($cellDataTableAttributes);
|
|
|
491 |
// echo '<br />Cell Data Text';
|
|
|
492 |
// print_r($cellDataText);
|
|
|
493 |
// echo '<br />';
|
|
|
494 |
//
|
|
|
495 |
$type = $formatting = $hyperlink = null;
|
|
|
496 |
$hasCalculatedValue = false;
|
|
|
497 |
$cellDataFormula = '';
|
|
|
498 |
if (isset($cellDataTableAttributes['formula'])) {
|
|
|
499 |
$cellDataFormula = $cellDataTableAttributes['formula'];
|
|
|
500 |
$hasCalculatedValue = true;
|
|
|
501 |
}
|
|
|
502 |
|
|
|
503 |
if (isset($cellDataOffice->annotation)) {
|
|
|
504 |
// echo 'Cell has comment<br />';
|
|
|
505 |
$annotationText = $cellDataOffice->annotation->children($namespacesContent['text']);
|
|
|
506 |
$textArray = array();
|
|
|
507 |
foreach($annotationText as $t) {
|
|
|
508 |
foreach($t->span as $text) {
|
|
|
509 |
$textArray[] = (string)$text;
|
|
|
510 |
}
|
|
|
511 |
}
|
|
|
512 |
$text = implode("\n",$textArray);
|
|
|
513 |
// echo $text,'<br />';
|
|
|
514 |
$objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID )
|
|
|
515 |
// ->setAuthor( $author )
|
|
|
516 |
->setText($this->_parseRichText($text) );
|
|
|
517 |
}
|
|
|
518 |
|
|
|
519 |
if (isset($cellDataText->p)) {
|
|
|
520 |
// Consolidate if there are multiple p records (maybe with spans as well)
|
|
|
521 |
$dataArray = array();
|
|
|
522 |
// Text can have multiple text:p and within those, multiple text:span.
|
|
|
523 |
// text:p newlines, but text:span does not.
|
|
|
524 |
// Also, here we assume there is no text data is span fields are specified, since
|
|
|
525 |
// we have no way of knowing proper positioning anyway.
|
|
|
526 |
foreach ($cellDataText->p as $pData) {
|
|
|
527 |
if (isset($pData->span)) {
|
|
|
528 |
// span sections do not newline, so we just create one large string here
|
|
|
529 |
$spanSection = "";
|
|
|
530 |
foreach ($pData->span as $spanData) {
|
|
|
531 |
$spanSection .= $spanData;
|
|
|
532 |
}
|
|
|
533 |
array_push($dataArray, $spanSection);
|
|
|
534 |
} else {
|
|
|
535 |
array_push($dataArray, $pData);
|
|
|
536 |
}
|
|
|
537 |
}
|
|
|
538 |
$allCellDataText = implode($dataArray, "\n");
|
|
|
539 |
|
|
|
540 |
// echo 'Value Type is '.$cellDataOfficeAttributes['value-type'].'<br />';
|
|
|
541 |
switch ($cellDataOfficeAttributes['value-type']) {
|
|
|
542 |
case 'string' :
|
|
|
543 |
$type = PHPExcel_Cell_DataType::TYPE_STRING;
|
|
|
544 |
$dataValue = $allCellDataText;
|
|
|
545 |
if (isset($dataValue->a)) {
|
|
|
546 |
$dataValue = $dataValue->a;
|
|
|
547 |
$cellXLinkAttributes = $dataValue->attributes($namespacesContent['xlink']);
|
|
|
548 |
$hyperlink = $cellXLinkAttributes['href'];
|
|
|
549 |
}
|
|
|
550 |
break;
|
|
|
551 |
case 'boolean' :
|
|
|
552 |
$type = PHPExcel_Cell_DataType::TYPE_BOOL;
|
|
|
553 |
$dataValue = ($allCellDataText == 'TRUE') ? True : False;
|
|
|
554 |
break;
|
|
|
555 |
case 'percentage' :
|
|
|
556 |
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
|
|
557 |
$dataValue = (float) $cellDataOfficeAttributes['value'];
|
|
|
558 |
if (floor($dataValue) == $dataValue) {
|
|
|
559 |
$dataValue = (integer) $dataValue;
|
|
|
560 |
}
|
|
|
561 |
$formatting = PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00;
|
|
|
562 |
break;
|
|
|
563 |
case 'currency' :
|
|
|
564 |
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
|
|
565 |
$dataValue = (float) $cellDataOfficeAttributes['value'];
|
|
|
566 |
if (floor($dataValue) == $dataValue) {
|
|
|
567 |
$dataValue = (integer) $dataValue;
|
|
|
568 |
}
|
|
|
569 |
$formatting = PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE;
|
|
|
570 |
break;
|
|
|
571 |
case 'float' :
|
|
|
572 |
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
|
|
573 |
$dataValue = (float) $cellDataOfficeAttributes['value'];
|
|
|
574 |
if (floor($dataValue) == $dataValue) {
|
|
|
575 |
if ($dataValue = (integer) $dataValue)
|
|
|
576 |
$dataValue = (integer) $dataValue;
|
|
|
577 |
else
|
|
|
578 |
$dataValue = (float) $dataValue;
|
|
|
579 |
}
|
|
|
580 |
break;
|
|
|
581 |
case 'date' :
|
|
|
582 |
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
|
|
583 |
$dateObj = new DateTime($cellDataOfficeAttributes['date-value'], $GMT);
|
|
|
584 |
$dateObj->setTimeZone($timezoneObj);
|
|
|
585 |
list($year,$month,$day,$hour,$minute,$second) = explode(' ',$dateObj->format('Y m d H i s'));
|
|
|
586 |
$dataValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year,$month,$day,$hour,$minute,$second);
|
|
|
587 |
if ($dataValue != floor($dataValue)) {
|
|
|
588 |
$formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15.' '.PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4;
|
|
|
589 |
} else {
|
|
|
590 |
$formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15;
|
|
|
591 |
}
|
|
|
592 |
break;
|
|
|
593 |
case 'time' :
|
|
|
594 |
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
|
|
595 |
$dataValue = PHPExcel_Shared_Date::PHPToExcel(strtotime('01-01-1970 '.implode(':',sscanf($cellDataOfficeAttributes['time-value'],'PT%dH%dM%dS'))));
|
|
|
596 |
$formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4;
|
|
|
597 |
break;
|
|
|
598 |
}
|
|
|
599 |
// echo 'Data value is '.$dataValue.'<br />';
|
|
|
600 |
// if ($hyperlink !== NULL) {
|
|
|
601 |
// echo 'Hyperlink is '.$hyperlink.'<br />';
|
|
|
602 |
// }
|
|
|
603 |
} else {
|
|
|
604 |
$type = PHPExcel_Cell_DataType::TYPE_NULL;
|
|
|
605 |
$dataValue = NULL;
|
|
|
606 |
}
|
|
|
607 |
|
|
|
608 |
if ($hasCalculatedValue) {
|
|
|
609 |
$type = PHPExcel_Cell_DataType::TYPE_FORMULA;
|
|
|
610 |
// echo 'Formula: '.$cellDataFormula.'<br />';
|
|
|
611 |
$cellDataFormula = substr($cellDataFormula,strpos($cellDataFormula,':=')+1);
|
|
|
612 |
$temp = explode('"',$cellDataFormula);
|
|
|
613 |
$tKey = false;
|
|
|
614 |
foreach($temp as &$value) {
|
|
|
615 |
// Only replace in alternate array entries (i.e. non-quoted blocks)
|
|
|
616 |
if ($tKey = !$tKey) {
|
|
|
617 |
$value = preg_replace('/\[\.(.*):\.(.*)\]/Ui','$1:$2',$value);
|
|
|
618 |
$value = preg_replace('/\[\.(.*)\]/Ui','$1',$value);
|
|
|
619 |
$value = PHPExcel_Calculation::_translateSeparator(';',',',$value,$inBraces);
|
|
|
620 |
}
|
|
|
621 |
}
|
|
|
622 |
unset($value);
|
|
|
623 |
// Then rebuild the formula string
|
|
|
624 |
$cellDataFormula = implode('"',$temp);
|
|
|
625 |
// echo 'Adjusted Formula: '.$cellDataFormula.'<br />';
|
|
|
626 |
}
|
|
|
627 |
|
|
|
628 |
$colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ?
|
|
|
629 |
$cellDataTableAttributes['number-columns-repeated'] : 1;
|
|
|
630 |
if ($type !== NULL) {
|
|
|
631 |
for ($i = 0; $i < $colRepeats; ++$i) {
|
|
|
632 |
if ($i > 0) {
|
|
|
633 |
++$columnID;
|
|
|
634 |
}
|
|
|
635 |
if ($type !== PHPExcel_Cell_DataType::TYPE_NULL) {
|
|
|
636 |
for ($rowAdjust = 0; $rowAdjust < $rowRepeats; ++$rowAdjust) {
|
|
|
637 |
$rID = $rowID + $rowAdjust;
|
|
|
638 |
$objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $dataValue),$type);
|
|
|
639 |
if ($hasCalculatedValue) {
|
|
|
640 |
// echo 'Forumla result is '.$dataValue.'<br />';
|
|
|
641 |
$objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setCalculatedValue($dataValue);
|
|
|
642 |
}
|
|
|
643 |
if ($formatting !== NULL) {
|
|
|
644 |
$objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode($formatting);
|
|
|
645 |
} else {
|
|
|
646 |
$objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL);
|
|
|
647 |
}
|
|
|
648 |
if ($hyperlink !== NULL) {
|
|
|
649 |
$objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->getHyperlink()->setUrl($hyperlink);
|
|
|
650 |
}
|
|
|
651 |
}
|
|
|
652 |
}
|
|
|
653 |
}
|
|
|
654 |
}
|
|
|
655 |
|
|
|
656 |
// Merged cells
|
|
|
657 |
if ((isset($cellDataTableAttributes['number-columns-spanned'])) || (isset($cellDataTableAttributes['number-rows-spanned']))) {
|
|
|
658 |
if (($type !== PHPExcel_Cell_DataType::TYPE_NULL) || (!$this->_readDataOnly)) {
|
|
|
659 |
$columnTo = $columnID;
|
|
|
660 |
if (isset($cellDataTableAttributes['number-columns-spanned'])) {
|
|
|
661 |
$columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cellDataTableAttributes['number-columns-spanned'] -2);
|
|
|
662 |
}
|
|
|
663 |
$rowTo = $rowID;
|
|
|
664 |
if (isset($cellDataTableAttributes['number-rows-spanned'])) {
|
|
|
665 |
$rowTo = $rowTo + $cellDataTableAttributes['number-rows-spanned'] - 1;
|
|
|
666 |
}
|
|
|
667 |
$cellRange = $columnID.$rowID.':'.$columnTo.$rowTo;
|
|
|
668 |
$objPHPExcel->getActiveSheet()->mergeCells($cellRange);
|
|
|
669 |
}
|
|
|
670 |
}
|
|
|
671 |
|
|
|
672 |
++$columnID;
|
|
|
673 |
}
|
|
|
674 |
$rowID += $rowRepeats;
|
|
|
675 |
break;
|
|
|
676 |
}
|
|
|
677 |
}
|
|
|
678 |
++$worksheetID;
|
|
|
679 |
}
|
|
|
680 |
}
|
|
|
681 |
|
|
|
682 |
// Return
|
|
|
683 |
return $objPHPExcel;
|
|
|
684 |
}
|
|
|
685 |
|
|
|
686 |
|
|
|
687 |
private function _parseRichText($is = '') {
|
|
|
688 |
$value = new PHPExcel_RichText();
|
|
|
689 |
|
|
|
690 |
$value->createText($is);
|
|
|
691 |
|
|
|
692 |
return $value;
|
|
|
693 |
}
|
|
|
694 |
|
|
|
695 |
}
|