Gnumeric.php 30 KB

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