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

/application/third_party/PHPExcel/Reader/SYLK.php

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