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.

850 lines
41 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_Gnumeric
  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_Gnumeric extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader
  36. {
  37. /**
  38. * Formats
  39. *
  40. * @var array
  41. */
  42. private $styles = array();
  43. /**
  44. * Shared Expressions
  45. *
  46. * @var array
  47. */
  48. private $expressions = array();
  49. private $referenceHelper = null;
  50. /**
  51. * Create a new PHPExcel_Reader_Gnumeric
  52. */
  53. public function __construct()
  54. {
  55. $this->readFilter = new PHPExcel_Reader_DefaultReadFilter();
  56. $this->referenceHelper = PHPExcel_ReferenceHelper::getInstance();
  57. }
  58. /**
  59. * Can the current PHPExcel_Reader_IReader read the file?
  60. *
  61. * @param string $pFilename
  62. * @return boolean
  63. * @throws PHPExcel_Reader_Exception
  64. */
  65. public function canRead($pFilename)
  66. {
  67. // Check if file exists
  68. if (!file_exists($pFilename)) {
  69. throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
  70. }
  71. // Check if gzlib functions are available
  72. if (!function_exists('gzread')) {
  73. throw new PHPExcel_Reader_Exception("gzlib library is not enabled");
  74. }
  75. // Read signature data (first 3 bytes)
  76. $fh = fopen($pFilename, 'r');
  77. $data = fread($fh, 2);
  78. fclose($fh);
  79. if ($data != chr(0x1F).chr(0x8B)) {
  80. return false;
  81. }
  82. return true;
  83. }
  84. /**
  85. * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object
  86. *
  87. * @param string $pFilename
  88. * @throws PHPExcel_Reader_Exception
  89. */
  90. public function listWorksheetNames($pFilename)
  91. {
  92. // Check if file exists
  93. if (!file_exists($pFilename)) {
  94. throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
  95. }
  96. $xml = new XMLReader();
  97. $xml->xml($this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, PHPExcel_Settings::getLibXmlLoaderOptions());
  98. $xml->setParserProperty(2, true);
  99. $worksheetNames = array();
  100. while ($xml->read()) {
  101. if ($xml->name == 'gnm:SheetName' && $xml->nodeType == XMLReader::ELEMENT) {
  102. $xml->read(); // Move onto the value node
  103. $worksheetNames[] = (string) $xml->value;
  104. } elseif ($xml->name == 'gnm:Sheets') {
  105. // break out of the loop once we've got our sheet names rather than parse the entire file
  106. break;
  107. }
  108. }
  109. return $worksheetNames;
  110. }
  111. /**
  112. * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)
  113. *
  114. * @param string $pFilename
  115. * @throws PHPExcel_Reader_Exception
  116. */
  117. public function listWorksheetInfo($pFilename)
  118. {
  119. // Check if file exists
  120. if (!file_exists($pFilename)) {
  121. throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
  122. }
  123. $xml = new XMLReader();
  124. $xml->xml($this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, PHPExcel_Settings::getLibXmlLoaderOptions());
  125. $xml->setParserProperty(2, true);
  126. $worksheetInfo = array();
  127. while ($xml->read()) {
  128. if ($xml->name == 'gnm:Sheet' && $xml->nodeType == XMLReader::ELEMENT) {
  129. $tmpInfo = array(
  130. 'worksheetName' => '',
  131. 'lastColumnLetter' => 'A',
  132. 'lastColumnIndex' => 0,
  133. 'totalRows' => 0,
  134. 'totalColumns' => 0,
  135. );
  136. while ($xml->read()) {
  137. if ($xml->name == 'gnm:Name' && $xml->nodeType == XMLReader::ELEMENT) {
  138. $xml->read(); // Move onto the value node
  139. $tmpInfo['worksheetName'] = (string) $xml->value;
  140. } elseif ($xml->name == 'gnm:MaxCol' && $xml->nodeType == XMLReader::ELEMENT) {
  141. $xml->read(); // Move onto the value node
  142. $tmpInfo['lastColumnIndex'] = (int) $xml->value;
  143. $tmpInfo['totalColumns'] = (int) $xml->value + 1;
  144. } elseif ($xml->name == 'gnm:MaxRow' && $xml->nodeType == XMLReader::ELEMENT) {
  145. $xml->read(); // Move onto the value node
  146. $tmpInfo['totalRows'] = (int) $xml->value + 1;
  147. break;
  148. }
  149. }
  150. $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
  151. $worksheetInfo[] = $tmpInfo;
  152. }
  153. }
  154. return $worksheetInfo;
  155. }
  156. private function gzfileGetContents($filename)
  157. {
  158. $file = @gzopen($filename, 'rb');
  159. if ($file !== false) {
  160. $data = '';
  161. while (!gzeof($file)) {
  162. $data .= gzread($file, 1024);
  163. }
  164. gzclose($file);
  165. }
  166. return $data;
  167. }
  168. /**
  169. * Loads PHPExcel from file
  170. *
  171. * @param string $pFilename
  172. * @return PHPExcel
  173. * @throws PHPExcel_Reader_Exception
  174. */
  175. public function load($pFilename)
  176. {
  177. // Create new PHPExcel
  178. $objPHPExcel = new PHPExcel();
  179. // Load into this instance
  180. return $this->loadIntoExisting($pFilename, $objPHPExcel);
  181. }
  182. /**
  183. * Loads PHPExcel from file into PHPExcel instance
  184. *
  185. * @param string $pFilename
  186. * @param PHPExcel $objPHPExcel
  187. * @return PHPExcel
  188. * @throws PHPExcel_Reader_Exception
  189. */
  190. public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
  191. {
  192. // Check if file exists
  193. if (!file_exists($pFilename)) {
  194. throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
  195. }
  196. $timezoneObj = new DateTimeZone('Europe/London');
  197. $GMT = new DateTimeZone('UTC');
  198. $gFileData = $this->gzfileGetContents($pFilename);
  199. // echo '<pre>';
  200. // echo htmlentities($gFileData,ENT_QUOTES,'UTF-8');
  201. // echo '</pre><hr />';
  202. //
  203. $xml = simplexml_load_string($this->securityScan($gFileData), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());
  204. $namespacesMeta = $xml->getNamespaces(true);
  205. // var_dump($namespacesMeta);
  206. //
  207. $gnmXML = $xml->children($namespacesMeta['gnm']);
  208. $docProps = $objPHPExcel->getProperties();
  209. // Document Properties are held differently, depending on the version of Gnumeric
  210. if (isset($namespacesMeta['office'])) {
  211. $officeXML = $xml->children($namespacesMeta['office']);
  212. $officeDocXML = $officeXML->{'document-meta'};
  213. $officeDocMetaXML = $officeDocXML->meta;
  214. foreach ($officeDocMetaXML as $officePropertyData) {
  215. $officePropertyDC = array();
  216. if (isset($namespacesMeta['dc'])) {
  217. $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']);
  218. }
  219. foreach ($officePropertyDC as $propertyName => $propertyValue) {
  220. $propertyValue = (string) $propertyValue;
  221. switch ($propertyName) {
  222. case 'title':
  223. $docProps->setTitle(trim($propertyValue));
  224. break;
  225. case 'subject':
  226. $docProps->setSubject(trim($propertyValue));
  227. break;
  228. case 'creator':
  229. $docProps->setCreator(trim($propertyValue));
  230. $docProps->setLastModifiedBy(trim($propertyValue));
  231. break;
  232. case 'date':
  233. $creationDate = strtotime(trim($propertyValue));
  234. $docProps->setCreated($creationDate);
  235. $docProps->setModified($creationDate);
  236. break;
  237. case 'description':
  238. $docProps->setDescription(trim($propertyValue));
  239. break;
  240. }
  241. }
  242. $officePropertyMeta = array();
  243. if (isset($namespacesMeta['meta'])) {
  244. $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);
  245. }
  246. foreach ($officePropertyMeta as $propertyName => $propertyValue) {
  247. $attributes = $propertyValue->attributes($namespacesMeta['meta']);
  248. $propertyValue = (string) $propertyValue;
  249. switch ($propertyName) {
  250. case 'keyword':
  251. $docProps->setKeywords(trim($propertyValue));
  252. break;
  253. case 'initial-creator':
  254. $docProps->setCreator(trim($propertyValue));
  255. $docProps->setLastModifiedBy(trim($propertyValue));
  256. break;
  257. case 'creation-date':
  258. $creationDate = strtotime(trim($propertyValue));
  259. $docProps->setCreated($creationDate);
  260. $docProps->setModified($creationDate);
  261. break;
  262. case 'user-defined':
  263. list(, $attrName) = explode(':', $attributes['name']);
  264. switch ($attrName) {
  265. case 'publisher':
  266. $docProps->setCompany(trim($propertyValue));
  267. break;
  268. case 'category':
  269. $docProps->setCategory(trim($propertyValue));
  270. break;
  271. case 'manager':
  272. $docProps->setManager(trim($propertyValue));
  273. break;
  274. }
  275. break;
  276. }
  277. }
  278. }
  279. } elseif (isset($gnmXML->Summary)) {
  280. foreach ($gnmXML->Summary->Item as $summaryItem) {
  281. $propertyName = $summaryItem->name;
  282. $propertyValue = $summaryItem->{'val-string'};
  283. switch ($propertyName) {
  284. case 'title':
  285. $docProps->setTitle(trim($propertyValue));
  286. break;
  287. case 'comments':
  288. $docProps->setDescription(trim($propertyValue));
  289. break;
  290. case 'keywords':
  291. $docProps->setKeywords(trim($propertyValue));
  292. break;
  293. case 'category':
  294. $docProps->setCategory(trim($propertyValue));
  295. break;
  296. case 'manager':
  297. $docProps->setManager(trim($propertyValue));
  298. break;
  299. case 'author':
  300. $docProps->setCreator(trim($propertyValue));
  301. $docProps->setLastModifiedBy(trim($propertyValue));
  302. break;
  303. case 'company':
  304. $docProps->setCompany(trim($propertyValue));
  305. break;
  306. }
  307. }
  308. }
  309. $worksheetID = 0;
  310. foreach ($gnmXML->Sheets->Sheet as $sheet) {
  311. $worksheetName = (string) $sheet->Name;
  312. // echo '<b>Worksheet: ', $worksheetName,'</b><br />';
  313. if ((isset($this->loadSheetsOnly)) && (!in_array($worksheetName, $this->loadSheetsOnly))) {
  314. continue;
  315. }
  316. $maxRow = $maxCol = 0;
  317. // Create new Worksheet
  318. $objPHPExcel->createSheet();
  319. $objPHPExcel->setActiveSheetIndex($worksheetID);
  320. // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula
  321. // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet
  322. // name in line with the formula, not the reverse
  323. $objPHPExcel->getActiveSheet()->setTitle($worksheetName, false);
  324. if ((!$this->readDataOnly) && (isset($sheet->PrintInformation))) {
  325. if (isset($sheet->PrintInformation->Margins)) {
  326. foreach ($sheet->PrintInformation->Margins->children('gnm', true) as $key => $margin) {
  327. $marginAttributes = $margin->attributes();
  328. $marginSize = 72 / 100; // Default
  329. switch ($marginAttributes['PrefUnit']) {
  330. case 'mm':
  331. $marginSize = intval($marginAttributes['Points']) / 100;
  332. break;
  333. }
  334. switch ($key) {
  335. case 'top':
  336. $objPHPExcel->getActiveSheet()->getPageMargins()->setTop($marginSize);
  337. break;
  338. case 'bottom':
  339. $objPHPExcel->getActiveSheet()->getPageMargins()->setBottom($marginSize);
  340. break;
  341. case 'left':
  342. $objPHPExcel->getActiveSheet()->getPageMargins()->setLeft($marginSize);
  343. break;
  344. case 'right':
  345. $objPHPExcel->getActiveSheet()->getPageMargins()->setRight($marginSize);
  346. break;
  347. case 'header':
  348. $objPHPExcel->getActiveSheet()->getPageMargins()->setHeader($marginSize);
  349. break;
  350. case 'footer':
  351. $objPHPExcel->getActiveSheet()->getPageMargins()->setFooter($marginSize);
  352. break;
  353. }
  354. }
  355. }
  356. }
  357. foreach ($sheet->Cells->Cell as $cell) {
  358. $cellAttributes = $cell->attributes();
  359. $row = (int) $cellAttributes->Row + 1;
  360. $column = (int) $cellAttributes->Col;
  361. if ($row > $maxRow) {
  362. $maxRow = $row;
  363. }
  364. if ($column > $maxCol) {
  365. $maxCol = $column;
  366. }
  367. $column = PHPExcel_Cell::stringFromColumnIndex($column);
  368. // Read cell?
  369. if ($this->getReadFilter() !== null) {
  370. if (!$this->getReadFilter()->readCell($column, $row, $worksheetName)) {
  371. continue;
  372. }
  373. }
  374. $ValueType = $cellAttributes->ValueType;
  375. $ExprID = (string) $cellAttributes->ExprID;
  376. // echo 'Cell ', $column, $row,'<br />';
  377. // echo 'Type is ', $ValueType,'<br />';
  378. // echo 'Value is ', $cell,'<br />';
  379. $type = PHPExcel_Cell_DataType::TYPE_FORMULA;
  380. if ($ExprID > '') {
  381. if (((string) $cell) > '') {
  382. $this->expressions[$ExprID] = array(
  383. 'column' => $cellAttributes->Col,
  384. 'row' => $cellAttributes->Row,
  385. 'formula' => (string) $cell
  386. );
  387. // echo 'NEW EXPRESSION ', $ExprID,'<br />';
  388. } else {
  389. $expression = $this->expressions[$ExprID];
  390. $cell = $this->referenceHelper->updateFormulaReferences(
  391. $expression['formula'],
  392. 'A1',
  393. $cellAttributes->Col - $expression['column'],
  394. $cellAttributes->Row - $expression['row'],
  395. $worksheetName
  396. );
  397. // echo 'SHARED EXPRESSION ', $ExprID,'<br />';
  398. // echo 'New Value is ', $cell,'<br />';
  399. }
  400. $type = PHPExcel_Cell_DataType::TYPE_FORMULA;
  401. } else {
  402. switch ($ValueType) {
  403. case '10': // NULL
  404. $type = PHPExcel_Cell_DataType::TYPE_NULL;
  405. break;
  406. case '20': // Boolean
  407. $type = PHPExcel_Cell_DataType::TYPE_BOOL;
  408. $cell = ($cell == 'TRUE') ? true: false;
  409. break;
  410. case '30': // Integer
  411. $cell = intval($cell);
  412. // Excel 2007+ doesn't differentiate between integer and float, so set the value and dropthru to the next (numeric) case
  413. case '40': // Float
  414. $type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
  415. break;
  416. case '50': // Error
  417. $type = PHPExcel_Cell_DataType::TYPE_ERROR;
  418. break;
  419. case '60': // String
  420. $type = PHPExcel_Cell_DataType::TYPE_STRING;
  421. break;
  422. case '70': // Cell Range
  423. case '80': // Array
  424. }
  425. }
  426. $objPHPExcel->getActiveSheet()->getCell($column.$row)->setValueExplicit($cell, $type);
  427. }
  428. if ((!$this->readDataOnly) && (isset($sheet->Objects))) {
  429. foreach ($sheet->Objects->children('gnm', true) as $key => $comment) {
  430. $commentAttributes = $comment->attributes();
  431. // Only comment objects are handled at the moment
  432. if ($commentAttributes->Text) {
  433. $objPHPExcel->getActiveSheet()->getComment((string)$commentAttributes->ObjectBound)->setAuthor((string)$commentAttributes->Author)->setText($this->parseRichText((string)$commentAttributes->Text));
  434. }
  435. }
  436. }
  437. // echo '$maxCol=', $maxCol,'; $maxRow=', $maxRow,'<br />';
  438. //
  439. foreach ($sheet->Styles->StyleRegion as $styleRegion) {
  440. $styleAttributes = $styleRegion->attributes();
  441. if (($styleAttributes['startRow'] <= $maxRow) &&
  442. ($styleAttributes['startCol'] <= $maxCol)) {
  443. $startColumn = PHPExcel_Cell::stringFromColumnIndex((int) $styleAttributes['startCol']);
  444. $startRow = $styleAttributes['startRow'] + 1;
  445. $endColumn = ($styleAttributes['endCol'] > $maxCol) ? $maxCol : (int) $styleAttributes['endCol'];
  446. $endColumn = PHPExcel_Cell::stringFromColumnIndex($endColumn);
  447. $endRow = ($styleAttributes['endRow'] > $maxRow) ? $maxRow : $styleAttributes['endRow'];
  448. $endRow += 1;
  449. $cellRange = $startColumn.$startRow.':'.$endColumn.$endRow;
  450. // echo $cellRange,'<br />';
  451. $styleAttributes = $styleRegion->Style->attributes();
  452. // var_dump($styleAttributes);
  453. // echo '<br />';
  454. // We still set the number format mask for date/time values, even if readDataOnly is true
  455. if ((!$this->readDataOnly) ||
  456. (PHPExcel_Shared_Date::isDateTimeFormatCode((string) $styleAttributes['Format']))) {
  457. $styleArray = array();
  458. $styleArray['numberformat']['code'] = (string) $styleAttributes['Format'];
  459. // If readDataOnly is false, we set all formatting information
  460. if (!$this->readDataOnly) {
  461. switch ($styleAttributes['HAlign']) {
  462. case '1':
  463. $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL;
  464. break;
  465. case '2':
  466. $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_LEFT;
  467. break;
  468. case '4':
  469. $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_RIGHT;
  470. break;
  471. case '8':
  472. $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_CENTER;
  473. break;
  474. case '16':
  475. case '64':
  476. $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS;
  477. break;
  478. case '32':
  479. $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY;
  480. break;
  481. }
  482. switch ($styleAttributes['VAlign']) {
  483. case '1':
  484. $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_TOP;
  485. break;
  486. case '2':
  487. $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_BOTTOM;
  488. break;
  489. case '4':
  490. $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_CENTER;
  491. break;
  492. case '8':
  493. $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_JUSTIFY;
  494. break;
  495. }
  496. $styleArray['alignment']['wrap'] = ($styleAttributes['WrapText'] == '1') ? true : false;
  497. $styleArray['alignment']['shrinkToFit'] = ($styleAttributes['ShrinkToFit'] == '1') ? true : false;
  498. $styleArray['alignment']['indent'] = (intval($styleAttributes["Indent"]) > 0) ? $styleAttributes["indent"] : 0;
  499. $RGB = self::parseGnumericColour($styleAttributes["Fore"]);
  500. $styleArray['font']['color']['rgb'] = $RGB;
  501. $RGB = self::parseGnumericColour($styleAttributes["Back"]);
  502. $shade = $styleAttributes["Shade"];
  503. if (($RGB != '000000') || ($shade != '0')) {
  504. $styleArray['fill']['color']['rgb'] = $styleArray['fill']['startcolor']['rgb'] = $RGB;
  505. $RGB2 = self::parseGnumericColour($styleAttributes["PatternColor"]);
  506. $styleArray['fill']['endcolor']['rgb'] = $RGB2;
  507. switch ($shade) {
  508. case '1':
  509. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_SOLID;
  510. break;
  511. case '2':
  512. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR;
  513. break;
  514. case '3':
  515. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_GRADIENT_PATH;
  516. break;
  517. case '4':
  518. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN;
  519. break;
  520. case '5':
  521. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY;
  522. break;
  523. case '6':
  524. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID;
  525. break;
  526. case '7':
  527. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL;
  528. break;
  529. case '8':
  530. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS;
  531. break;
  532. case '9':
  533. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKUP;
  534. break;
  535. case '10':
  536. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL;
  537. break;
  538. case '11':
  539. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625;
  540. break;
  541. case '12':
  542. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_GRAY125;
  543. break;
  544. case '13':
  545. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN;
  546. break;
  547. case '14':
  548. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY;
  549. break;
  550. case '15':
  551. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID;
  552. break;
  553. case '16':
  554. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL;
  555. break;
  556. case '17':
  557. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS;
  558. break;
  559. case '18':
  560. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP;
  561. break;
  562. case '19':
  563. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL;
  564. break;
  565. case '20':
  566. $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY;
  567. break;
  568. }
  569. }
  570. $fontAttributes = $styleRegion->Style->Font->attributes();
  571. // var_dump($fontAttributes);
  572. // echo '<br />';
  573. $styleArray['font']['name'] = (string) $styleRegion->Style->Font;
  574. $styleArray['font']['size'] = intval($fontAttributes['Unit']);
  575. $styleArray['font']['bold'] = ($fontAttributes['Bold'] == '1') ? true : false;
  576. $styleArray['font']['italic'] = ($fontAttributes['Italic'] == '1') ? true : false;
  577. $styleArray['font']['strike'] = ($fontAttributes['StrikeThrough'] == '1') ? true : false;
  578. switch ($fontAttributes['Underline']) {
  579. case '1':
  580. $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_SINGLE;
  581. break;
  582. case '2':
  583. $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_DOUBLE;
  584. break;
  585. case '3':
  586. $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING;
  587. break;
  588. case '4':
  589. $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING;
  590. break;
  591. default:
  592. $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_NONE;
  593. break;
  594. }
  595. switch ($fontAttributes['Script']) {
  596. case '1':
  597. $styleArray['font']['superScript'] = true;
  598. break;
  599. case '-1':
  600. $styleArray['font']['subScript'] = true;
  601. break;
  602. }
  603. if (isset($styleRegion->Style->StyleBorder)) {
  604. if (isset($styleRegion->Style->StyleBorder->Top)) {
  605. $styleArray['borders']['top'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Top->attributes());
  606. }
  607. if (isset($styleRegion->Style->StyleBorder->Bottom)) {
  608. $styleArray['borders']['bottom'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Bottom->attributes());
  609. }
  610. if (isset($styleRegion->Style->StyleBorder->Left)) {
  611. $styleArray['borders']['left'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Left->attributes());
  612. }
  613. if (isset($styleRegion->Style->StyleBorder->Right)) {
  614. $styleArray['borders']['right'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Right->attributes());
  615. }
  616. if ((isset($styleRegion->Style->StyleBorder->Diagonal)) && (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}))) {
  617. $styleArray['borders']['diagonal'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes());
  618. $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_BOTH;
  619. } elseif (isset($styleRegion->Style->StyleBorder->Diagonal)) {
  620. $styleArray['borders']['diagonal'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes());
  621. $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_UP;
  622. } elseif (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'})) {
  623. $styleArray['borders']['diagonal'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}->attributes());
  624. $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_DOWN;
  625. }
  626. }
  627. if (isset($styleRegion->Style->HyperLink)) {
  628. // TO DO
  629. $hyperlink = $styleRegion->Style->HyperLink->attributes();
  630. }
  631. }
  632. // var_dump($styleArray);
  633. // echo '<br />';
  634. $objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($styleArray);
  635. }
  636. }
  637. }
  638. if ((!$this->readDataOnly) && (isset($sheet->Cols))) {
  639. // Column Widths
  640. $columnAttributes = $sheet->Cols->attributes();
  641. $defaultWidth = $columnAttributes['DefaultSizePts'] / 5.4;
  642. $c = 0;
  643. foreach ($sheet->Cols->ColInfo as $columnOverride) {
  644. $columnAttributes = $columnOverride->attributes();
  645. $column = $columnAttributes['No'];
  646. $columnWidth = $columnAttributes['Unit'] / 5.4;
  647. $hidden = ((isset($columnAttributes['Hidden'])) && ($columnAttributes['Hidden'] == '1')) ? true : false;
  648. $columnCount = (isset($columnAttributes['Count'])) ? $columnAttributes['Count'] : 1;
  649. while ($c < $column) {
  650. $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($defaultWidth);
  651. ++$c;
  652. }
  653. while (($c < ($column+$columnCount)) && ($c <= $maxCol)) {
  654. $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($columnWidth);
  655. if ($hidden) {
  656. $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setVisible(false);
  657. }
  658. ++$c;
  659. }
  660. }
  661. while ($c <= $maxCol) {
  662. $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($defaultWidth);
  663. ++$c;
  664. }
  665. }
  666. if ((!$this->readDataOnly) && (isset($sheet->Rows))) {
  667. // Row Heights
  668. $rowAttributes = $sheet->Rows->attributes();
  669. $defaultHeight = $rowAttributes['DefaultSizePts'];
  670. $r = 0;
  671. foreach ($sheet->Rows->RowInfo as $rowOverride) {
  672. $rowAttributes = $rowOverride->attributes();
  673. $row = $rowAttributes['No'];
  674. $rowHeight = $rowAttributes['Unit'];
  675. $hidden = ((isset($rowAttributes['Hidden'])) && ($rowAttributes['Hidden'] == '1')) ? true : false;
  676. $rowCount = (isset($rowAttributes['Count'])) ? $rowAttributes['Count'] : 1;
  677. while ($r < $row) {
  678. ++$r;
  679. $objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight);
  680. }
  681. while (($r < ($row+$rowCount)) && ($r < $maxRow)) {
  682. ++$r;
  683. $objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($rowHeight);
  684. if ($hidden) {
  685. $objPHPExcel->getActiveSheet()->getRowDimension($r)->setVisible(false);
  686. }
  687. }
  688. }
  689. while ($r < $maxRow) {
  690. ++$r;
  691. $objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight);
  692. }
  693. }
  694. // Handle Merged Cells in this worksheet
  695. if (isset($sheet->MergedRegions)) {
  696. foreach ($sheet->MergedRegions->Merge as $mergeCells) {
  697. if (strpos($mergeCells, ':') !== false) {
  698. $objPHPExcel->getActiveSheet()->mergeCells($mergeCells);
  699. }
  700. }
  701. }
  702. $worksheetID++;
  703. }
  704. // Loop through definedNames (global named ranges)
  705. if (isset($gnmXML->Names)) {
  706. foreach ($gnmXML->Names->Name as $namedRange) {
  707. $name = (string) $namedRange->name;
  708. $range = (string) $namedRange->value;
  709. if (stripos($range, '#REF!') !== false) {
  710. continue;
  711. }
  712. $range = explode('!', $range);
  713. $range[0] = trim($range[0], "'");
  714. if ($worksheet = $objPHPExcel->getSheetByName($range[0])) {
  715. $extractedRange = str_replace('$', '', $range[1]);
  716. $objPHPExcel->addNamedRange(new PHPExcel_NamedRange($name, $worksheet, $extractedRange));
  717. }
  718. }
  719. }
  720. // Return
  721. return $objPHPExcel;
  722. }
  723. private static function parseBorderAttributes($borderAttributes)
  724. {
  725. $styleArray = array();
  726. if (isset($borderAttributes["Color"])) {
  727. $styleArray['color']['rgb'] = self::parseGnumericColour($borderAttributes["Color"]);
  728. }
  729. switch ($borderAttributes["Style"]) {
  730. case '0':
  731. $styleArray['style'] = PHPExcel_Style_Border::BORDER_NONE;
  732. break;
  733. case '1':
  734. $styleArray['style'] = PHPExcel_Style_Border::BORDER_THIN;
  735. break;
  736. case '2':
  737. $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUM;
  738. break;
  739. case '3':
  740. $styleArray['style'] = PHPExcel_Style_Border::BORDER_SLANTDASHDOT;
  741. break;
  742. case '4':
  743. $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHED;
  744. break;
  745. case '5':
  746. $styleArray['style'] = PHPExcel_Style_Border::BORDER_THICK;
  747. break;
  748. case '6':
  749. $styleArray['style'] = PHPExcel_Style_Border::BORDER_DOUBLE;
  750. break;
  751. case '7':
  752. $styleArray['style'] = PHPExcel_Style_Border::BORDER_DOTTED;
  753. break;
  754. case '8':
  755. $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHED;
  756. break;
  757. case '9':
  758. $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHDOT;
  759. break;
  760. case '10':
  761. $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT;
  762. break;
  763. case '11':
  764. $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHDOTDOT;
  765. break;
  766. case '12':
  767. $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT;
  768. break;
  769. case '13':
  770. $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT;
  771. break;
  772. }
  773. return $styleArray;
  774. }
  775. private function parseRichText($is = '')
  776. {
  777. $value = new PHPExcel_RichText();
  778. $value->createText($is);
  779. return $value;
  780. }
  781. private static function parseGnumericColour($gnmColour)
  782. {
  783. list($gnmR, $gnmG, $gnmB) = explode(':', $gnmColour);
  784. $gnmR = substr(str_pad($gnmR, 4, '0', STR_PAD_RIGHT), 0, 2);
  785. $gnmG = substr(str_pad($gnmG, 4, '0', STR_PAD_RIGHT), 0, 2);
  786. $gnmB = substr(str_pad($gnmB, 4, '0', STR_PAD_RIGHT), 0, 2);
  787. return $gnmR . $gnmG . $gnmB;
  788. }
  789. }