For God so loved the world, that He gave His only begotten Son, that all who believe in Him should not perish but have everlasting life
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

406 lines
11 KiB

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