PageRenderTime 48ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/include/PHPExcel/Reader/SYLK.php

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