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