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