PageRenderTime 46ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/add-ons/PHPExcel/PHPExcel/Reader/OOCalc.php

https://github.com/jcplat/console-seolan
PHP | 412 lines | 224 code | 44 blank | 144 comment | 37 complexity | 9fa434ccf777a7e9cee43dc116aae26d MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, GPL-3.0, Apache-2.0, BSD-3-Clause
  1. <?php
  2. /**
  3. * PHPExcel
  4. *
  5. * Copyright (c) 2006 - 2009 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 - 2009 PHPExcel (http://www.codeplex.com/PHPExcel)
  24. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  25. * @version 1.7.1, 2009-11-02
  26. */
  27. /** PHPExcel root directory */
  28. if (!defined('PHPEXCEL_ROOT')) {
  29. /**
  30. * @ignore
  31. */
  32. define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');
  33. }
  34. /** PHPExcel */
  35. require_once PHPEXCEL_ROOT . 'PHPExcel.php';
  36. /** PHPExcel_Reader_IReader */
  37. require_once PHPEXCEL_ROOT . 'PHPExcel/Reader/IReader.php';
  38. /** PHPExcel_Worksheet */
  39. require_once PHPEXCEL_ROOT . 'PHPExcel/Worksheet.php';
  40. /** PHPExcel_Cell */
  41. require_once PHPEXCEL_ROOT . 'PHPExcel/Cell.php';
  42. /** PHPExcel_Calculation */
  43. require_once PHPEXCEL_ROOT . 'PHPExcel/Calculation.php';
  44. /** PHPExcel_Reader_DefaultReadFilter */
  45. require_once PHPEXCEL_ROOT . 'PHPExcel/Reader/DefaultReadFilter.php';
  46. /**
  47. * PHPExcel_Reader_OOCalc
  48. *
  49. * @category PHPExcel
  50. * @package PHPExcel_Reader
  51. * @copyright Copyright (c) 2006 - 2009 PHPExcel (http://www.codeplex.com/PHPExcel)
  52. */
  53. class PHPExcel_Reader_OOCalc implements PHPExcel_Reader_IReader
  54. {
  55. /**
  56. * Input encoding
  57. *
  58. * @var string
  59. */
  60. private $_inputEncoding;
  61. /**
  62. * Sheet index to read
  63. *
  64. * @var int
  65. */
  66. private $_sheetIndex;
  67. /**
  68. * Formats
  69. *
  70. * @var array
  71. */
  72. private $_styles = array();
  73. /**
  74. * PHPExcel_Reader_IReadFilter instance
  75. *
  76. * @var PHPExcel_Reader_IReadFilter
  77. */
  78. private $_readFilter = null;
  79. /**
  80. * Create a new PHPExcel_Reader_OOCalc
  81. */
  82. public function __construct() {
  83. $this->_sheetIndex = 0;
  84. $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter();
  85. }
  86. /**
  87. * Can the current PHPExcel_Reader_IReader read the file?
  88. *
  89. * @param string $pFileName
  90. * @return boolean
  91. */
  92. public function canRead($pFilename)
  93. {
  94. // Check if file exists
  95. if (!file_exists($pFilename)) {
  96. throw new Exception("Could not open " . $pFilename . " for reading! File does not exist.");
  97. }
  98. // Load file
  99. $zip = new ZipArchive;
  100. if ($zip->open($pFilename) === true) {
  101. // check if it is an OOXML archive
  102. $mimeType = $zip->getFromName("mimetype");
  103. $zip->close();
  104. return ($mimeType === 'application/vnd.oasis.opendocument.spreadsheet');
  105. }
  106. return false;
  107. }
  108. /**
  109. * Loads PHPExcel from file
  110. *
  111. * @param string $pFilename
  112. * @throws Exception
  113. */
  114. public function load($pFilename)
  115. {
  116. // Create new PHPExcel
  117. $objPHPExcel = new PHPExcel();
  118. // Load into this instance
  119. return $this->loadIntoExisting($pFilename, $objPHPExcel);
  120. }
  121. /**
  122. * Read filter
  123. *
  124. * @return PHPExcel_Reader_IReadFilter
  125. */
  126. public function getReadFilter() {
  127. return $this->_readFilter;
  128. }
  129. /**
  130. * Set read filter
  131. *
  132. * @param PHPExcel_Reader_IReadFilter $pValue
  133. */
  134. public function setReadFilter(PHPExcel_Reader_IReadFilter $pValue) {
  135. $this->_readFilter = $pValue;
  136. }
  137. private static function identifyFixedStyleValue($styleList,&$styleAttributeValue) {
  138. $styleAttributeValue = strtolower($styleAttributeValue);
  139. foreach($styleList as $style) {
  140. if ($styleAttributeValue == strtolower($style)) {
  141. $styleAttributeValue = $style;
  142. return true;
  143. }
  144. }
  145. return false;
  146. }
  147. /**
  148. * Loads PHPExcel from file into PHPExcel instance
  149. *
  150. * @param string $pFilename
  151. * @param PHPExcel $objPHPExcel
  152. * @throws Exception
  153. */
  154. public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
  155. {
  156. // Check if file exists
  157. if (!file_exists($pFilename)) {
  158. throw new Exception("Could not open " . $pFilename . " for reading! File does not exist.");
  159. }
  160. $zip = new ZipArchive;
  161. if ($zip->open($pFilename) === true) {
  162. // echo '<h1>Meta Information</h1>';
  163. $xml = simplexml_load_string($zip->getFromName("meta.xml"));
  164. $namespacesMeta = $xml->getNamespaces(true);
  165. // echo '<pre>';
  166. // print_r($namespacesMeta);
  167. // echo '</pre><hr />';
  168. $docProps = $objPHPExcel->getProperties();
  169. $officeProperty = $xml->children($namespacesMeta['office']);
  170. foreach($officeProperty as $officePropertyData) {
  171. $officePropertyDC = array();
  172. if (isset($namespacesMeta['dc'])) {
  173. $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']);
  174. }
  175. foreach($officePropertyDC as $propertyName => $propertyValue) {
  176. // echo $propertyName.' = '.$propertyValue.'<hr />';
  177. switch ($propertyName) {
  178. case 'title' :
  179. $docProps->setTitle($propertyValue);
  180. break;
  181. case 'subject' :
  182. $docProps->setSubject($propertyValue);
  183. break;
  184. case 'creator' :
  185. $docProps->setCreator($propertyValue);
  186. break;
  187. case 'date' :
  188. $creationDate = strtotime($propertyValue);
  189. $docProps->setCreated($creationDate);
  190. break;
  191. case 'description' :
  192. $docProps->setDescription($propertyValue);
  193. break;
  194. }
  195. }
  196. $officePropertyMeta = array();
  197. if (isset($namespacesMeta['dc'])) {
  198. $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);
  199. }
  200. foreach($officePropertyMeta as $propertyName => $propertyValue) {
  201. $propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']);
  202. // echo $propertyName.' = '.$propertyValue.'<br />';
  203. // foreach ($propertyValueAttributes as $key => $value) {
  204. // echo $key.' = '.$value.'<br />';
  205. // }
  206. // echo '<hr />';
  207. //
  208. switch ($propertyName) {
  209. case 'keyword' :
  210. $docProps->setKeywords($propertyValue);
  211. break;
  212. }
  213. }
  214. }
  215. // echo '<h1>Workbook Content</h1>';
  216. $xml = simplexml_load_string($zip->getFromName("content.xml"));
  217. $namespacesContent = $xml->getNamespaces(true);
  218. // echo '<pre>';
  219. // print_r($namespacesContent);
  220. // echo '</pre><hr />';
  221. $workbook = $xml->children($namespacesContent['office']);
  222. foreach($workbook->body->spreadsheet as $workbookData) {
  223. $workbookData = $workbookData->children($namespacesContent['table']);
  224. $worksheetID = 0;
  225. foreach($workbookData->table as $worksheetData) {
  226. // echo '<h2>Worksheet '.$worksheetData['name'].'</h2>';
  227. // Create new Worksheet
  228. $objPHPExcel->createSheet();
  229. $objPHPExcel->setActiveSheetIndex($worksheetID);
  230. $worksheetData = $worksheetData->children($namespacesContent['table']);
  231. if (isset($worksheetData['name'])) {
  232. $worksheetName = $worksheetData['name'];
  233. $objPHPExcel->getActiveSheet()->setTitle($worksheetName);
  234. }
  235. $rowID = 1;
  236. foreach($worksheetData as $key => $rowData) {
  237. // echo '<b>'.$key.'</b><br />';
  238. switch ($key) {
  239. case 'table-row' :
  240. $columnID = 'A';
  241. foreach($rowData as $key => $cellData) {
  242. // echo '<b>'.$columnID.$rowID.'</b><br />';
  243. $cellDataText = $cellData->children($namespacesContent['text']);
  244. $cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']);
  245. $cellDataTableAttributes = $cellData->attributes($namespacesContent['table']);
  246. // echo 'Office Attributes: ';
  247. // print_r($cellDataOfficeAttributes);
  248. // echo '<br />Table Attributes: ';
  249. // print_r($cellDataTableAttributes);
  250. // echo '<br />';
  251. //
  252. $type = $formatting = null;
  253. $hasCalculatedValue = false;
  254. $cellDataFormula = '';
  255. if (isset($cellDataTableAttributes['formula'])) {
  256. $cellDataFormula = $cellDataTableAttributes['formula'];
  257. $hasCalculatedValue = true;
  258. }
  259. if (isset($cellDataText->p)) {
  260. switch ($cellDataOfficeAttributes['value-type']) {
  261. case 'string' :
  262. $type = PHPExcel_Cell_DataType::TYPE_STRING;
  263. $dataValue = $cellDataText->p;
  264. break;
  265. case 'boolean' :
  266. $type = PHPExcel_Cell_DataType::TYPE_BOOL;
  267. $dataValue = ($cellDataText->p == 'TRUE') ? True : False;
  268. break;
  269. case 'float' :
  270. $type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
  271. $dataValue = (float) $cellDataOfficeAttributes['value'];
  272. if (floor($dataValue) == $dataValue) {
  273. $dataValue = (integer) $dataValue;
  274. }
  275. break;
  276. case 'date' :
  277. $type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
  278. $dataValue = PHPExcel_Shared_Date::PHPToExcel(strtotime($cellDataOfficeAttributes['date-value']));
  279. if ($dataValue != floor($dataValue)) {
  280. $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15.' '.PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4;
  281. } else {
  282. $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15;
  283. }
  284. break;
  285. case 'time' :
  286. $type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
  287. $dataValue = PHPExcel_Shared_Date::PHPToExcel(strtotime('01-01-1970 '.implode(':',sscanf($cellDataOfficeAttributes['time-value'],'PT%dH%dM%dS'))));
  288. $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4;
  289. break;
  290. }
  291. }
  292. if ($hasCalculatedValue) {
  293. $type = PHPExcel_Cell_DataType::TYPE_FORMULA;
  294. // echo 'Formula: '.$cellDataFormula.'<br />';
  295. $cellDataFormula = substr($cellDataFormula,strpos($cellDataFormula,':=')+1);
  296. $temp = explode('"',$cellDataFormula);
  297. foreach($temp as $key => &$value) {
  298. // Only replace in alternate array entries (i.e. non-quoted blocks)
  299. if (($key % 2) == 0) {
  300. $value = preg_replace('/\[\.(.*):\.(.*)\]/Ui','$1:$2',$value);
  301. $value = preg_replace('/\[\.(.*)\]/Ui','$1',$value);
  302. }
  303. }
  304. unset($value);
  305. // Then rebuild the formula string
  306. $cellDataFormula = implode('"',$temp);
  307. // echo 'Adjusted Formula: '.$cellDataFormula.'<br />';
  308. }
  309. if (!is_null($type)) {
  310. $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $dataValue),$type);
  311. if ($hasCalculatedValue) {
  312. // echo 'Forumla result is '.$cellValue.'<br />';
  313. $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setCalculatedValue($dataValue);
  314. }
  315. if (($cellDataOfficeAttributes['value-type'] == 'date') ||
  316. ($cellDataOfficeAttributes['value-type'] == 'time')) {
  317. $objPHPExcel->getActiveSheet()->getStyle($columnID.$rowID)->getNumberFormat()->setFormatCode($formatting);
  318. }
  319. }
  320. // Merged cells
  321. if ((isset($cellDataTableAttributes['number-columns-spanned'])) || (isset($cellDataTableAttributes['number-rows-spanned']))) {
  322. $columnTo = $columnID;
  323. if (isset($cellDataTableAttributes['number-columns-spanned'])) {
  324. $columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cellDataTableAttributes['number-columns-spanned'] -2);
  325. }
  326. $rowTo = $rowID;
  327. if (isset($cellDataTableAttributes['number-rows-spanned'])) {
  328. $rowTo = $rowTo + $cellDataTableAttributes['number-rows-spanned'] - 1;
  329. }
  330. $cellRange = $columnID.$rowID.':'.$columnTo.$rowTo;
  331. $objPHPExcel->getActiveSheet()->mergeCells($cellRange);
  332. }
  333. if (isset($cellDataTableAttributes['number-columns-repeated'])) {
  334. // echo 'Repeated '.$cellDataTableAttributes['number-columns-repeated'].' times<br />';
  335. $columnID = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cellDataTableAttributes['number-columns-repeated'] - 2);
  336. }
  337. ++$columnID;
  338. }
  339. ++$rowID;
  340. break;
  341. }
  342. }
  343. ++$worksheetID;
  344. }
  345. }
  346. }
  347. // Return
  348. return $objPHPExcel;
  349. }
  350. /**
  351. * Get sheet index
  352. *
  353. * @return int
  354. */
  355. public function getSheetIndex() {
  356. return $this->_sheetIndex;
  357. }
  358. /**
  359. * Set sheet index
  360. *
  361. * @param int $pValue Sheet index
  362. * @return PHPExcel_Reader_OOCalc
  363. */
  364. public function setSheetIndex($pValue = 0) {
  365. $this->_sheetIndex = $pValue;
  366. return $this;
  367. }
  368. }