PageRenderTime 97ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/common/libraries/plugin/phpexcel/PHPExcel/Reader/SYLK.php

https://bitbucket.org/renaatdemuynck/chamilo
PHP | 493 lines | 307 code | 38 blank | 148 comment | 45 complexity | 0fb4efcf321f087906e499f1e58a4aff MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, LGPL-3.0, GPL-3.0, MIT, GPL-2.0
  1. <?php
  2. /**
  3. * PHPExcel
  4. *
  5. * Copyright (c) 2006 - 2011 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 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
  24. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  25. * @version 1.7.6, 2011-02-27
  26. */
  27. /** PHPExcel root directory */
  28. if (! defined('PHPEXCEL_ROOT'))
  29. {
  30. /**
  31. * @ignore
  32. */
  33. define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');
  34. require (PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
  35. }
  36. /**
  37. * PHPExcel_Reader_SYLK
  38. *
  39. * @category PHPExcel
  40. * @package PHPExcel_Reader
  41. * @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
  42. */
  43. class PHPExcel_Reader_SYLK implements PHPExcel_Reader_IReader
  44. {
  45. /**
  46. * Input encoding
  47. *
  48. * @var string
  49. */
  50. private $_inputEncoding = 'ANSI';
  51. /**
  52. * Sheet index to read
  53. *
  54. * @var int
  55. */
  56. private $_sheetIndex = 0;
  57. /**
  58. * Formats
  59. *
  60. * @var array
  61. */
  62. private $_formats = array();
  63. /**
  64. * Format Count
  65. *
  66. * @var int
  67. */
  68. private $_format = 0;
  69. /**
  70. * PHPExcel_Reader_IReadFilter instance
  71. *
  72. * @var PHPExcel_Reader_IReadFilter
  73. */
  74. private $_readFilter = null;
  75. /**
  76. * Create a new PHPExcel_Reader_SYLK
  77. */
  78. public function __construct()
  79. {
  80. $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter();
  81. }
  82. /**
  83. * Can the current PHPExcel_Reader_IReader read the file?
  84. *
  85. * @param string $pFileName
  86. * @return boolean
  87. */
  88. public function canRead($pFilename)
  89. {
  90. // Check if file exists
  91. if (! file_exists($pFilename))
  92. {
  93. throw new Exception("Could not open " . $pFilename . " for reading! File does not exist.");
  94. }
  95. // Read sample data (first 2 KB will do)
  96. $fh = fopen($pFilename, 'r');
  97. $data = fread($fh, 2048);
  98. fclose($fh);
  99. // Count delimiters in file
  100. $delimiterCount = substr_count($data, ';');
  101. if ($delimiterCount < 1)
  102. {
  103. return false;
  104. }
  105. // Analyze first line looking for ID; signature
  106. $lines = explode("\n", $data);
  107. if (substr($lines[0], 0, 4) != 'ID;P')
  108. {
  109. return false;
  110. }
  111. return true;
  112. }
  113. /**
  114. * Loads PHPExcel from file
  115. *
  116. * @param string $pFilename
  117. * @return PHPExcel
  118. * @throws Exception
  119. */
  120. public function load($pFilename)
  121. {
  122. // Create new PHPExcel
  123. $objPHPExcel = new PHPExcel();
  124. // Load into this instance
  125. return $this->loadIntoExisting($pFilename, $objPHPExcel);
  126. }
  127. /**
  128. * Read filter
  129. *
  130. * @return PHPExcel_Reader_IReadFilter
  131. */
  132. public function getReadFilter()
  133. {
  134. return $this->_readFilter;
  135. }
  136. /**
  137. * Set read filter
  138. *
  139. * @param PHPExcel_Reader_IReadFilter $pValue
  140. */
  141. public function setReadFilter(PHPExcel_Reader_IReadFilter $pValue)
  142. {
  143. $this->_readFilter = $pValue;
  144. return $this;
  145. }
  146. /**
  147. * Set input encoding
  148. *
  149. * @param string $pValue Input encoding
  150. */
  151. public function setInputEncoding($pValue = 'ANSI')
  152. {
  153. $this->_inputEncoding = $pValue;
  154. return $this;
  155. }
  156. /**
  157. * Get input encoding
  158. *
  159. * @return string
  160. */
  161. public function getInputEncoding()
  162. {
  163. return $this->_inputEncoding;
  164. }
  165. /**
  166. * Loads PHPExcel from file into PHPExcel instance
  167. *
  168. * @param string $pFilename
  169. * @param PHPExcel $objPHPExcel
  170. * @return PHPExcel
  171. * @throws Exception
  172. */
  173. public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
  174. {
  175. // Check if file exists
  176. if (! file_exists($pFilename))
  177. {
  178. throw new Exception("Could not open " . $pFilename . " for reading! File does not exist.");
  179. }
  180. // Create new PHPExcel
  181. while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex)
  182. {
  183. $objPHPExcel->createSheet();
  184. }
  185. $objPHPExcel->setActiveSheetIndex($this->_sheetIndex);
  186. $fromFormats = array('\-', '\ ');
  187. $toFormats = array('-', ' ');
  188. // Open file
  189. $fileHandle = fopen($pFilename, 'r');
  190. if ($fileHandle === false)
  191. {
  192. throw new Exception("Could not open file $pFilename for reading.");
  193. }
  194. // Loop through file
  195. $rowData = array();
  196. $column = $row = '';
  197. // loop through one row (line) at a time in the file
  198. while (($rowData = fgets($fileHandle)) !== FALSE)
  199. {
  200. // convert SYLK encoded $rowData to UTF-8
  201. $rowData = PHPExcel_Shared_String :: SYLKtoUTF8($rowData);
  202. // explode each row at semicolons while taking into account that literal semicolon (;)
  203. // is escaped like this (;;)
  204. $rowData = explode("\t", str_replace('¤', ';', str_replace(';', "\t", str_replace(';;', '¤', rtrim($rowData)))));
  205. $dataType = array_shift($rowData);
  206. // Read shared styles
  207. if ($dataType == 'P')
  208. {
  209. $formatArray = array();
  210. foreach ($rowData as $rowDatum)
  211. {
  212. switch ($rowDatum{0})
  213. {
  214. case 'P' :
  215. $formatArray['numberformat']['code'] = str_replace($fromFormats, $toFormats, substr($rowDatum, 1));
  216. break;
  217. case 'E' :
  218. case 'F' :
  219. $formatArray['font']['name'] = substr($rowDatum, 1);
  220. break;
  221. case 'L' :
  222. $formatArray['font']['size'] = substr($rowDatum, 1);
  223. break;
  224. case 'S' :
  225. $styleSettings = substr($rowDatum, 1);
  226. for($i = 0; $i < strlen($styleSettings); ++ $i)
  227. {
  228. switch ($styleSettings{$i})
  229. {
  230. case 'I' :
  231. $formatArray['font']['italic'] = true;
  232. break;
  233. case 'D' :
  234. $formatArray['font']['bold'] = true;
  235. break;
  236. case 'T' :
  237. $formatArray['borders']['top']['style'] = PHPExcel_Style_Border :: BORDER_THIN;
  238. break;
  239. case 'B' :
  240. $formatArray['borders']['bottom']['style'] = PHPExcel_Style_Border :: BORDER_THIN;
  241. break;
  242. case 'L' :
  243. $formatArray['borders']['left']['style'] = PHPExcel_Style_Border :: BORDER_THIN;
  244. break;
  245. case 'R' :
  246. $formatArray['borders']['right']['style'] = PHPExcel_Style_Border :: BORDER_THIN;
  247. break;
  248. }
  249. }
  250. break;
  251. }
  252. }
  253. $this->_formats['P' . $this->_format ++] = $formatArray;
  254. // Read cell value data
  255. }
  256. elseif ($dataType == 'C')
  257. {
  258. $hasCalculatedValue = false;
  259. $cellData = $cellDataFormula = '';
  260. foreach ($rowData as $rowDatum)
  261. {
  262. switch ($rowDatum{0})
  263. {
  264. case 'C' :
  265. case 'X' :
  266. $column = substr($rowDatum, 1);
  267. break;
  268. case 'R' :
  269. case 'Y' :
  270. $row = substr($rowDatum, 1);
  271. break;
  272. case 'K' :
  273. $cellData = substr($rowDatum, 1);
  274. break;
  275. case 'E' :
  276. $cellDataFormula = '=' . substr($rowDatum, 1);
  277. // Convert R1C1 style references to A1 style references (but only when not quoted)
  278. $temp = explode('"', $cellDataFormula);
  279. $key = false;
  280. foreach ($temp as &$value)
  281. {
  282. // Only count/replace in alternate array entries
  283. if ($key = ! $key)
  284. {
  285. preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/', $value, $cellReferences, PREG_SET_ORDER + PREG_OFFSET_CAPTURE);
  286. // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way
  287. // through the formula from left to right. Reversing means that we work right to left.through
  288. // the formula
  289. $cellReferences = array_reverse($cellReferences);
  290. // Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent,
  291. // then modify the formula to use that new reference
  292. foreach ($cellReferences as $cellReference)
  293. {
  294. $rowReference = $cellReference[2][0];
  295. // Empty R reference is the current row
  296. if ($rowReference == '')
  297. $rowReference = $row;
  298. // Bracketed R references are relative to the current row
  299. if ($rowReference{0} == '[')
  300. $rowReference = $row + trim($rowReference, '[]');
  301. $columnReference = $cellReference[4][0];
  302. // Empty C reference is the current column
  303. if ($columnReference == '')
  304. $columnReference = $column;
  305. // Bracketed C references are relative to the current column
  306. if ($columnReference{0} == '[')
  307. $columnReference = $column + trim($columnReference, '[]');
  308. $A1CellReference = PHPExcel_Cell :: stringFromColumnIndex($columnReference - 1) . $rowReference;
  309. $value = substr_replace($value, $A1CellReference, $cellReference[0][1], strlen($cellReference[0][0]));
  310. }
  311. }
  312. }
  313. unset($value);
  314. // Then rebuild the formula string
  315. $cellDataFormula = implode('"', $temp);
  316. $hasCalculatedValue = true;
  317. break;
  318. }
  319. }
  320. $columnLetter = PHPExcel_Cell :: stringFromColumnIndex($column - 1);
  321. $cellData = PHPExcel_Calculation :: _unwrapResult($cellData);
  322. // Set cell value
  323. $objPHPExcel->getActiveSheet()->getCell($columnLetter . $row)->setValue(($hasCalculatedValue) ? $cellDataFormula : $cellData);
  324. if ($hasCalculatedValue)
  325. {
  326. $cellData = PHPExcel_Calculation :: _unwrapResult($cellData);
  327. $objPHPExcel->getActiveSheet()->getCell($columnLetter . $row)->setCalculatedValue($cellData);
  328. }
  329. // Read cell formatting
  330. }
  331. elseif ($dataType == 'F')
  332. {
  333. $formatStyle = $columnWidth = $styleSettings = '';
  334. $styleData = array();
  335. foreach ($rowData as $rowDatum)
  336. {
  337. switch ($rowDatum{0})
  338. {
  339. case 'C' :
  340. case 'X' :
  341. $column = substr($rowDatum, 1);
  342. break;
  343. case 'R' :
  344. case 'Y' :
  345. $row = substr($rowDatum, 1);
  346. break;
  347. case 'P' :
  348. $formatStyle = $rowDatum;
  349. break;
  350. case 'W' :
  351. list($startCol, $endCol, $columnWidth) = explode(' ', substr($rowDatum, 1));
  352. break;
  353. case 'S' :
  354. $styleSettings = substr($rowDatum, 1);
  355. for($i = 0; $i < strlen($styleSettings); ++ $i)
  356. {
  357. switch ($styleSettings{$i})
  358. {
  359. case 'I' :
  360. $styleData['font']['italic'] = true;
  361. break;
  362. case 'D' :
  363. $styleData['font']['bold'] = true;
  364. break;
  365. case 'T' :
  366. $styleData['borders']['top']['style'] = PHPExcel_Style_Border :: BORDER_THIN;
  367. break;
  368. case 'B' :
  369. $styleData['borders']['bottom']['style'] = PHPExcel_Style_Border :: BORDER_THIN;
  370. break;
  371. case 'L' :
  372. $styleData['borders']['left']['style'] = PHPExcel_Style_Border :: BORDER_THIN;
  373. break;
  374. case 'R' :
  375. $styleData['borders']['right']['style'] = PHPExcel_Style_Border :: BORDER_THIN;
  376. break;
  377. }
  378. }
  379. break;
  380. }
  381. }
  382. if (($formatStyle > '') && ($column > '') && ($row > ''))
  383. {
  384. $columnLetter = PHPExcel_Cell :: stringFromColumnIndex($column - 1);
  385. $objPHPExcel->getActiveSheet()->getStyle($columnLetter . $row)->applyFromArray($this->_formats[$formatStyle]);
  386. }
  387. if ((count($styleData) > 0) && ($column > '') && ($row > ''))
  388. {
  389. $columnLetter = PHPExcel_Cell :: stringFromColumnIndex($column - 1);
  390. $objPHPExcel->getActiveSheet()->getStyle($columnLetter . $row)->applyFromArray($styleData);
  391. }
  392. if ($columnWidth > '')
  393. {
  394. if ($startCol == $endCol)
  395. {
  396. $startCol = PHPExcel_Cell :: stringFromColumnIndex($startCol - 1);
  397. $objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth);
  398. }
  399. else
  400. {
  401. $startCol = PHPExcel_Cell :: stringFromColumnIndex($startCol - 1);
  402. $endCol = PHPExcel_Cell :: stringFromColumnIndex($endCol - 1);
  403. $objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth);
  404. do
  405. {
  406. $objPHPExcel->getActiveSheet()->getColumnDimension(++ $startCol)->setWidth($columnWidth);
  407. }
  408. while ($startCol != $endCol);
  409. }
  410. }
  411. }
  412. else
  413. {
  414. foreach ($rowData as $rowDatum)
  415. {
  416. switch ($rowDatum{0})
  417. {
  418. case 'C' :
  419. case 'X' :
  420. $column = substr($rowDatum, 1);
  421. break;
  422. case 'R' :
  423. case 'Y' :
  424. $row = substr($rowDatum, 1);
  425. break;
  426. }
  427. }
  428. }
  429. }
  430. // Close file
  431. fclose($fileHandle);
  432. // Return
  433. return $objPHPExcel;
  434. }
  435. /**
  436. * Get sheet index
  437. *
  438. * @return int
  439. */
  440. public function getSheetIndex()
  441. {
  442. return $this->_sheetIndex;
  443. }
  444. /**
  445. * Set sheet index
  446. *
  447. * @param int $pValue Sheet index
  448. * @return PHPExcel_Reader_SYLK
  449. */
  450. public function setSheetIndex($pValue = 0)
  451. {
  452. $this->_sheetIndex = $pValue;
  453. return $this;
  454. }
  455. }