Gnumeric.php 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  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. }