For God so loved the world, that He gave His only begotten Son, that all who believe in Him should not perish but have everlasting life
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

696 lines
36 KiB

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