CSV.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. <?php
  2. /**
  3. * PHPExcel
  4. *
  5. * Copyright (c) 2006 - 2014 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 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
  24. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  25. * @version 1.8.0, 2014-03-02
  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 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
  41. */
  42. class PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract 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. * @var int
  90. */
  91. private $_contiguousRow = -1;
  92. /**
  93. * Create a new PHPExcel_Reader_CSV
  94. */
  95. public function __construct() {
  96. $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter();
  97. }
  98. /**
  99. * Validate that the current file is a CSV file
  100. *
  101. * @return boolean
  102. */
  103. protected function _isValidFormat()
  104. {
  105. return TRUE;
  106. }
  107. /**
  108. * Set input encoding
  109. *
  110. * @param string $pValue Input encoding
  111. */
  112. public function setInputEncoding($pValue = 'UTF-8')
  113. {
  114. $this->_inputEncoding = $pValue;
  115. return $this;
  116. }
  117. /**
  118. * Get input encoding
  119. *
  120. * @return string
  121. */
  122. public function getInputEncoding()
  123. {
  124. return $this->_inputEncoding;
  125. }
  126. /**
  127. * Move filepointer past any BOM marker
  128. *
  129. */
  130. protected function _skipBOM()
  131. {
  132. rewind($this->_fileHandle);
  133. switch ($this->_inputEncoding) {
  134. case 'UTF-8':
  135. fgets($this->_fileHandle, 4) == "\xEF\xBB\xBF" ?
  136. fseek($this->_fileHandle, 3) : fseek($this->_fileHandle, 0);
  137. break;
  138. case 'UTF-16LE':
  139. fgets($this->_fileHandle, 3) == "\xFF\xFE" ?
  140. fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0);
  141. break;
  142. case 'UTF-16BE':
  143. fgets($this->_fileHandle, 3) == "\xFE\xFF" ?
  144. fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0);
  145. break;
  146. case 'UTF-32LE':
  147. fgets($this->_fileHandle, 5) == "\xFF\xFE\x00\x00" ?
  148. fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0);
  149. break;
  150. case 'UTF-32BE':
  151. fgets($this->_fileHandle, 5) == "\x00\x00\xFE\xFF" ?
  152. fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0);
  153. break;
  154. default:
  155. break;
  156. }
  157. }
  158. /**
  159. * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)
  160. *
  161. * @param string $pFilename
  162. * @throws PHPExcel_Reader_Exception
  163. */
  164. public function listWorksheetInfo($pFilename)
  165. {
  166. // Open file
  167. $this->_openFile($pFilename);
  168. if (!$this->_isValidFormat()) {
  169. fclose ($this->_fileHandle);
  170. throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file.");
  171. }
  172. $fileHandle = $this->_fileHandle;
  173. // Skip BOM, if any
  174. $this->_skipBOM();
  175. $escapeEnclosures = array( "\\" . $this->_enclosure, $this->_enclosure . $this->_enclosure );
  176. $worksheetInfo = array();
  177. $worksheetInfo[0]['worksheetName'] = 'Worksheet';
  178. $worksheetInfo[0]['lastColumnLetter'] = 'A';
  179. $worksheetInfo[0]['lastColumnIndex'] = 0;
  180. $worksheetInfo[0]['totalRows'] = 0;
  181. $worksheetInfo[0]['totalColumns'] = 0;
  182. // Loop through each line of the file in turn
  183. while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) {
  184. $worksheetInfo[0]['totalRows']++;
  185. $worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1);
  186. }
  187. $worksheetInfo[0]['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']);
  188. $worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1;
  189. // Close file
  190. fclose($fileHandle);
  191. return $worksheetInfo;
  192. }
  193. /**
  194. * Loads PHPExcel from file
  195. *
  196. * @param string $pFilename
  197. * @return PHPExcel
  198. * @throws PHPExcel_Reader_Exception
  199. */
  200. public function load($pFilename)
  201. {
  202. // Create new PHPExcel
  203. $objPHPExcel = new PHPExcel();
  204. // Load into this instance
  205. return $this->loadIntoExisting($pFilename, $objPHPExcel);
  206. }
  207. /**
  208. * Loads PHPExcel from file into PHPExcel instance
  209. *
  210. * @param string $pFilename
  211. * @param PHPExcel $objPHPExcel
  212. * @return PHPExcel
  213. * @throws PHPExcel_Reader_Exception
  214. */
  215. public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
  216. {
  217. $lineEnding = ini_get('auto_detect_line_endings');
  218. ini_set('auto_detect_line_endings', true);
  219. // Open file
  220. $this->_openFile($pFilename);
  221. if (!$this->_isValidFormat()) {
  222. fclose ($this->_fileHandle);
  223. throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file.");
  224. }
  225. $fileHandle = $this->_fileHandle;
  226. // Skip BOM, if any
  227. $this->_skipBOM();
  228. // Create new PHPExcel object
  229. while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) {
  230. $objPHPExcel->createSheet();
  231. }
  232. $sheet = $objPHPExcel->setActiveSheetIndex($this->_sheetIndex);
  233. $escapeEnclosures = array( "\\" . $this->_enclosure,
  234. $this->_enclosure . $this->_enclosure
  235. );
  236. // Set our starting row based on whether we're in contiguous mode or not
  237. $currentRow = 1;
  238. if ($this->_contiguous) {
  239. $currentRow = ($this->_contiguousRow == -1) ? $sheet->getHighestRow(): $this->_contiguousRow;
  240. }
  241. // Loop through each line of the file in turn
  242. while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) {
  243. $columnLetter = 'A';
  244. foreach($rowData as $rowDatum) {
  245. if ($rowDatum != '' && $this->_readFilter->readCell($columnLetter, $currentRow)) {
  246. // Unescape enclosures
  247. $rowDatum = str_replace($escapeEnclosures, $this->_enclosure, $rowDatum);
  248. // Convert encoding if necessary
  249. if ($this->_inputEncoding !== 'UTF-8') {
  250. $rowDatum = PHPExcel_Shared_String::ConvertEncoding($rowDatum, 'UTF-8', $this->_inputEncoding);
  251. }
  252. // Set cell value
  253. $sheet->getCell($columnLetter . $currentRow)->setValue($rowDatum);
  254. }
  255. ++$columnLetter;
  256. }
  257. ++$currentRow;
  258. }
  259. // Close file
  260. fclose($fileHandle);
  261. if ($this->_contiguous) {
  262. $this->_contiguousRow = $currentRow;
  263. }
  264. ini_set('auto_detect_line_endings', $lineEnding);
  265. // Return
  266. return $objPHPExcel;
  267. }
  268. /**
  269. * Get delimiter
  270. *
  271. * @return string
  272. */
  273. public function getDelimiter() {
  274. return $this->_delimiter;
  275. }
  276. /**
  277. * Set delimiter
  278. *
  279. * @param string $pValue Delimiter, defaults to ,
  280. * @return PHPExcel_Reader_CSV
  281. */
  282. public function setDelimiter($pValue = ',') {
  283. $this->_delimiter = $pValue;
  284. return $this;
  285. }
  286. /**
  287. * Get enclosure
  288. *
  289. * @return string
  290. */
  291. public function getEnclosure() {
  292. return $this->_enclosure;
  293. }
  294. /**
  295. * Set enclosure
  296. *
  297. * @param string $pValue Enclosure, defaults to "
  298. * @return PHPExcel_Reader_CSV
  299. */
  300. public function setEnclosure($pValue = '"') {
  301. if ($pValue == '') {
  302. $pValue = '"';
  303. }
  304. $this->_enclosure = $pValue;
  305. return $this;
  306. }
  307. /**
  308. * Get line ending
  309. *
  310. * @return string
  311. */
  312. public function getLineEnding() {
  313. return $this->_lineEnding;
  314. }
  315. /**
  316. * Set line ending
  317. *
  318. * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL)
  319. * @return PHPExcel_Reader_CSV
  320. */
  321. public function setLineEnding($pValue = PHP_EOL) {
  322. $this->_lineEnding = $pValue;
  323. return $this;
  324. }
  325. /**
  326. * Get sheet index
  327. *
  328. * @return integer
  329. */
  330. public function getSheetIndex() {
  331. return $this->_sheetIndex;
  332. }
  333. /**
  334. * Set sheet index
  335. *
  336. * @param integer $pValue Sheet index
  337. * @return PHPExcel_Reader_CSV
  338. */
  339. public function setSheetIndex($pValue = 0) {
  340. $this->_sheetIndex = $pValue;
  341. return $this;
  342. }
  343. /**
  344. * Set Contiguous
  345. *
  346. * @param boolean $contiguous
  347. */
  348. public function setContiguous($contiguous = FALSE)
  349. {
  350. $this->_contiguous = (bool) $contiguous;
  351. if (!$contiguous) {
  352. $this->_contiguousRow = -1;
  353. }
  354. return $this;
  355. }
  356. /**
  357. * Get Contiguous
  358. *
  359. * @return boolean
  360. */
  361. public function getContiguous() {
  362. return $this->_contiguous;
  363. }
  364. }