PageRenderTime 60ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://github.com/jcplat/console-seolan
PHP | 1595 lines | 1148 code | 216 blank | 231 comment | 452 complexity | a1bce0cf47a7fad635f4344bf04c71be MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, GPL-3.0, Apache-2.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * PHPExcel
  4. *
  5. * Copyright (c) 2006 - 2009 PHPExcel
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * @category PHPExcel
  22. * @package PHPExcel_Reader
  23. * @copyright Copyright (c) 2006 - 2009 PHPExcel (http://www.codeplex.com/PHPExcel)
  24. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  25. * @version 1.7.1, 2009-11-02
  26. */
  27. /** PHPExcel root directory */
  28. if (!defined('PHPEXCEL_ROOT')) {
  29. /**
  30. * @ignore
  31. */
  32. define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');
  33. }
  34. /** PHPExcel */
  35. require_once PHPEXCEL_ROOT . 'PHPExcel.php';
  36. /** PHPExcel_Reader_IReader */
  37. require_once PHPEXCEL_ROOT . 'PHPExcel/Reader/IReader.php';
  38. /** PHPExcel_Worksheet */
  39. require_once PHPEXCEL_ROOT . 'PHPExcel/Worksheet.php';
  40. /** PHPExcel_Cell */
  41. require_once PHPEXCEL_ROOT . 'PHPExcel/Cell.php';
  42. /** PHPExcel_Style */
  43. require_once PHPEXCEL_ROOT . 'PHPExcel/Style.php';
  44. /** PHPExcel_Style_Borders */
  45. require_once PHPEXCEL_ROOT . 'PHPExcel/Style/Borders.php';
  46. /** PHPExcel_Style_Conditional */
  47. require_once PHPEXCEL_ROOT . 'PHPExcel/Style/Conditional.php';
  48. /** PHPExcel_Style_Protection */
  49. require_once PHPEXCEL_ROOT . 'PHPExcel/Style/Protection.php';
  50. /** PHPExcel_Style_NumberFormat */
  51. require_once PHPEXCEL_ROOT . 'PHPExcel/Style/NumberFormat.php';
  52. /** PHPExcel_Worksheet_BaseDrawing */
  53. require_once PHPEXCEL_ROOT . 'PHPExcel/Worksheet/BaseDrawing.php';
  54. /** PHPExcel_Worksheet_Drawing */
  55. require_once PHPEXCEL_ROOT . 'PHPExcel/Worksheet/Drawing.php';
  56. /** PHPExcel_Shared_Drawing */
  57. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/Drawing.php';
  58. /** PHPExcel_Shared_Date */
  59. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/Date.php';
  60. /** PHPExcel_Shared_File */
  61. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/File.php';
  62. /** PHPExcel_Shared_String */
  63. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/String.php';
  64. /** PHPExcel_ReferenceHelper */
  65. require_once PHPEXCEL_ROOT . 'PHPExcel/ReferenceHelper.php';
  66. /** PHPExcel_Reader_IReadFilter */
  67. require_once PHPEXCEL_ROOT . 'PHPExcel/Reader/IReadFilter.php';
  68. /** PHPExcel_Reader_DefaultReadFilter */
  69. require_once PHPEXCEL_ROOT . 'PHPExcel/Reader/DefaultReadFilter.php';
  70. /**
  71. * PHPExcel_Reader_Excel2007
  72. *
  73. * @category PHPExcel
  74. * @package PHPExcel_Reader
  75. * @copyright Copyright (c) 2006 - 2009 PHPExcel (http://www.codeplex.com/PHPExcel)
  76. */
  77. class PHPExcel_Reader_Excel2007 implements PHPExcel_Reader_IReader
  78. {
  79. /**
  80. * Read data only?
  81. *
  82. * @var boolean
  83. */
  84. private $_readDataOnly = false;
  85. /**
  86. * Restict which sheets should be loaded?
  87. *
  88. * @var array
  89. */
  90. private $_loadSheetsOnly = null;
  91. /**
  92. * PHPExcel_Reader_IReadFilter instance
  93. *
  94. * @var PHPExcel_Reader_IReadFilter
  95. */
  96. private $_readFilter = null;
  97. /**
  98. * Read data only?
  99. *
  100. * @return boolean
  101. */
  102. public function getReadDataOnly() {
  103. return $this->_readDataOnly;
  104. }
  105. /**
  106. * Set read data only
  107. *
  108. * @param boolean $pValue
  109. * @return PHPExcel_Reader_Excel2007
  110. */
  111. public function setReadDataOnly($pValue = false) {
  112. $this->_readDataOnly = $pValue;
  113. return $this;
  114. }
  115. /**
  116. * Get which sheets to load
  117. *
  118. * @return mixed
  119. */
  120. public function getLoadSheetsOnly()
  121. {
  122. return $this->_loadSheetsOnly;
  123. }
  124. /**
  125. * Set which sheets to load
  126. *
  127. * @param mixed $value
  128. * @return PHPExcel_Reader_Excel2007
  129. */
  130. public function setLoadSheetsOnly($value = null)
  131. {
  132. $this->_loadSheetsOnly = is_array($value) ?
  133. $value : array($value);
  134. return $this;
  135. }
  136. /**
  137. * Set all sheets to load
  138. *
  139. * @return PHPExcel_Reader_Excel2007
  140. */
  141. public function setLoadAllSheets()
  142. {
  143. $this->_loadSheetsOnly = null;
  144. return $this;
  145. }
  146. /**
  147. * Read filter
  148. *
  149. * @return PHPExcel_Reader_IReadFilter
  150. */
  151. public function getReadFilter() {
  152. return $this->_readFilter;
  153. }
  154. /**
  155. * Set read filter
  156. *
  157. * @param PHPExcel_Reader_IReadFilter $pValue
  158. * @return PHPExcel_Reader_Excel2007
  159. */
  160. public function setReadFilter(PHPExcel_Reader_IReadFilter $pValue) {
  161. $this->_readFilter = $pValue;
  162. return $this;
  163. }
  164. /**
  165. * Create a new PHPExcel_Reader_Excel2007 instance
  166. */
  167. public function __construct() {
  168. $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter();
  169. }
  170. /**
  171. * Can the current PHPExcel_Reader_IReader read the file?
  172. *
  173. * @param string $pFileName
  174. * @return boolean
  175. */
  176. public function canRead($pFilename)
  177. {
  178. // Check if file exists
  179. if (!file_exists($pFilename)) {
  180. throw new Exception("Could not open " . $pFilename . " for reading! File does not exist.");
  181. }
  182. // Load file
  183. $zip = new ZipArchive;
  184. if ($zip->open($pFilename) === true) {
  185. // check if it is an OOXML archive
  186. $rels = simplexml_load_string($zip->getFromName("_rels/.rels"));
  187. $zip->close();
  188. return ($rels !== false);
  189. }
  190. return false;
  191. }
  192. private function _castToBool($c) {
  193. // echo 'Initial Cast to Boolean<br />';
  194. $value = isset($c->v) ? (string) $c->v : null;
  195. if ($value == '0') {
  196. $value = false;
  197. } elseif ($value == '1') {
  198. $value = true;
  199. } else {
  200. $value = (bool)$c->v;
  201. }
  202. return $value;
  203. } // function _castToBool()
  204. private function _castToError($c) {
  205. // echo 'Initial Cast to Error<br />';
  206. return isset($c->v) ? (string) $c->v : null;;
  207. } // function _castToError()
  208. private function _castToString($c) {
  209. // echo 'Initial Cast to String<br />';
  210. return isset($c->v) ? (string) $c->v : null;;
  211. } // function _castToString()
  212. private function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas,$castBaseType) {
  213. // echo '<font color="darkgreen">Formula</font><br />';
  214. // echo '$c->f is '.$c->f.'<br />';
  215. $cellDataType = 'f';
  216. $value = "={$c->f}";
  217. $calculatedValue = $this->$castBaseType($c);
  218. // Shared formula?
  219. if (isset($c->f['t']) && strtolower((string)$c->f['t']) == 'shared') {
  220. // echo '<font color="darkgreen">SHARED FORMULA</font><br />';
  221. $instance = (string)$c->f['si'];
  222. // echo 'Instance ID = '.$instance.'<br />';
  223. //
  224. // echo 'Shared Formula Array:<pre>';
  225. // print_r($sharedFormulas);
  226. // echo '</pre>';
  227. if (!isset($sharedFormulas[(string)$c->f['si']])) {
  228. // echo '<font color="darkgreen">SETTING NEW SHARED FORMULA</font><br />';
  229. // echo 'Master is '.$r.'<br />';
  230. // echo 'Formula is '.$value.'<br />';
  231. $sharedFormulas[$instance] = array( 'master' => $r,
  232. 'formula' => $value
  233. );
  234. // echo 'New Shared Formula Array:<pre>';
  235. // print_r($sharedFormulas);
  236. // echo '</pre>';
  237. } else {
  238. // echo '<font color="darkgreen">GETTING SHARED FORMULA</font><br />';
  239. // echo 'Master is '.$sharedFormulas[$instance]['master'].'<br />';
  240. // echo 'Formula is '.$sharedFormulas[$instance]['formula'].'<br />';
  241. $master = PHPExcel_Cell::coordinateFromString($sharedFormulas[$instance]['master']);
  242. $current = PHPExcel_Cell::coordinateFromString($r);
  243. $difference = array(0, 0);
  244. $difference[0] = PHPExcel_Cell::columnIndexFromString($current[0]) - PHPExcel_Cell::columnIndexFromString($master[0]);
  245. $difference[1] = $current[1] - $master[1];
  246. $helper = PHPExcel_ReferenceHelper::getInstance();
  247. $value = $helper->updateFormulaReferences( $sharedFormulas[$instance]['formula'],
  248. 'A1',
  249. $difference[0],
  250. $difference[1]
  251. );
  252. // echo 'Adjusted Formula is '.$value.'<br />';
  253. }
  254. }
  255. }
  256. /**
  257. * Loads PHPExcel from file
  258. *
  259. * @param string $pFilename
  260. * @throws Exception
  261. */
  262. public function load($pFilename)
  263. {
  264. // Check if file exists
  265. if (!file_exists($pFilename)) {
  266. throw new Exception("Could not open " . $pFilename . " for reading! File does not exist.");
  267. }
  268. // Initialisations
  269. $excel = new PHPExcel;
  270. $excel->removeSheetByIndex(0);
  271. if (!$this->_readDataOnly) {
  272. $excel->removeCellStyleXfByIndex(0); // remove the default style
  273. $excel->removeCellXfByIndex(0); // remove the default style
  274. }
  275. $zip = new ZipArchive;
  276. $zip->open($pFilename);
  277. $rels = simplexml_load_string($zip->getFromName("_rels/.rels")); //~ http://schemas.openxmlformats.org/package/2006/relationships");
  278. foreach ($rels->Relationship as $rel) {
  279. switch ($rel["Type"]) {
  280. case "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties":
  281. $xmlCore = simplexml_load_string($zip->getFromName("{$rel['Target']}"));
  282. if ($xmlCore === false) { // Apache POI hack
  283. $xmlCore = simplexml_load_string($zip->getFromName(substr("{$rel['Target']}", 1)));
  284. }
  285. if ($xmlCore) {
  286. $xmlCore->registerXPathNamespace("dc", "http://purl.org/dc/elements/1.1/");
  287. $xmlCore->registerXPathNamespace("dcterms", "http://purl.org/dc/terms/");
  288. $xmlCore->registerXPathNamespace("cp", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties");
  289. $docProps = $excel->getProperties();
  290. $docProps->setCreator((string) self::array_item($xmlCore->xpath("dc:creator")));
  291. $docProps->setLastModifiedBy((string) self::array_item($xmlCore->xpath("cp:lastModifiedBy")));
  292. $docProps->setCreated(strtotime(self::array_item($xmlCore->xpath("dcterms:created")))); //! respect xsi:type
  293. $docProps->setModified(strtotime(self::array_item($xmlCore->xpath("dcterms:modified")))); //! respect xsi:type
  294. $docProps->setTitle((string) self::array_item($xmlCore->xpath("dc:title")));
  295. $docProps->setDescription((string) self::array_item($xmlCore->xpath("dc:description")));
  296. $docProps->setSubject((string) self::array_item($xmlCore->xpath("dc:subject")));
  297. $docProps->setKeywords((string) self::array_item($xmlCore->xpath("cp:keywords")));
  298. $docProps->setCategory((string) self::array_item($xmlCore->xpath("cp:category")));
  299. }
  300. break;
  301. case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument":
  302. $dir = dirname($rel["Target"]);
  303. $relsWorkbook = simplexml_load_string($zip->getFromName("$dir/_rels/" . basename($rel["Target"]) . ".rels")); //~ http://schemas.openxmlformats.org/package/2006/relationships");
  304. if ($relsWorkbook === false) { // Apache POI hack
  305. $relsWorkbook = simplexml_load_string($zip->getFromName(substr("$dir/_rels/" . basename($rel["Target"]) . ".rels", 1))); //~ http://schemas.openxmlformats.org/package/2006/relationships");
  306. }
  307. $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships");
  308. $sharedStrings = array();
  309. $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings']"));
  310. $xmlStrings = simplexml_load_string($zip->getFromName("$dir/$xpath[Target]")); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main");
  311. if (isset($xmlStrings) && isset($xmlStrings->si)) {
  312. foreach ($xmlStrings->si as $val) {
  313. if (isset($val->t)) {
  314. $sharedStrings[] = PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $val->t );
  315. } elseif (isset($val->r)) {
  316. $sharedStrings[] = $this->_parseRichText($val);
  317. }
  318. }
  319. }
  320. $worksheets = array();
  321. foreach ($relsWorkbook->Relationship as $ele) {
  322. if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet") {
  323. $worksheets[(string) $ele["Id"]] = $ele["Target"];
  324. }
  325. }
  326. $styles = array();
  327. $cellStyles = array();
  328. $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']"));
  329. $xmlStyles = simplexml_load_string($zip->getFromName("$dir/$xpath[Target]")); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main");
  330. $numFmts = null;
  331. if ($xmlStyles && $xmlStyles->numFmts[0]) {
  332. $numFmts = $xmlStyles->numFmts[0];
  333. }
  334. if (isset($numFmts) && !is_null($numFmts)) {
  335. $numFmts->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
  336. }
  337. if (!$this->_readDataOnly && $xmlStyles) {
  338. foreach ($xmlStyles->cellXfs->xf as $xf) {
  339. $numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;
  340. if ($xf["numFmtId"]) {
  341. if (isset($numFmts)) {
  342. $tmpNumFmt = self::array_item($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]"));
  343. if (isset($tmpNumFmt["formatCode"])) {
  344. $numFmt = (string) $tmpNumFmt["formatCode"];
  345. }
  346. }
  347. if ((int)$xf["numFmtId"] < 164) {
  348. $numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]);
  349. }
  350. }
  351. //$numFmt = str_replace('mm', 'i', $numFmt);
  352. //$numFmt = str_replace('h', 'H', $numFmt);
  353. $style = (object) array(
  354. "numFmt" => $numFmt,
  355. "font" => $xmlStyles->fonts->font[intval($xf["fontId"])],
  356. "fill" => $xmlStyles->fills->fill[intval($xf["fillId"])],
  357. "border" => $xmlStyles->borders->border[intval($xf["borderId"])],
  358. "alignment" => $xf->alignment,
  359. "protection" => $xf->protection,
  360. "applyAlignment" => (isset($xf["applyAlignment"]) && ((string)$xf["applyAlignment"] == 'true' || (string)$xf["applyAlignment"] == '1')),
  361. "applyBorder" => (isset($xf["applyBorder"]) && ((string)$xf["applyBorder"] == 'true' || (string)$xf["applyBorder"] == '1')),
  362. "applyFill" => (isset($xf["applyFill"]) && ((string)$xf["applyFill"] == 'true' || (string)$xf["applyFill"] == '1')),
  363. "applyFont" => (isset($xf["applyFont"]) && ((string)$xf["applyFont"] == 'true' || (string)$xf["applyFont"] == '1')),
  364. "applyNumberFormat" => (isset($xf["applyNumberFormat"]) && ((string)$xf["applyNumberFormat"] == 'true' || (string)$xf["applyNumberFormat"] == '1')),
  365. "applyProtection" => (isset($xf["applyProtection"]) && ((string)$xf["applyProtection"] == 'true' || (string)$xf["applyProtection"] == '1'))
  366. );
  367. $styles[] = $style;
  368. // add style to cellXf collection
  369. $objStyle = new PHPExcel_Style;
  370. $this->_readStyle($objStyle, $style);
  371. $excel->addCellXf($objStyle);
  372. }
  373. foreach ($xmlStyles->cellStyleXfs->xf as $xf) {
  374. $numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;
  375. if ($numFmts && $xf["numFmtId"]) {
  376. $tmpNumFmt = self::array_item($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]"));
  377. if (isset($tmpNumFmt["formatCode"])) {
  378. $numFmt = (string) $tmpNumFmt["formatCode"];
  379. } else if ((int)$xf["numFmtId"] < 165) {
  380. $numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]);
  381. }
  382. }
  383. $cellStyle = (object) array(
  384. "numFmt" => $numFmt,
  385. "font" => $xmlStyles->fonts->font[intval($xf["fontId"])],
  386. "fill" => $xmlStyles->fills->fill[intval($xf["fillId"])],
  387. "border" => $xmlStyles->borders->border[intval($xf["borderId"])],
  388. "alignment" => $xf->alignment,
  389. "protection" => $xf->protection,
  390. "applyAlignment" => true,
  391. "applyBorder" => true,
  392. "applyFill" => true,
  393. "applyFont" => true,
  394. "applyNumberFormat" => true,
  395. "applyProtection" => true
  396. );
  397. $cellStyles[] = $cellStyle;
  398. // add style to cellStyleXf collection
  399. $objStyle = new PHPExcel_Style;
  400. $this->_readStyle($objStyle, $cellStyle);
  401. $excel->addCellStyleXf($objStyle);
  402. }
  403. }
  404. $dxfs = array();
  405. if (!$this->_readDataOnly && $xmlStyles) {
  406. foreach ($xmlStyles->dxfs->dxf as $dxf) {
  407. $style = new PHPExcel_Style;
  408. $this->_readStyle($style, $dxf);
  409. $dxfs[] = $style;
  410. }
  411. foreach ($xmlStyles->cellStyles->cellStyle as $cellStyle) {
  412. if (intval($cellStyle['builtinId']) == 0) {
  413. if (isset($cellStyles[intval($cellStyle['xfId'])])) {
  414. // Set default style
  415. $style = new PHPExcel_Style;
  416. $this->_readStyle($style, $cellStyles[intval($cellStyle['xfId'])]);
  417. // normal style, currently not using it for anything
  418. }
  419. }
  420. }
  421. }
  422. $xmlWorkbook = simplexml_load_string($zip->getFromName("{$rel['Target']}")); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main");
  423. if ($xmlWorkbook === false) { // Apache POI hack
  424. $xmlWorkbook = simplexml_load_string($zip->getFromName(substr("{$rel['Target']}", 1))); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main");
  425. }
  426. // Set base date
  427. if ($xmlWorkbook->workbookPr) {
  428. PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900);
  429. if (isset($xmlWorkbook->workbookPr['date1904'])) {
  430. $date1904 = (string)$xmlWorkbook->workbookPr['date1904'];
  431. if ($date1904 == "true" || $date1904 == "1") {
  432. PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904);
  433. }
  434. }
  435. }
  436. $sheetId = 0; // keep track of new sheet id in final workbook
  437. $oldSheetId = -1; // keep track of old sheet id in final workbook
  438. $countSkippedSheets = 0; // keep track of number of skipped sheets
  439. $mapSheetId = array(); // mapping of sheet ids from old to new
  440. foreach ($xmlWorkbook->sheets->sheet as $eleSheet) {
  441. ++$oldSheetId;
  442. // Check if sheet should be skipped
  443. if (isset($this->_loadSheetsOnly) && !in_array((string) $eleSheet["name"], $this->_loadSheetsOnly)) {
  444. ++$countSkippedSheets;
  445. $mapSheetId[$oldSheetId] = null;
  446. continue;
  447. }
  448. // Map old sheet id in original workbook to new sheet id.
  449. // They will differ if loadSheetsOnly() is being used
  450. $mapSheetId[$oldSheetId] = $oldSheetId - $countSkippedSheets;
  451. // Load sheet
  452. $docSheet = $excel->createSheet();
  453. $docSheet->setTitle((string) $eleSheet["name"]);
  454. $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")];
  455. $xmlSheet = simplexml_load_string($zip->getFromName("$dir/$fileWorksheet")); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main");
  456. $sharedFormulas = array();
  457. if (isset($eleSheet["state"]) && (string) $eleSheet["state"] != '') {
  458. $docSheet->setSheetState( (string) $eleSheet["state"] );
  459. }
  460. if (isset($xmlSheet->sheetViews) && isset($xmlSheet->sheetViews->sheetView)) {
  461. if (isset($xmlSheet->sheetViews->sheetView['zoomScale'])) {
  462. $docSheet->getSheetView()->setZoomScale( intval($xmlSheet->sheetViews->sheetView['zoomScale']) );
  463. }
  464. if (isset($xmlSheet->sheetViews->sheetView['zoomScaleNormal'])) {
  465. $docSheet->getSheetView()->setZoomScaleNormal( intval($xmlSheet->sheetViews->sheetView['zoomScaleNormal']) );
  466. }
  467. if (isset($xmlSheet->sheetViews->sheetView['showGridLines'])) {
  468. $docSheet->setShowGridLines((string)$xmlSheet->sheetViews->sheetView['showGridLines'] ? true : false);
  469. }
  470. if (isset($xmlSheet->sheetViews->sheetView['rightToLeft'])) {
  471. $docSheet->setRightToLeft((string)$xmlSheet->sheetViews->sheetView['rightToLeft'] ? true : false);
  472. }
  473. if (isset($xmlSheet->sheetViews->sheetView->pane)) {
  474. if (isset($xmlSheet->sheetViews->sheetView->pane['topLeftCell'])) {
  475. $docSheet->freezePane( (string)$xmlSheet->sheetViews->sheetView->pane['topLeftCell'] );
  476. } else {
  477. $xSplit = 0;
  478. $ySplit = 0;
  479. if (isset($xmlSheet->sheetViews->sheetView->pane['xSplit'])) {
  480. $xSplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['xSplit']);
  481. }
  482. if (isset($xmlSheet->sheetViews->sheetView->pane['ySplit'])) {
  483. $ySplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['ySplit']);
  484. }
  485. $docSheet->freezePaneByColumnAndRow($xSplit, $ySplit);
  486. }
  487. }
  488. }
  489. if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->tabColor)) {
  490. if (isset($xmlSheet->sheetPr->tabColor['rgb'])) {
  491. $docSheet->getTabColor()->setARGB( (string)$xmlSheet->sheetPr->tabColor['rgb'] );
  492. }
  493. }
  494. if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->outlinePr)) {
  495. if (isset($xmlSheet->sheetPr->outlinePr['summaryRight']) && $xmlSheet->sheetPr->outlinePr['summaryRight'] == false) {
  496. $docSheet->setShowSummaryRight(false);
  497. } else {
  498. $docSheet->setShowSummaryRight(true);
  499. }
  500. if (isset($xmlSheet->sheetPr->outlinePr['summaryBelow']) && $xmlSheet->sheetPr->outlinePr['summaryBelow'] == false) {
  501. $docSheet->setShowSummaryBelow(false);
  502. } else {
  503. $docSheet->setShowSummaryBelow(true);
  504. }
  505. }
  506. if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->pageSetUpPr)) {
  507. if (isset($xmlSheet->sheetPr->pageSetUpPr['fitToPage']) && $xmlSheet->sheetPr->pageSetUpPr['fitToPage'] == false) {
  508. $docSheet->getPageSetup()->setFitToPage(false);
  509. } else {
  510. $docSheet->getPageSetup()->setFitToPage(true);
  511. }
  512. }
  513. if (isset($xmlSheet->sheetFormatPr)) {
  514. if (isset($xmlSheet->sheetFormatPr['customHeight']) && ((string)$xmlSheet->sheetFormatPr['customHeight'] == '1' || strtolower((string)$xmlSheet->sheetFormatPr['customHeight']) == 'true') && isset($xmlSheet->sheetFormatPr['defaultRowHeight'])) {
  515. $docSheet->getDefaultRowDimension()->setRowHeight( (float)$xmlSheet->sheetFormatPr['defaultRowHeight'] );
  516. }
  517. if (isset($xmlSheet->sheetFormatPr['defaultColWidth'])) {
  518. $docSheet->getDefaultColumnDimension()->setWidth( (float)$xmlSheet->sheetFormatPr['defaultColWidth'] );
  519. }
  520. }
  521. if (isset($xmlSheet->cols) && !$this->_readDataOnly) {
  522. foreach ($xmlSheet->cols->col as $col) {
  523. for ($i = intval($col["min"]) - 1; $i < intval($col["max"]); ++$i) {
  524. if ($col["style"]) {
  525. $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setXfIndex(intval($col["style"]));
  526. }
  527. if ($col["bestFit"]) {
  528. $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setAutoSize(true);
  529. }
  530. if ($col["hidden"]) {
  531. $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setVisible(false);
  532. }
  533. if ($col["collapsed"]) {
  534. $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setCollapsed(true);
  535. }
  536. if ($col["outlineLevel"] > 0) {
  537. $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setOutlineLevel(intval($col["outlineLevel"]));
  538. }
  539. $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setWidth(floatval($col["width"]));
  540. if (intval($col["max"]) == 16384) {
  541. break;
  542. }
  543. }
  544. }
  545. }
  546. if (isset($xmlSheet->printOptions) && !$this->_readDataOnly) {
  547. if ($xmlSheet->printOptions['gridLinesSet'] == 'true' && $xmlSheet->printOptions['gridLinesSet'] == '1') {
  548. $docSheet->setShowGridlines(true);
  549. }
  550. if ($xmlSheet->printOptions['gridLines'] == 'true' || $xmlSheet->printOptions['gridLines'] == '1') {
  551. $docSheet->setPrintGridlines(true);
  552. }
  553. if ($xmlSheet->printOptions['horizontalCentered']) {
  554. $docSheet->getPageSetup()->setHorizontalCentered(true);
  555. }
  556. if ($xmlSheet->printOptions['verticalCentered']) {
  557. $docSheet->getPageSetup()->setVerticalCentered(true);
  558. }
  559. }
  560. if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) {
  561. foreach ($xmlSheet->sheetData->row as $row) {
  562. if ($row["ht"] && !$this->_readDataOnly) {
  563. $docSheet->getRowDimension(intval($row["r"]))->setRowHeight(floatval($row["ht"]));
  564. }
  565. if ($row["hidden"] && !$this->_readDataOnly) {
  566. $docSheet->getRowDimension(intval($row["r"]))->setVisible(false);
  567. }
  568. if ($row["collapsed"]) {
  569. $docSheet->getRowDimension(intval($row["r"]))->setCollapsed(true);
  570. }
  571. if ($row["outlineLevel"] > 0) {
  572. $docSheet->getRowDimension(intval($row["r"]))->setOutlineLevel(intval($row["outlineLevel"]));
  573. }
  574. if ($row["s"]) {
  575. $docSheet->getRowDimension(intval($row["r"]))->setXfIndex(intval($row["s"]));
  576. }
  577. foreach ($row->c as $c) {
  578. $r = (string) $c["r"];
  579. $cellDataType = (string) $c["t"];
  580. $value = null;
  581. $calculatedValue = null;
  582. // Read cell?
  583. if (!is_null($this->getReadFilter())) {
  584. $coordinates = PHPExcel_Cell::coordinateFromString($r);
  585. if (!$this->getReadFilter()->readCell($coordinates[0], $coordinates[1], $docSheet->getTitle())) {
  586. continue;
  587. }
  588. }
  589. // echo '<b>Reading cell '.$coordinates[0].$coordinates[1].'</b><br />';
  590. // print_r($c);
  591. // echo '<br />';
  592. // echo 'Cell Data Type is '.$cellDataType.': ';
  593. //
  594. // Read cell!
  595. switch ($cellDataType) {
  596. case "s":
  597. // echo 'String<br />';
  598. if ((string)$c->v != '') {
  599. $value = $sharedStrings[intval($c->v)];
  600. if ($value instanceof PHPExcel_RichText) {
  601. $value = clone $value;
  602. }
  603. } else {
  604. $value = '';
  605. }
  606. break;
  607. case "b":
  608. // echo 'Boolean<br />';
  609. if (!isset($c->f)) {
  610. $value = $this->_castToBool($c);
  611. } else {
  612. // Formula
  613. $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToBool');
  614. // echo '$calculatedValue = '.$calculatedValue.'<br />';
  615. }
  616. break;
  617. case "inlineStr":
  618. // echo 'Inline String<br />';
  619. $value = $this->_parseRichText($c->is);
  620. break;
  621. case "e":
  622. // echo 'Error<br />';
  623. if (!isset($c->f)) {
  624. $value = $this->_castToError($c);
  625. } else {
  626. // Formula
  627. $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToError');
  628. // echo '$calculatedValue = '.$calculatedValue.'<br />';
  629. }
  630. break;
  631. default:
  632. // echo 'Default<br />';
  633. if (!isset($c->f)) {
  634. // echo 'Not a Formula<br />';
  635. $value = $this->_castToString($c);
  636. } else {
  637. // echo 'Treat as Formula<br />';
  638. // Formula
  639. $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToString');
  640. // echo '$calculatedValue = '.$calculatedValue.'<br />';
  641. }
  642. break;
  643. }
  644. // echo 'Value is '.$value.'<br />';
  645. // Check for numeric values
  646. if (is_numeric($value) && $cellDataType != 's') {
  647. if ($value == (int)$value) $value = (int)$value;
  648. elseif ($value == (float)$value) $value = (float)$value;
  649. elseif ($value == (double)$value) $value = (double)$value;
  650. }
  651. // Rich text?
  652. if ($value instanceof PHPExcel_RichText && $this->_readDataOnly) {
  653. $value = $value->getPlainText();
  654. }
  655. // Assign value
  656. if ($cellDataType != '') {
  657. $docSheet->setCellValueExplicit($r, $value, $cellDataType);
  658. } else {
  659. $docSheet->setCellValue($r, $value);
  660. }
  661. if (!is_null($calculatedValue)) {
  662. $docSheet->getCell($r)->setCalculatedValue($calculatedValue);
  663. }
  664. // Style information?
  665. if ($c["s"] && !$this->_readDataOnly) {
  666. // no style index means 0, it seems
  667. $docSheet->getCell($r)->setXfIndex(isset($styles[intval($c["s"])]) ?
  668. intval($c["s"]) : 0);
  669. }
  670. // Set rich text parent
  671. if ($value instanceof PHPExcel_RichText && !$this->_readDataOnly) {
  672. $value->setParent($docSheet->getCell($r));
  673. }
  674. }
  675. }
  676. }
  677. $conditionals = array();
  678. if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->conditionalFormatting) {
  679. foreach ($xmlSheet->conditionalFormatting as $conditional) {
  680. foreach ($conditional->cfRule as $cfRule) {
  681. if (
  682. (
  683. (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_NONE ||
  684. (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CELLIS ||
  685. (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT
  686. ) && isset($dxfs[intval($cfRule["dxfId"])])
  687. ) {
  688. $conditionals[(string) $conditional["sqref"]][intval($cfRule["priority"])] = $cfRule;
  689. }
  690. }
  691. }
  692. foreach ($conditionals as $ref => $cfRules) {
  693. ksort($cfRules);
  694. $conditionalStyles = array();
  695. foreach ($cfRules as $cfRule) {
  696. $objConditional = new PHPExcel_Style_Conditional();
  697. $objConditional->setConditionType((string)$cfRule["type"]);
  698. $objConditional->setOperatorType((string)$cfRule["operator"]);
  699. if ((string)$cfRule["text"] != '') {
  700. $objConditional->setText((string)$cfRule["text"]);
  701. }
  702. if (count($cfRule->formula) > 1) {
  703. foreach ($cfRule->formula as $formula) {
  704. $objConditional->addCondition((string)$formula);
  705. }
  706. } else {
  707. $objConditional->addCondition((string)$cfRule->formula);
  708. }
  709. $objConditional->setStyle(clone $dxfs[intval($cfRule["dxfId"])]);
  710. $conditionalStyles[] = $objConditional;
  711. }
  712. // Extract all cell references in $ref
  713. $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($ref);
  714. foreach ($aReferences as $reference) {
  715. $docSheet->getStyle($reference)->setConditionalStyles($conditionalStyles);
  716. }
  717. }
  718. }
  719. $aKeys = array("sheet", "objects", "scenarios", "formatCells", "formatColumns", "formatRows", "insertColumns", "insertRows", "insertHyperlinks", "deleteColumns", "deleteRows", "selectLockedCells", "sort", "autoFilter", "pivotTables", "selectUnlockedCells");
  720. if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) {
  721. foreach ($aKeys as $key) {
  722. $method = "set" . ucfirst($key);
  723. $docSheet->getProtection()->$method($xmlSheet->sheetProtection[$key] == "true");
  724. }
  725. }
  726. if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) {
  727. $docSheet->getProtection()->setPassword((string) $xmlSheet->sheetProtection["password"], true);
  728. if ($xmlSheet->protectedRanges->protectedRange) {
  729. foreach ($xmlSheet->protectedRanges->protectedRange as $protectedRange) {
  730. $docSheet->protectCells((string) $protectedRange["sqref"], (string) $protectedRange["password"], true);
  731. }
  732. }
  733. }
  734. if ($xmlSheet && $xmlSheet->autoFilter && !$this->_readDataOnly) {
  735. $docSheet->setAutoFilter((string) $xmlSheet->autoFilter["ref"]);
  736. }
  737. if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->_readDataOnly) {
  738. foreach ($xmlSheet->mergeCells->mergeCell as $mergeCell) {
  739. $docSheet->mergeCells((string) $mergeCell["ref"]);
  740. }
  741. }
  742. if ($xmlSheet && $xmlSheet->pageMargins && !$this->_readDataOnly) {
  743. $docPageMargins = $docSheet->getPageMargins();
  744. $docPageMargins->setLeft(floatval($xmlSheet->pageMargins["left"]));
  745. $docPageMargins->setRight(floatval($xmlSheet->pageMargins["right"]));
  746. $docPageMargins->setTop(floatval($xmlSheet->pageMargins["top"]));
  747. $docPageMargins->setBottom(floatval($xmlSheet->pageMargins["bottom"]));
  748. $docPageMargins->setHeader(floatval($xmlSheet->pageMargins["header"]));
  749. $docPageMargins->setFooter(floatval($xmlSheet->pageMargins["footer"]));
  750. }
  751. if ($xmlSheet && $xmlSheet->pageSetup && !$this->_readDataOnly) {
  752. $docPageSetup = $docSheet->getPageSetup();
  753. if (isset($xmlSheet->pageSetup["orientation"])) {
  754. $docPageSetup->setOrientation((string) $xmlSheet->pageSetup["orientation"]);
  755. }
  756. if (isset($xmlSheet->pageSetup["paperSize"])) {
  757. $docPageSetup->setPaperSize(intval($xmlSheet->pageSetup["paperSize"]));
  758. }
  759. if (isset($xmlSheet->pageSetup["scale"])) {
  760. $docPageSetup->setScale(intval($xmlSheet->pageSetup["scale"]), false);
  761. }
  762. if (isset($xmlSheet->pageSetup["fitToHeight"]) && intval($xmlSheet->pageSetup["fitToHeight"]) >= 0) {
  763. $docPageSetup->setFitToHeight(intval($xmlSheet->pageSetup["fitToHeight"]), false);
  764. }
  765. if (isset($xmlSheet->pageSetup["fitToWidth"]) && intval($xmlSheet->pageSetup["fitToWidth"]) >= 0) {
  766. $docPageSetup->setFitToWidth(intval($xmlSheet->pageSetup["fitToWidth"]), false);
  767. }
  768. if (isset($xmlSheet->pageSetup["firstPageNumber"]) && isset($xmlSheet->pageSetup["useFirstPageNumber"]) &&
  769. ((string)$xmlSheet->pageSetup["useFirstPageNumber"] == 'true' || (string)$xmlSheet->pageSetup["useFirstPageNumber"] == '1')) {
  770. $docPageSetup->setFirstPageNumber(intval($xmlSheet->pageSetup["firstPageNumber"]));
  771. }
  772. }
  773. if ($xmlSheet && $xmlSheet->headerFooter && !$this->_readDataOnly) {
  774. $docHeaderFooter = $docSheet->getHeaderFooter();
  775. if (isset($xmlSheet->headerFooter["differentOddEven"]) &&
  776. ((string)$xmlSheet->headerFooter["differentOddEven"] == 'true' || (string)$xmlSheet->headerFooter["differentOddEven"] == '1')) {
  777. $docHeaderFooter->setDifferentOddEven(true);
  778. } else {
  779. $docHeaderFooter->setDifferentOddEven(false);
  780. }
  781. if (isset($xmlSheet->headerFooter["differentFirst"]) &&
  782. ((string)$xmlSheet->headerFooter["differentFirst"] == 'true' || (string)$xmlSheet->headerFooter["differentFirst"] == '1')) {
  783. $docHeaderFooter->setDifferentFirst(true);
  784. } else {
  785. $docHeaderFooter->setDifferentFirst(false);
  786. }
  787. if (isset($xmlSheet->headerFooter["scaleWithDoc"]) &&
  788. ((string)$xmlSheet->headerFooter["scaleWithDoc"] == 'false' || (string)$xmlSheet->headerFooter["scaleWithDoc"] == '0')) {
  789. $docHeaderFooter->setScaleWithDocument(false);
  790. } else {
  791. $docHeaderFooter->setScaleWithDocument(true);
  792. }
  793. if (isset($xmlSheet->headerFooter["alignWithMargins"]) &&
  794. ((string)$xmlSheet->headerFooter["alignWithMargins"] == 'false' || (string)$xmlSheet->headerFooter["alignWithMargins"] == '0')) {
  795. $docHeaderFooter->setAlignWithMargins(false);
  796. } else {
  797. $docHeaderFooter->setAlignWithMargins(true);
  798. }
  799. $docHeaderFooter->setOddHeader((string) $xmlSheet->headerFooter->oddHeader);
  800. $docHeaderFooter->setOddFooter((string) $xmlSheet->headerFooter->oddFooter);
  801. $docHeaderFooter->setEvenHeader((string) $xmlSheet->headerFooter->evenHeader);
  802. $docHeaderFooter->setEvenFooter((string) $xmlSheet->headerFooter->evenFooter);
  803. $docHeaderFooter->setFirstHeader((string) $xmlSheet->headerFooter->firstHeader);
  804. $docHeaderFooter->setFirstFooter((string) $xmlSheet->headerFooter->firstFooter);
  805. }
  806. if ($xmlSheet && $xmlSheet->rowBreaks && $xmlSheet->rowBreaks->brk && !$this->_readDataOnly) {
  807. foreach ($xmlSheet->rowBreaks->brk as $brk) {
  808. if ($brk["man"]) {
  809. $docSheet->setBreak("A$brk[id]", PHPExcel_Worksheet::BREAK_ROW);
  810. }
  811. }
  812. }
  813. if ($xmlSheet && $xmlSheet->colBreaks && $xmlSheet->colBreaks->brk && !$this->_readDataOnly) {
  814. foreach ($xmlSheet->colBreaks->brk as $brk) {
  815. if ($brk["man"]) {
  816. $docSheet->setBreak(PHPExcel_Cell::stringFromColumnIndex($brk["id"]) . "1", PHPExcel_Worksheet::BREAK_COLUMN);
  817. }
  818. }
  819. }
  820. if ($xmlSheet && $xmlSheet->dataValidations && !$this->_readDataOnly) {
  821. foreach ($xmlSheet->dataValidations->dataValidation as $dataValidation) {
  822. // Uppercase coordinate
  823. $range = strtoupper($dataValidation["sqref"]);
  824. // Extract all cell references in $range
  825. $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($range);
  826. foreach ($aReferences as $reference) {
  827. // Create validation
  828. $docValidation = $docSheet->getCell($reference)->getDataValidation();
  829. $docValidation->setType((string) $dataValidation["type"]);
  830. $docValidation->setErrorStyle((string) $dataValidation["errorStyle"]);
  831. $docValidation->setOperator((string) $dataValidation["operator"]);
  832. $docValidation->setAllowBlank($dataValidation["allowBlank"] != 0);
  833. $docValidation->setShowDropDown($dataValidation["showDropDown"] == 0);
  834. $docValidation->setShowInputMessage($dataValidation["showInputMessage"] != 0);
  835. $docValidation->setShowErrorMessage($dataValidation["showErrorMessage"] != 0);
  836. $docValidation->setErrorTitle((string) $dataValidation["errorTitle"]);
  837. $docValidation->setError((string) $dataValidation["error"]);
  838. $docValidation->setPromptTitle((string) $dataValidation["promptTitle"]);
  839. $docValidation->setPrompt((string) $dataValidation["prompt"]);
  840. $docValidation->setFormula1((string) $dataValidation->formula1);
  841. $docValidation->setFormula2((string) $dataValidation->formula2);
  842. }
  843. }
  844. }
  845. // Add hyperlinks
  846. $hyperlinks = array();
  847. if (!$this->_readDataOnly) {
  848. // Locate hyperlink relations
  849. if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) {
  850. $relsWorksheet = simplexml_load_string($zip->getFromName( dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships");
  851. foreach ($relsWorksheet->Relationship as $ele) {
  852. if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink") {
  853. $hyperlinks[(string)$ele["Id"]] = (string)$ele["Target"];
  854. }
  855. }
  856. }
  857. // Loop through hyperlinks
  858. if ($xmlSheet && $xmlSheet->hyperlinks) {
  859. foreach ($xmlSheet->hyperlinks->hyperlink as $hyperlink) {
  860. // Link url
  861. $linkRel = $hyperlink->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships');
  862. foreach (PHPExcel_Cell::extractAllCellReferencesInRange($hyperlink['ref']) as $cellReference) {
  863. if (isset($linkRel['id'])) {
  864. $docSheet->getCell( $cellReference )->getHyperlink()->setUrl( $hyperlinks[ (string)$linkRel['id'] ] );
  865. }
  866. if (isset($hyperlink['location'])) {
  867. $docSheet->getCell( $cellReference )->getHyperlink()->setUrl( 'sheet://' . (string)$hyperlink['location'] );
  868. }
  869. // Tooltip
  870. if (isset($hyperlink['tooltip'])) {
  871. $docSheet->getCell( $cellReference )->getHyperlink()->setTooltip( (string)$hyperlink['tooltip'] );
  872. }
  873. }
  874. }
  875. }
  876. }
  877. // Add comments
  878. $comments = array();
  879. $vmlComments = array();
  880. if (!$this->_readDataOnly) {
  881. // Locate comment relations
  882. if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) {
  883. $relsWorksheet = simplexml_load_string($zip->getFromName( dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships");
  884. foreach ($relsWorksheet->Relationship as $ele) {
  885. if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments") {
  886. $comments[(string)$ele["Id"]] = (string)$ele["Target"];
  887. }
  888. if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing") {
  889. $vmlComments[(string)$ele["Id"]] = (string)$ele["Target"];
  890. }
  891. }
  892. }
  893. // Loop through comments
  894. foreach ($comments as $relName => $relPath) {
  895. // Load comments file
  896. $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath);
  897. $commentsFile = simplexml_load_string($zip->getFromName($relPath) );
  898. // Utility variables
  899. $authors = array();
  900. // Loop through authors
  901. foreach ($commentsFile->authors->author as $author) {
  902. $authors[] = (string)$author;
  903. }
  904. // Loop through contents
  905. foreach ($commentsFile->commentList->comment as $comment) {
  906. $docSheet->getComment( (string)$comment['ref'] )->setAuthor( $authors[(string)$comment['authorId']] );
  907. $docSheet->getComment( (string)$comment['ref'] )->setText( $this->_parseRichText($comment->text) );
  908. }
  909. }
  910. // Loop through VML comments
  911. foreach ($vmlComments as $relName => $relPath) {
  912. // Load VML comments file
  913. $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath);
  914. $vmlCommentsFile = simplexml_load_string( $zip->getFromName($relPath) );
  915. $vmlCommentsFile->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');
  916. $shapes = $vmlCommentsFile->xpath('//v:shape');
  917. foreach ($shapes as $shape) {
  918. $shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');
  919. if (isset($shape['style'])) {
  920. $style = (string)$shape['style'];
  921. $fillColor = strtoupper( substr( (string)$shape['fillcolor'], 1 ) );
  922. $column = null;
  923. $row = null;
  924. $clientData = $shape->xpath('.//x:ClientData');
  925. if (is_array($clientData)) {
  926. $clientData = $clientData[0];
  927. if ( isset($clientData['ObjectType']) && (string)$clientData['ObjectType'] == 'Note' ) {
  928. $temp = $clientData->xpath('.//x:Row');
  929. if (is_array($temp)) $row = $temp[0];
  930. $temp = $clientData->xpath('.//x:Column');
  931. if (is_array($temp)) $column = $temp[0];
  932. }
  933. }
  934. if (!is_null($column) && !is_null($row)) {
  935. // Set comment properties
  936. $comment = $docSheet->getCommentByColumnAndRow($column, $row + 1);
  937. $comment->getFillColor()->setRGB( $fillColor );
  938. // Parse style
  939. $styleArray = explode(';', str_replace(' ', '', $style));
  940. foreach ($styleArray as $stylePair) {
  941. $stylePair = explode(':', $stylePair);
  942. if ($stylePair[0] == 'margin-left') $comment->setMarginLeft($stylePair[1]);
  943. if ($stylePair[0] == 'margin-top') $comment->setMarginTop($stylePair[1]);
  944. if ($stylePair[0] == 'width') $comment->setWidth($stylePair[1]);
  945. if ($stylePair[0] == 'height') $comment->setHeight($stylePair[1]);
  946. if ($stylePair[0] == 'visibility') $comment->setVisible( $stylePair[1] == 'visible' );
  947. }
  948. }
  949. }
  950. }
  951. }
  952. // Header/footer images
  953. if ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->_readDataOnly) {
  954. if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) {
  955. $relsWorksheet = simplexml_load_string($zip->getFromName( dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships");
  956. $vmlRelationship = '';
  957. foreach ($relsWorksheet->Relationship as $ele) {
  958. if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing") {
  959. $vmlRelationship = self::dir_add("$dir/$fileWorksheet", $ele["Target"]);
  960. }
  961. }
  962. if ($vmlRelationship != '') {
  963. // Fetch linked images
  964. $relsVML = simplexml_load_string($zip->getFromName( dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels' )); //~ http://schemas.openxmlformats.org/package/2006/relationships");
  965. $drawings = array();
  966. foreach ($relsVML->Relationship as $ele) {
  967. if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") {
  968. $drawings[(string) $ele["Id"]] = self::dir_add($vmlRelationship, $ele["Target"]);
  969. }
  970. }
  971. // Fetch VML document
  972. $vmlDrawing = simplexml_load_string($zip->getFromName($vmlRelationship));
  973. $vmlDrawing->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');
  974. $hfImages = array();
  975. $shapes = $vmlDrawing->xpath('//v:shape');
  976. foreach ($shapes as $shape) {
  977. $shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');
  978. $imageData = $shape->xpath('//v:imagedata');
  979. $imageData = $imageData[0];
  980. $imageData = $imageData->attributes('urn:schemas-microsoft-com:office:office');
  981. $style = self::toCSSArray( (string)$shape['style'] );
  982. $hfImages[ (string)$shape['id'] ] = new PHPExcel_Worksheet_HeaderFooterDrawing();
  983. if (isset($imageData['title'])) {
  984. $hfImages[ (string)$shape['id'] ]->setName( (string)$imageData['title'] );
  985. }
  986. $hfImages[ (string)$shape['id'] ]->setPath("zip://$pFilename#" . $drawings[(string)$imageData['relid']], false);
  987. $hfImages[ (string)$shape['id'] ]->setResizeProportional(false);
  988. $hfImages[ (string)$shape['id'] ]->setWidth($style['width']);
  989. $hfImages[ (string)$shape['id'] ]->setHeight($style['height']);
  990. $hfImages[ (string)$shape['id'] ]->setOffsetX($style['margin-left']);
  991. $hfImages[ (string)$shape['id'] ]->setOffsetY($style['margin-top']);
  992. $hfImages[ (string)$shape['id'] ]->setResizeProportional(true);
  993. }
  994. $docSheet->getHeaderFooter()->setImages($hfImages);
  995. }
  996. }
  997. }
  998. }
  999. // TODO: Make sure drawings and graph are loaded differently!
  1000. if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) {
  1001. $relsWorksheet = simplexml_load_string($zip->getFromName( dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships");
  1002. $drawings = array();
  1003. foreach ($relsWorksheet->Relationship as $ele) {
  1004. if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing") {
  1005. $drawings[(string) $ele["Id"]] = self::dir_add("$dir/$fileWorksheet", $ele["Target"]);
  1006. }
  1007. }
  1008. if ($xmlSheet->drawing && !$this->_readDataOnly) {
  1009. foreach ($xmlSheet->drawing as $drawing) {
  1010. $fileDrawing = $drawings[(string) self::array_item($drawing->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")];
  1011. $relsDrawing = simplexml_load_string($zip->getFromName( dirname($fileDrawing) . "/_rels/" . basename($fileDrawing) . ".rels") ); //~ http://schemas.openxmlformats.org/package/2006/relationships");
  1012. $images = array();
  1013. if ($relsDrawing && $relsDrawing->Relationship) {
  1014. foreach ($relsDrawing->Relationship as $ele) {
  1015. if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") {
  1016. $images[(string) $ele["Id"]] = self::dir_add($fileDrawing, $ele["Target"]);
  1017. }
  1018. }
  1019. }
  1020. $xmlDrawing = simplexml_load_string($zip->getFromName($fileDrawing))->children("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing");
  1021. if ($xmlDrawing->oneCellAnchor) {
  1022. foreach ($xmlDrawing->oneCellAnchor as $oneCellAnchor) {
  1023. if ($oneCellAnchor->pic->blipFill) {
  1024. $blip = $oneCellAnchor->pic->blipFill->children("http://schemas.openxmlformats.org/drawingml/2006/main")->blip;
  1025. $xfrm = $oneCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->xfrm;
  1026. $outerShdw = $oneCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->effectLst->outerShdw;
  1027. $objDrawing = new PHPExcel_Worksheet_Drawing;
  1028. $objDrawing->setName((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "name"));
  1029. $objDrawing->setDescription((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "descr"));
  1030. $objDrawing->setPath("zip://$pFilename#" . $images[(string) self::array_item($blip->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "embed")], false);
  1031. $objDrawing->setCoordinates(PHPExcel_Cell::stringFromColumnIndex($oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1));
  1032. $objDrawing->setOffsetX(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff));
  1033. $objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from

Large files files are truncated, but you can click here to view the full file