/PHPExcel/Reader/CSV.php

https://bitbucket.org/nfredricks/wp-employee-time · PHP · 505 lines · 205 code · 74 blank · 226 comment · 36 complexity · 61912d2ffd0dcba4212627bb06eb3be9 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 1.7.8, 2012-10-12
  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_CSV
  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_CSV implements PHPExcel_Reader_IReader
  43. {
  44. /**
  45. * Input encoding
  46. *
  47. * @access private
  48. * @var string
  49. */
  50. private $_inputEncoding = 'UTF-8';
  51. /**
  52. * Delimiter
  53. *
  54. * @access private
  55. * @var string
  56. */
  57. private $_delimiter = ',';
  58. /**
  59. * Enclosure
  60. *
  61. * @access private
  62. * @var string
  63. */
  64. private $_enclosure = '"';
  65. /**
  66. * Line ending
  67. *
  68. * @access private
  69. * @var string
  70. */
  71. private $_lineEnding = PHP_EOL;
  72. /**
  73. * Sheet index to read
  74. *
  75. * @access private
  76. * @var int
  77. */
  78. private $_sheetIndex = 0;
  79. /**
  80. * Load rows contiguously
  81. *
  82. * @access private
  83. * @var int
  84. */
  85. private $_contiguous = false;
  86. /**
  87. * Row counter for loading rows contiguously
  88. *
  89. * @access private
  90. * @var int
  91. */
  92. private $_contiguousRow = -1;
  93. /**
  94. * PHPExcel_Reader_IReadFilter instance
  95. *
  96. * @access private
  97. * @var PHPExcel_Reader_IReadFilter
  98. */
  99. private $_readFilter = null;
  100. /**
  101. * Create a new PHPExcel_Reader_CSV
  102. */
  103. public function __construct() {
  104. $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter();
  105. } // function __construct()
  106. /**
  107. * Can the current PHPExcel_Reader_IReader read the file?
  108. *
  109. * @access public
  110. * @param string $pFileName
  111. * @return boolean
  112. * @throws Exception
  113. */
  114. public function canRead($pFilename)
  115. {
  116. // Check if file exists
  117. if (!file_exists($pFilename)) {
  118. throw new Exception("Could not open " . $pFilename . " for reading! File does not exist.");
  119. }
  120. return true;
  121. } // function canRead()
  122. /**
  123. * Read filter
  124. *
  125. * @access public
  126. * @return PHPExcel_Reader_IReadFilter
  127. */
  128. public function getReadFilter() {
  129. return $this->_readFilter;
  130. } // function getReadFilter()
  131. /**
  132. * Set read filter
  133. *
  134. * @access public
  135. * @param PHPExcel_Reader_IReadFilter $pValue
  136. */
  137. public function setReadFilter(PHPExcel_Reader_IReadFilter $pValue) {
  138. $this->_readFilter = $pValue;
  139. return $this;
  140. } // function setReadFilter()
  141. /**
  142. * Set input encoding
  143. *
  144. * @access public
  145. * @param string $pValue Input encoding
  146. */
  147. public function setInputEncoding($pValue = 'UTF-8')
  148. {
  149. $this->_inputEncoding = $pValue;
  150. return $this;
  151. } // function setInputEncoding()
  152. /**
  153. * Get input encoding
  154. *
  155. * @access public
  156. * @return string
  157. */
  158. public function getInputEncoding()
  159. {
  160. return $this->_inputEncoding;
  161. } // function getInputEncoding()
  162. /**
  163. * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)
  164. *
  165. * @access public
  166. * @param string $pFilename
  167. * @throws Exception
  168. */
  169. public function listWorksheetInfo($pFilename)
  170. {
  171. // Check if file exists
  172. if (!file_exists($pFilename)) {
  173. throw new Exception("Could not open " . $pFilename . " for reading! File does not exist.");
  174. }
  175. // Open file
  176. $fileHandle = fopen($pFilename, 'r');
  177. if ($fileHandle === false) {
  178. throw new Exception("Could not open file " . $pFilename . " for reading.");
  179. }
  180. // Skip BOM, if any
  181. switch ($this->_inputEncoding) {
  182. case 'UTF-8':
  183. fgets($fileHandle, 4) == "\xEF\xBB\xBF" ?
  184. fseek($fileHandle, 3) : fseek($fileHandle, 0);
  185. break;
  186. case 'UTF-16LE':
  187. fgets($fileHandle, 3) == "\xFF\xFE" ?
  188. fseek($fileHandle, 2) : fseek($fileHandle, 0);
  189. break;
  190. case 'UTF-16BE':
  191. fgets($fileHandle, 3) == "\xFE\xFF" ?
  192. fseek($fileHandle, 2) : fseek($fileHandle, 0);
  193. break;
  194. case 'UTF-32LE':
  195. fgets($fileHandle, 5) == "\xFF\xFE\x00\x00" ?
  196. fseek($fileHandle, 4) : fseek($fileHandle, 0);
  197. break;
  198. case 'UTF-32BE':
  199. fgets($fileHandle, 5) == "\x00\x00\xFE\xFF" ?
  200. fseek($fileHandle, 4) : fseek($fileHandle, 0);
  201. break;
  202. default:
  203. break;
  204. }
  205. $escapeEnclosures = array( "\\" . $this->_enclosure, $this->_enclosure . $this->_enclosure );
  206. $worksheetInfo = array();
  207. $worksheetInfo[0]['worksheetName'] = 'Worksheet';
  208. $worksheetInfo[0]['lastColumnLetter'] = 'A';
  209. $worksheetInfo[0]['lastColumnIndex'] = 0;
  210. $worksheetInfo[0]['totalRows'] = 0;
  211. $worksheetInfo[0]['totalColumns'] = 0;
  212. // Loop through each line of the file in turn
  213. while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) {
  214. $worksheetInfo[0]['totalRows']++;
  215. $worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1);
  216. }
  217. $worksheetInfo[0]['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']);
  218. $worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1;
  219. // Close file
  220. fclose($fileHandle);
  221. return $worksheetInfo;
  222. }
  223. /**
  224. * Loads PHPExcel from file
  225. *
  226. * @access public
  227. * @param string $pFilename
  228. * @return PHPExcel
  229. * @throws Exception
  230. */
  231. public function load($pFilename)
  232. {
  233. // Create new PHPExcel
  234. $objPHPExcel = new PHPExcel();
  235. // Load into this instance
  236. return $this->loadIntoExisting($pFilename, $objPHPExcel);
  237. } // function load()
  238. /**
  239. * Loads PHPExcel from file into PHPExcel instance
  240. *
  241. * @access public
  242. * @param string $pFilename
  243. * @param PHPExcel $objPHPExcel
  244. * @return PHPExcel
  245. * @throws Exception
  246. */
  247. public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
  248. {
  249. // Check if file exists
  250. if (!file_exists($pFilename)) {
  251. throw new Exception("Could not open " . $pFilename . " for reading! File does not exist.");
  252. }
  253. // Create new PHPExcel
  254. while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) {
  255. $objPHPExcel->createSheet();
  256. }
  257. $sheet = $objPHPExcel->setActiveSheetIndex( $this->_sheetIndex );
  258. $lineEnding = ini_get('auto_detect_line_endings');
  259. ini_set('auto_detect_line_endings', true);
  260. // Open file
  261. $fileHandle = fopen($pFilename, 'r');
  262. if ($fileHandle === false) {
  263. throw new Exception("Could not open file $pFilename for reading.");
  264. }
  265. // Skip BOM, if any
  266. switch ($this->_inputEncoding) {
  267. case 'UTF-8':
  268. fgets($fileHandle, 4) == "\xEF\xBB\xBF" ?
  269. fseek($fileHandle, 3) : fseek($fileHandle, 0);
  270. break;
  271. case 'UTF-16LE':
  272. fgets($fileHandle, 3) == "\xFF\xFE" ?
  273. fseek($fileHandle, 2) : fseek($fileHandle, 0);
  274. break;
  275. case 'UTF-16BE':
  276. fgets($fileHandle, 3) == "\xFE\xFF" ?
  277. fseek($fileHandle, 2) : fseek($fileHandle, 0);
  278. break;
  279. case 'UTF-32LE':
  280. fgets($fileHandle, 5) == "\xFF\xFE\x00\x00" ?
  281. fseek($fileHandle, 4) : fseek($fileHandle, 0);
  282. break;
  283. case 'UTF-32BE':
  284. fgets($fileHandle, 5) == "\x00\x00\xFE\xFF" ?
  285. fseek($fileHandle, 4) : fseek($fileHandle, 0);
  286. break;
  287. default:
  288. break;
  289. }
  290. $escapeEnclosures = array( "\\" . $this->_enclosure,
  291. $this->_enclosure . $this->_enclosure
  292. );
  293. // Set our starting row based on whether we're in contiguous mode or not
  294. $currentRow = 1;
  295. if ($this->_contiguous) {
  296. $currentRow = ($this->_contiguousRow == -1) ? $sheet->getHighestRow(): $this->_contiguousRow;
  297. }
  298. // Loop through each line of the file in turn
  299. while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) {
  300. $columnLetter = 'A';
  301. foreach($rowData as $rowDatum) {
  302. if ($rowDatum != '' && $this->_readFilter->readCell($columnLetter, $currentRow)) {
  303. // Unescape enclosures
  304. $rowDatum = str_replace($escapeEnclosures, $this->_enclosure, $rowDatum);
  305. // Convert encoding if necessary
  306. if ($this->_inputEncoding !== 'UTF-8') {
  307. $rowDatum = PHPExcel_Shared_String::ConvertEncoding($rowDatum, 'UTF-8', $this->_inputEncoding);
  308. }
  309. // Set cell value
  310. $sheet->getCell($columnLetter . $currentRow)->setValue($rowDatum);
  311. }
  312. ++$columnLetter;
  313. }
  314. ++$currentRow;
  315. }
  316. // Close file
  317. fclose($fileHandle);
  318. if ($this->_contiguous) {
  319. $this->_contiguousRow = $currentRow;
  320. }
  321. ini_set('auto_detect_line_endings', $lineEnding);
  322. // Return
  323. return $objPHPExcel;
  324. } // function loadIntoExisting()
  325. /**
  326. * Get delimiter
  327. *
  328. * @access public
  329. * @return string
  330. */
  331. public function getDelimiter() {
  332. return $this->_delimiter;
  333. } // function getDelimiter()
  334. /**
  335. * Set delimiter
  336. *
  337. * @access public
  338. * @param string $pValue Delimiter, defaults to ,
  339. * @return PHPExcel_Reader_CSV
  340. */
  341. public function setDelimiter($pValue = ',') {
  342. $this->_delimiter = $pValue;
  343. return $this;
  344. } // function setDelimiter()
  345. /**
  346. * Get enclosure
  347. *
  348. * @access public
  349. * @return string
  350. */
  351. public function getEnclosure() {
  352. return $this->_enclosure;
  353. } // function getEnclosure()
  354. /**
  355. * Set enclosure
  356. *
  357. * @access public
  358. * @param string $pValue Enclosure, defaults to "
  359. * @return PHPExcel_Reader_CSV
  360. */
  361. public function setEnclosure($pValue = '"') {
  362. if ($pValue == '') {
  363. $pValue = '"';
  364. }
  365. $this->_enclosure = $pValue;
  366. return $this;
  367. } // function setEnclosure()
  368. /**
  369. * Get line ending
  370. *
  371. * @access public
  372. * @return string
  373. */
  374. public function getLineEnding() {
  375. return $this->_lineEnding;
  376. } // function getLineEnding()
  377. /**
  378. * Set line ending
  379. *
  380. * @access public
  381. * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL)
  382. * @return PHPExcel_Reader_CSV
  383. */
  384. public function setLineEnding($pValue = PHP_EOL) {
  385. $this->_lineEnding = $pValue;
  386. return $this;
  387. } // function setLineEnding()
  388. /**
  389. * Get sheet index
  390. *
  391. * @access public
  392. * @return int
  393. */
  394. public function getSheetIndex() {
  395. return $this->_sheetIndex;
  396. } // function getSheetIndex()
  397. /**
  398. * Set sheet index
  399. *
  400. * @access public
  401. * @param int $pValue Sheet index
  402. * @return PHPExcel_Reader_CSV
  403. */
  404. public function setSheetIndex($pValue = 0) {
  405. $this->_sheetIndex = $pValue;
  406. return $this;
  407. } // function setSheetIndex()
  408. /**
  409. * Set Contiguous
  410. *
  411. * @access public
  412. * @param string $pValue Input encoding
  413. */
  414. public function setContiguous($contiguous = false)
  415. {
  416. $this->_contiguous = (bool)$contiguous;
  417. if (!$contiguous) {
  418. $this->_contiguousRow = -1;
  419. }
  420. return $this;
  421. } // function setInputEncoding()
  422. /**
  423. * Get Contiguous
  424. *
  425. * @access public
  426. * @return boolean
  427. */
  428. public function getContiguous() {
  429. return $this->_contiguous;
  430. } // function getSheetIndex()
  431. }