Parcourir la source

修复若干BUG

liangjianshan il y a 9 ans
Parent
commit
cd8b651b21

+ 38 - 0
PHPExcelReader/PHPExcel/Autoloader.php

@@ -0,0 +1,38 @@
+<?php
+/**
+ * autoload library
+ */
+
+PHPExcel_Autoloader::Register();
+
+class PHPExcel_Autoloader {
+	/**
+	 * Register the Autoloader with SPL
+	 */
+	public static function Register() {
+		if (function_exists('__autoload')) {
+			spl_autoload_register('__autoload');
+		}
+
+		return spl_autoload_register(array('PHPExcel_Autoloader', 'Load'));
+	}
+	
+	
+	/**
+	 * Autoload a class identified by name
+	 * @param	string	$pClassName	Name of the object to load
+	 */
+	public static function Load($pClassName){
+		if ((class_exists($pClassName, FALSE)) || (strpos($pClassName, 'PHPExcel') !== 0)) {
+			return FALSE;
+		}
+	
+		$pClassFilePath = PHPEXCEL_ROOT . str_replace('_', DIRECTORY_SEPARATOR, $pClassName) . '.php';
+
+		if ((file_exists($pClassFilePath) === FALSE) || (is_readable($pClassFilePath) === FALSE)) {
+			return FALSE;
+		}
+	
+		require $pClassFilePath;
+	}
+}

+ 213 - 0
PHPExcelReader/PHPExcel/Reader/CSV.php

@@ -0,0 +1,213 @@
+<?php
+
+class PHPExcel_Reader_CSV implements Iterator, Countable {
+	private $_inputEncoding	= 'UTF-8';
+	private $_delimiter	= ',';
+	private $_enclosure	= '"';
+	private $_filter = 0;
+
+	/**
+	 * @param string $filePath
+	 * @param int $filter  filter empty row
+	 * @throws Exception
+	 */
+	public function __construct($filePath, $filter = 0) {
+		if ( ! file_exists($filePath)) {
+			throw new Exception("Could not open " . $filePath . " for reading! File does not exist.");
+		}
+
+		$this->filePath = $filePath;
+		$this->_filter = $filter;
+		ini_set('auto_detect_line_endings', true);
+		
+		$this->_fileHandle = fopen($filePath,  'r');
+		$this->_detectEncoding();
+	}
+
+	/**
+	 * Move filepointer past any BOM marker
+	 *
+	 */
+	private function _detectEncoding()
+	{
+		$step = 0;
+		while ($step < 3) {
+			$BOM = bin2hex(fread($this->_fileHandle, 2 + $step++));
+			rewind($this->_fileHandle);
+			if ($BOM == 'fffe' || $BOM == 'feff') {
+				$BOMLength = 2;
+				$this->_delimiter = "\t";
+				$this->_inputEncoding = 'UTF-16';
+				break;
+			}
+			else if ($BOM == 'efbbbf') {
+				$BOMLength = 3;
+				break;
+			}
+			else if ($BOM == '0000feff' || $BOM == 'fffe0000') {
+				$BOMLength = 4;
+				$this->_delimiter = "\t";
+				$this->_inputEncoding = 'UTF-32';
+				break;
+			}
+		}
+
+		if ( ! $BOMLength) {
+			$encoding = mb_detect_encoding(fgets($this->_fileHandle, 1024), 'ASCII, UTF-8, GB2312, GBK');
+			rewind($this->_fileHandle);
+			if ($encoding) {
+				if ($encoding == 'EUC-CN') {
+					$this->_inputEncoding = 'GB2312';
+				}
+				else if ($encoding == 'CP936') {
+					$this->_inputEncoding = 'GBK';
+				}
+				else {
+					$this->_inputEncoding = $encoding;
+				}
+			}
+		}
+
+		if ($this->_inputEncoding != 'UTF-8') {
+			stream_filter_register("convert_iconv.*", "convert_iconv_filter");
+			stream_filter_append($this->_fileHandle, 'convert_iconv.' . $this->_inputEncoding . '/UTF-8');
+		}
+	}
+
+	/**
+	 * Returns information about sheets in the file.
+	 * @return array
+	 */
+	public function Sheets() {
+		return array(0 => basename($this->filePath));
+	}
+
+	/**
+	 * Changes sheet to another.
+	 * @param bool
+	 */
+	public function ChangeSheet($index) {
+		if ($index == 0) {
+			$this->rewind();
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Rewind the Iterator to the first element.
+	 */
+	public function rewind() {
+		rewind($this->_fileHandle);
+		$this->currentRow = null;
+		$this->index = 0;
+	}
+
+	/**
+	 * Return the current element.
+	 * @return mixed
+	 */
+	public function current() {
+		if ($this->index == 0 && ! isset($this->currentRow)) {
+			$this->rewind();
+			$this->next();
+			$this->index = 0;
+		}
+
+		return $this->currentRow;
+	}
+
+	/**
+	 * Move forward to next element.
+	 */
+	public function next() {
+		$this->currentRow = array();
+
+		$this->index++;
+		while (($row = fgetcsv($this->_fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== false) {
+			if ( ! $this->_filter || array_filter($row, array($this, 'filter'))) {
+				$this->currentRow = $row;
+				break;
+			}
+		}
+
+		return $this->currentRow;
+	}
+
+	/**
+	 * Return the identifying key of the current element.
+	 * @return mixed
+	 */
+	public function key() {
+		return $this->index;
+	}
+
+	/**
+	 * Check if there is a current element after calls to rewind() or next().
+	 * @return bool
+	 */
+	public function valid() {
+		if ($this->currentRow || ! feof($this->_fileHandle)) {
+			return true;
+		}
+		else {
+			fclose($this->_fileHandle);
+			return false;
+		}
+	}
+
+	/**
+	 * return the count of the contained items
+	 * @return int
+	 */
+	public function count() {
+		if ( ! isset($this->rowCount)) {
+			$total = 0;
+
+			rewind($this->_fileHandle);
+			while (($row = fgetcsv($this->_fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== false) {				
+				if ( ! $this->_filter || array_filter($row, array($this, 'filter'))) {
+					$total++;
+				}
+			}
+
+			$this->rowCount = $total;
+		}
+
+		return $this->rowCount;
+	}
+
+	/**
+	 * filter empty string
+	 * @param mixed $value
+	 * @return boolean
+	 */
+	private function filter($value) {
+		return trim($value) !== '';
+	}
+}
+
+class convert_iconv_filter extends php_user_filter {
+	private $modes;
+
+	function filter($in, $out, &$consumed, $closing) {
+		while ($bucket = stream_bucket_make_writeable($in)) {
+			$bucket->data = mb_convert_encoding($bucket->data, $this->modes[1], $this->modes[0]);
+			$consumed += $bucket->datalen;
+			stream_bucket_append($out, $bucket);
+		}
+		return PSFS_PASS_ON;
+	}
+
+	function onCreate() {
+		$format = explode('/', substr($this->filtername, 14));
+		if (count($format) == 2) {
+			$this->modes = $format;
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+}

Fichier diff supprimé car celui-ci est trop grand
+ 553 - 245
PHPExcelReader/PHPExcel/Reader/Excel5.php


+ 315 - 0
PHPExcelReader/PHPExcel/Reader/OLERead.php

@@ -0,0 +1,315 @@
+<?php
+/**
+ * PHPExcel
+ *
+ * Copyright (c) 2006 - 2014 PHPExcel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category   PHPExcel
+ * @package    PHPExcel_Reader
+ * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
+ * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL
+ * @version    1.8.0, 2014-03-02
+ */
+
+defined('IDENTIFIER_OLE') ||
+    define('IDENTIFIER_OLE', pack('CCCCCCCC', 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1));
+
+class PHPExcel_Reader_OLERead {
+	private $data = '';
+
+	// OLE identifier
+	const IDENTIFIER_OLE = IDENTIFIER_OLE;
+
+	// Size of a sector = 512 bytes
+	const BIG_BLOCK_SIZE					= 0x200;
+
+	// Size of a short sector = 64 bytes
+	const SMALL_BLOCK_SIZE					= 0x40;
+
+	// Size of a directory entry always = 128 bytes
+	const PROPERTY_STORAGE_BLOCK_SIZE		= 0x80;
+
+	// Minimum size of a standard stream = 4096 bytes, streams smaller than this are stored as short streams
+	const SMALL_BLOCK_THRESHOLD				= 0x1000;
+
+	// header offsets
+	const NUM_BIG_BLOCK_DEPOT_BLOCKS_POS	= 0x2c;
+	const ROOT_START_BLOCK_POS				= 0x30;
+	const SMALL_BLOCK_DEPOT_BLOCK_POS		= 0x3c;
+	const EXTENSION_BLOCK_POS				= 0x44;
+	const NUM_EXTENSION_BLOCK_POS			= 0x48;
+	const BIG_BLOCK_DEPOT_BLOCKS_POS		= 0x4c;
+
+	// property storage offsets (directory offsets)
+	const SIZE_OF_NAME_POS					= 0x40;
+	const TYPE_POS							= 0x42;
+	const START_BLOCK_POS					= 0x74;
+	const SIZE_POS							= 0x78;
+
+
+
+	public $wrkbook						= null;
+	public $summaryInformation			= null;
+	public $documentSummaryInformation	= null;
+
+
+	/**
+	 * Read the file
+	 *
+	 * @param $sFileName string Filename
+	 * @throws Exception
+	 */
+	public function read($sFileName)
+	{
+		// Check if file exists and is readable
+		if(!is_readable($sFileName)) {
+			throw new Exception("Could not open " . $sFileName . " for reading! File does not exist, or it is not readable.");
+		}
+
+		// Get the file identifier
+		// Don't bother reading the whole file until we know it's a valid OLE file
+		$this->data = file_get_contents($sFileName, FALSE, NULL, 0, 8);
+
+		// Check OLE identifier
+		if ($this->data != self::IDENTIFIER_OLE) {
+			throw new Exception('The filename ' . $sFileName . ' is not recognised as an OLE file');
+		}
+
+		// Get the file data
+		$this->data = file_get_contents($sFileName);
+
+		// Total number of sectors used for the SAT
+		$this->numBigBlockDepotBlocks = self::_GetInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);
+
+		// SecID of the first sector of the directory stream
+		$this->rootStartBlock = self::_GetInt4d($this->data, self::ROOT_START_BLOCK_POS);
+
+		// SecID of the first sector of the SSAT (or -2 if not extant)
+		$this->sbdStartBlock = self::_GetInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS);
+
+		// SecID of the first sector of the MSAT (or -2 if no additional sectors are used)
+		$this->extensionBlock = self::_GetInt4d($this->data, self::EXTENSION_BLOCK_POS);
+
+		// Total number of sectors used by MSAT
+		$this->numExtensionBlocks = self::_GetInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS);
+
+		$bigBlockDepotBlocks = array();
+		$pos = self::BIG_BLOCK_DEPOT_BLOCKS_POS;
+
+		$bbdBlocks = $this->numBigBlockDepotBlocks;
+
+		if ($this->numExtensionBlocks != 0) {
+			$bbdBlocks = (self::BIG_BLOCK_SIZE - self::BIG_BLOCK_DEPOT_BLOCKS_POS)/4;
+		}
+
+		for ($i = 0; $i < $bbdBlocks; ++$i) {
+			  $bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos);
+			  $pos += 4;
+		}
+
+		for ($j = 0; $j < $this->numExtensionBlocks; ++$j) {
+			$pos = ($this->extensionBlock + 1) * self::BIG_BLOCK_SIZE;
+			$blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, self::BIG_BLOCK_SIZE / 4 - 1);
+
+			for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; ++$i) {
+				$bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos);
+				$pos += 4;
+			}
+
+			$bbdBlocks += $blocksToRead;
+			if ($bbdBlocks < $this->numBigBlockDepotBlocks) {
+				$this->extensionBlock = self::_GetInt4d($this->data, $pos);
+			}
+		}
+
+		$pos = 0;
+		$this->bigBlockChain = '';
+		$bbs = self::BIG_BLOCK_SIZE / 4;
+		for ($i = 0; $i < $this->numBigBlockDepotBlocks; ++$i) {
+			$pos = ($bigBlockDepotBlocks[$i] + 1) * self::BIG_BLOCK_SIZE;
+
+			$this->bigBlockChain .= substr($this->data, $pos, 4*$bbs);
+			$pos += 4*$bbs;
+		}
+
+		$pos = 0;
+		$sbdBlock = $this->sbdStartBlock;
+		$this->smallBlockChain = '';
+		while ($sbdBlock != -2) {
+			$pos = ($sbdBlock + 1) * self::BIG_BLOCK_SIZE;
+
+			$this->smallBlockChain .= substr($this->data, $pos, 4*$bbs);
+			$pos += 4*$bbs;
+
+			$sbdBlock = self::_GetInt4d($this->bigBlockChain, $sbdBlock*4);
+		}
+
+		// read the directory stream
+		$block = $this->rootStartBlock;
+		$this->entry = $this->_readData($block);
+
+		$this->_readPropertySets();
+	}
+
+	/**
+	 * Extract binary stream data
+	 *
+	 * @return string
+	 */
+	public function getStream($stream)
+	{
+		if ($stream === NULL) {
+			return null;
+		}
+
+		$streamData = '';
+
+		if ($this->props[$stream]['size'] < self::SMALL_BLOCK_THRESHOLD) {
+			$rootdata = $this->_readData($this->props[$this->rootentry]['startBlock']);
+
+			$block = $this->props[$stream]['startBlock'];
+
+			while ($block != -2) {
+	  			$pos = $block * self::SMALL_BLOCK_SIZE;
+				$streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE);
+
+				$block = self::_GetInt4d($this->smallBlockChain, $block*4);
+			}
+
+			return $streamData;
+		} else {
+			$numBlocks = $this->props[$stream]['size'] / self::BIG_BLOCK_SIZE;
+			if ($this->props[$stream]['size'] % self::BIG_BLOCK_SIZE != 0) {
+				++$numBlocks;
+			}
+
+			if ($numBlocks == 0) return '';
+
+			$block = $this->props[$stream]['startBlock'];
+
+			while ($block != -2) {
+				$pos = ($block + 1) * self::BIG_BLOCK_SIZE;
+				$streamData .= substr($this->data, $pos, self::BIG_BLOCK_SIZE);
+				$block = self::_GetInt4d($this->bigBlockChain, $block*4);
+			}
+
+			return $streamData;
+		}
+	}
+
+	/**
+	 * Read a standard stream (by joining sectors using information from SAT)
+	 *
+	 * @param int $bl Sector ID where the stream starts
+	 * @return string Data for standard stream
+	 */
+	private function _readData($bl)
+	{
+		$block = $bl;
+		$data = '';
+
+		while ($block != -2)  {
+			$pos = ($block + 1) * self::BIG_BLOCK_SIZE;
+			$data .= substr($this->data, $pos, self::BIG_BLOCK_SIZE);
+			$block = self::_GetInt4d($this->bigBlockChain, $block*4);
+		}
+		return $data;
+	 }
+
+	/**
+	 * Read entries in the directory stream.
+	 */
+	private function _readPropertySets() {
+		$offset = 0;
+
+		// loop through entires, each entry is 128 bytes
+		$entryLen = strlen($this->entry);
+		while ($offset < $entryLen) {
+			// entry data (128 bytes)
+			$d = substr($this->entry, $offset, self::PROPERTY_STORAGE_BLOCK_SIZE);
+
+			// size in bytes of name
+			$nameSize = ord($d[self::SIZE_OF_NAME_POS]) | (ord($d[self::SIZE_OF_NAME_POS+1]) << 8);
+
+			// type of entry
+			$type = ord($d[self::TYPE_POS]);
+
+			// sectorID of first sector or short sector, if this entry refers to a stream (the case with workbook)
+			// sectorID of first sector of the short-stream container stream, if this entry is root entry
+			$startBlock = self::_GetInt4d($d, self::START_BLOCK_POS);
+
+			$size = self::_GetInt4d($d, self::SIZE_POS);
+
+			$name = str_replace("\x00", "", substr($d,0,$nameSize));
+
+
+			$this->props[] = array (
+				'name' => $name,
+				'type' => $type,
+				'startBlock' => $startBlock,
+				'size' => $size);
+
+			// tmp helper to simplify checks
+			$upName = strtoupper($name);
+
+			// Workbook directory entry (BIFF5 uses Book, BIFF8 uses Workbook)
+			if (($upName === 'WORKBOOK') || ($upName === 'BOOK')) {
+				$this->wrkbook = count($this->props) - 1;
+			}
+			else if ( $upName === 'ROOT ENTRY' || $upName === 'R') {
+				// Root entry
+				$this->rootentry = count($this->props) - 1;
+			}
+
+			// Summary information
+			if ($name == chr(5) . 'SummaryInformation') {
+//				echo 'Summary Information<br />';
+				$this->summaryInformation = count($this->props) - 1;
+			}
+
+			// Additional Document Summary information
+			if ($name == chr(5) . 'DocumentSummaryInformation') {
+//				echo 'Document Summary Information<br />';
+				$this->documentSummaryInformation = count($this->props) - 1;
+			}
+
+			$offset += self::PROPERTY_STORAGE_BLOCK_SIZE;
+		}
+	}
+
+	/**
+	 * Read 4 bytes of data at specified position
+	 *
+	 * @param string $data
+	 * @param int $pos
+	 * @return int
+	 */
+	private static function _GetInt4d($data, $pos)
+	{
+		// FIX: represent numbers correctly on 64-bit system
+		// http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334
+		// Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems
+		$_or_24 = ord($data[$pos + 3]);
+		if ($_or_24 >= 128) {
+			// negative number
+			$_ord_24 = -abs((256 - $_or_24) << 24);
+		} else {
+			$_ord_24 = ($_or_24 & 127) << 24;
+		}
+		return ord($data[$pos]) | (ord($data[$pos + 1]) << 8) | (ord($data[$pos + 2]) << 16) | $_ord_24;
+	}
+}

+ 31 - 36
PHPExcelReader/SpreadsheetReader/SpreadsheetReader_XLS.php → PHPExcelReader/PHPExcel/Reader/XLS.php

@@ -1,27 +1,33 @@
 <?php
 
-class SpreadsheetReader_XLS implements Iterator, Countable {
+class PHPExcel_Reader_XLS implements Iterator, Countable {
 	private $handle = false;
 	private $index = 0;
 	private $rowCount = null;
 	private $currentSheet = 0;
 	private $currentRow = null;
-	
+
 	public  $error = false;
-	
+
 	public function __construct($filePath) {
-		self::classLoad();
-		$this->handle = new Spreadsheet_Excel_Reader($filePath);
-		if ($this->handle->error) {
+		if ( ! file_exists($filePath)) {
+			throw new Exception("Could not open " . $filePath . " for reading! File does not exist.");
+		}
+
+		try {
+			$this->handle = new PHPExcel_Reader_Excel5($filePath);
+
+			return true;
+		} catch (Exception $e) {
 			$this->error = true;
 			return false;
 		}
 	}
-	
+
 	public function __destruct() {
 		unset($this->handle);
 	}
-	
+
 	/**
 	 * Retrieves an array with information about sheets in the current file
 	 *
@@ -30,10 +36,10 @@ class SpreadsheetReader_XLS implements Iterator, Countable {
 	public function Sheets() {
 		$this->sheetInfo = $this->handle->getWorksheetInfo();
 		$this->rowCount = $this->sheetInfo['totalRows'];
-		
+
 		return $this->sheetInfo;
 	}
-	
+
 	/**
 	 * Changes the current sheet in the file to another
 	 * @param $index int
@@ -42,27 +48,27 @@ class SpreadsheetReader_XLS implements Iterator, Countable {
 	public function ChangeSheet($index)	{
 		return $this->handle->ChangeSheet($index);
 	}
-	
+
 	/**
 	 * Rewind the Iterator to the first element.
 	 */
 	public function rewind() {
 		$this->index = 0;
 	}
-	
+
 	/**
 	 * Return the current element.
 	 * @return mixed
 	 */
 	public function current() {
-		if ($this->index == 0 && is_null($this->currentRow)) {
+		if ($this->index == 0 && ! isset($this->currentRow)) {
 			$this->next();
 			$this->index = 0;
 		}
 
 		return $this->currentRow;
 	}
-	
+
 	/**
 	 * Move forward to next element.
 	 */
@@ -71,21 +77,16 @@ class SpreadsheetReader_XLS implements Iterator, Countable {
 		if( ! $this->sheetInfo) {
 			$this->Sheets();
 		}
-		
+
 		$this->index++;
 		$cell = $this->handle->getCell();
-		if(count($cell) < $this->sheetInfo['totalColumns']){
-			for($i = 0; $i < $this->sheetInfo['totalColumns']; $i++) {
-				$this->currentRow[$i] = isset($cell[$i]) ? $cell[$i] : '';
-			}
-		}
-		else{
-			$this->currentRow = $cell;
+		for($i = 0; $i < $this->sheetInfo['totalColumns']; $i++) {
+			$this->currentRow[$i] = isset($cell[$i]) ? $cell[$i] : '';
 		}
-		
+
 		return $this->currentRow;
 	}
-	
+
 	/**
 	 * Return the identifying key of the current element.
 	 * @return mixed
@@ -93,7 +94,7 @@ class SpreadsheetReader_XLS implements Iterator, Countable {
 	public function key() {
 		return $this->index;
 	}
-	
+
 	/**
 	 * Check if there is a current element after calls to rewind() or next().
 	 * @return boolean
@@ -102,10 +103,10 @@ class SpreadsheetReader_XLS implements Iterator, Countable {
 		if ($this->error) {
 			return false;
 		}
-		
+
 		return ($this->index < $this->count());
 	}
-	
+
 	/**
 	 * return the count of the contained items
 	 */
@@ -113,17 +114,11 @@ class SpreadsheetReader_XLS implements Iterator, Countable {
 		if ($this->error) {
 			return 0;
 		}
-		
-		if(is_null($this->rowCount)){
+
+		if( ! isset($this->rowCount)){
 			$this->Sheets();
 		}
-		
+
 		return $this->rowCount;
 	}
-	
-	private static function classLoad()	{
-		if ( ! class_exists('Spreadsheet_Excel_Reader', false)) {
-			require dirname(__FILE__) . DIRECTORY_SEPARATOR . 'SpreadsheetReader.php';
-		}
-	}
 }

+ 27 - 16
PHPExcelReader/SpreadsheetReader/SpreadsheetReader_XLSX.php → PHPExcelReader/PHPExcel/Reader/XLSX.php

@@ -1,6 +1,6 @@
 <?php
 
-class SpreadsheetReader_XLSX implements Iterator, Countable {
+class PHPExcel_Reader_XLSX implements Iterator, Countable {
 	const CELL_TYPE_BOOL = 'b';
 	const CELL_TYPE_NUMBER = 'n';
 	const CELL_TYPE_ERROR = 'e';
@@ -111,7 +111,7 @@ class SpreadsheetReader_XLSX implements Iterator, Countable {
 		11 => '0.00E+00',
 		12 => '# ?/?',
 		13 => '# ??/??',
-		14 => 'mm-dd-yy',
+		14 => 'yyyy/m/d',
 		15 => 'd-mmm-yy',
 		16 => 'd-mmm',
 		17 => 'mmm-yy',
@@ -119,21 +119,30 @@ class SpreadsheetReader_XLSX implements Iterator, Countable {
 		19 => 'h:mm:ss AM/PM',
 		20 => 'h:mm',
 		21 => 'h:mm:ss',
-		22 => 'm/d/yy h:mm',
+		22 => 'yyyy/m/d h:mm',
+		
+		31 => 'yyyy年m月d日',
+		32 => 'h时mmi分',
+		33 => 'h时mmi分ss秒',
 
 		37 => '#,##0 ;(#,##0)',
 		38 => '#,##0 ;[Red](#,##0)',
 		39 => '#,##0.00;(#,##0.00)',
 		40 => '#,##0.00;[Red](#,##0.00)',
 
+		44 => '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)',
 		45 => 'mm:ss',
 		46 => '[h]:mm:ss',
-		47 => 'mmss.0',
+		47 => 'mm:ss.0',
 		48 => '##0.0E+0',
 		49 => '@',
 
+		55 => 'AM/PM h时mmi分',
+		56 => 'AM/PM h时mmi分ss秒',
+		58 => 'm月d日',
+
 		// CHT & CHS
-		27 => '[$-404]e/m/d',
+		27 => 'yyyy年m月',
 		30 => 'm/d/yy',
 		36 => '[$-404]e/m/d',
 		50 => '[$-404]e/m/d',
@@ -142,7 +151,7 @@ class SpreadsheetReader_XLSX implements Iterator, Countable {
 		// THA
 		59 => 't0',
 		60 => 't0.00',
-		61 =>'t#,##0',
+		61 => 't#,##0',
 		62 => 't#,##0.00',
 		67 => 't0%',
 		68 => 't0.00%',
@@ -155,12 +164,14 @@ class SpreadsheetReader_XLSX implements Iterator, Countable {
 		'All' => array(
 			'\\' => '',
 			'am/pm' => 'A',
+			'e' => 'Y',
 			'yyyy' => 'Y',
 			'yy' => 'y',
 			'mmmmm' => 'M',
 			'mmmm' => 'F',
 			'mmm' => 'M',
 			':mm' => ':i',
+			'mmi'	=> 'i',
 			'mm' => 'm',
 			'm' => 'n',
 			'dddd' => 'l',
@@ -176,13 +187,13 @@ class SpreadsheetReader_XLSX implements Iterator, Countable {
 		),
 		'12H' => array(
 			'hh' => 'h',
-			'h' => 'G'
+			'h' => 'g'
 		)
 	);
 
 	private static $BaseDate = false;
 	private static $DecimalSeparator = '.';
-	private static $ThousandSeparator = '';
+	private static $ThousandSeparator = ',';
 	private static $CurrencyCode = '';
 
 	/**
@@ -274,7 +285,7 @@ class SpreadsheetReader_XLSX implements Iterator, Countable {
 					}
 				}
 			}
-			
+
 			if ($this -> StylesXML -> numFmts && $this -> StylesXML -> numFmts -> numFmt)
 			{
 				foreach ($this -> StylesXML -> numFmts -> numFmt as $Index => $NumFmt)
@@ -650,7 +661,7 @@ class SpreadsheetReader_XLSX implements Iterator, Countable {
 			}
 			elseif (isset($this -> Formats[$Index]))
 			{
-				$Format['Code'] = $this -> Formats[$Index];
+				$Format['Code'] = str_replace('"', '', $this -> Formats[$Index]);
 			}
 
 			// Format code found, now parsing the format
@@ -658,7 +669,7 @@ class SpreadsheetReader_XLSX implements Iterator, Countable {
 			{
 				$Sections = explode(';', $Format['Code']);
 				$Format['Code'] = $Sections[0];
-				
+
 				switch (count($Sections))
 				{
 					case 2:
@@ -691,7 +702,7 @@ class SpreadsheetReader_XLSX implements Iterator, Countable {
 			{
 				$Format['Type'] = 'Percentage';
 			}
-			elseif (preg_match('/^(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy]/i', $Format['Code']))
+			elseif (preg_match('/(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy]/i', $Format['Code']))
 			{
 				$Format['Type'] = 'DateTime';
 
@@ -788,10 +799,10 @@ class SpreadsheetReader_XLSX implements Iterator, Countable {
 		// Applying format to value
 		if ($Format)
 		{
-    		if ($Format['Code'] == '@')
-    		{
-        		return (string)$Value;
-    		}
+			if ($Format['Code'] == '@')
+			{
+				return (string)$Value;
+			}
 			// Percentages
 			elseif ($Format['Type'] == 'Percentage')
 			{

+ 42 - 68
PHPExcelReader/PHPExcelReader.php

@@ -5,20 +5,21 @@
  * @version 1.0.0
  * @author Janson Leung
  */
+
+/** PHPExcel root directory */
+if ( ! defined('PHPEXCEL_ROOT')) {
+	define('PHPEXCEL_ROOT', dirname(__FILE__) . '/');
+	require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
+}
+
 class PHPExcelReader implements SeekableIterator, Countable {
 	const TYPE_XLSX = 'XLSX';
 	const TYPE_XLS = 'XLS';
 	const TYPE_CSV = 'CSV';
-	const TYPE_ODS = 'ODS';
-
-	private $options = array(
-		'Delimiter' => '',
-		'Enclosure' => '"'
-	);
 
+	private $handle;
+	private $type;
 	private $index = 0;
-	private $handle = array();
-	private $type = false;
 
 	/**
 	 * @param string Path to file
@@ -27,7 +28,7 @@ class PHPExcelReader implements SeekableIterator, Countable {
 	 */
 	public function __construct($filePath, $originalFileName = false, $mimeType = false) {
 		if ( ! is_readable($filePath)) {
-			throw new Exception('SpreadsheetReader: File (' . $filePath . ') not readable');
+			throw new Exception('PHPExcel_Reader: File (' . $filePath . ') not readable');
 		}
 
 		$defaultTimeZone = @date_default_timezone_get();
@@ -38,10 +39,10 @@ class PHPExcelReader implements SeekableIterator, Countable {
 		// Checking the other parameters for correctness
 		// This should be a check for string but we're lenient
 		if ( ! empty($originalFileName) && ! is_scalar($originalFileName)) {
-			throw new Exception('SpreadsheetReader: Original file (2nd parameter) path is not a string or a scalar value.');
+			throw new Exception('PHPExcel_Reader: Original file (2nd parameter) is not a string or a scalar value.');
 		}
 		if ( ! empty($mimeType) && ! is_scalar($mimeType)) {
-			throw new Exception('SpreadsheetReader: Mime type (3nd parameter) path is not a string or a scalar value.');
+			throw new Exception('PHPExcel_Reader: Mime type (3nd parameter) is not a string or a scalar value.');
 		}
 
 		// 1. Determine type
@@ -52,46 +53,49 @@ class PHPExcelReader implements SeekableIterator, Countable {
 		$Extension = strtolower(pathinfo($originalFileName, PATHINFO_EXTENSION));
 		if($mimeType) {
 			switch ($mimeType) {
-				case 'text/csv':
+				case 'application/octet-stream':
+					$this->type = $Extension == 'xlsx' ? self::TYPE_XLSX : self::TYPE_CSV;
+					break;
+				case 'text/x-comma-separated-values':
 				case 'text/comma-separated-values':
+				case 'application/x-csv':
+				case 'text/x-csv':
+				case 'text/csv':
+				case 'application/csv':
+				case 'application/vnd.msexcel':
 				case 'text/plain':
 					$this->type = self::TYPE_CSV;
 					break;
-				case 'application/vnd.ms-excel':
 				case 'application/msexcel':
 				case 'application/x-msexcel':
 				case 'application/x-ms-excel':
-				case 'application/vnd.ms-excel':
 				case 'application/x-excel':
 				case 'application/x-dos_ms_excel':
 				case 'application/xls':
-				case 'application/xlt':
 				case 'application/x-xls':
-					// Excel does weird stuff
-					if (in_array($Extension, array('csv', 'tsv', 'txt'))) {
-						$this->type = self::TYPE_CSV;
-					}
-					else {
-						$this->type = self::TYPE_XLS;
-					}
+				case 'application/download':
+				case 'application/vnd.ms-office':
+				case 'application/msword':
+				case 'application/xlt':
+					$this->type = self::TYPE_XLS;
 					break;
-				case 'application/vnd.oasis.opendocument.spreadsheet':
-				case 'application/vnd.oasis.opendocument.spreadsheet-template':
-					$this->type = self::TYPE_ODS;
+				case 'application/vnd.ms-excel':
+				case 'application/excel':
+					$this->type = $Extension == 'csv' ? self::TYPE_CSV : self::TYPE_XLS;
 					break;
 				case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
 				case 'application/vnd.openxmlformats-officedocument.spreadsheetml.template':
+				case 'application/zip':
+				case 'application/msword':
+				case 'application/x-zip':
 				case 'application/xlsx':
 				case 'application/xltx':
 					$this->type = self::TYPE_XLSX;
 					break;
-				case 'application/xml':
-					// Excel 2004 xml format uses this
-					break;
 			}
 		}
 
-		if ( ! $this->type)	{
+		if ( ! $this->type) {
 			switch ($Extension) {
 				case 'xlsx':
 				case 'xltx': // XLSX template
@@ -103,10 +107,6 @@ class PHPExcelReader implements SeekableIterator, Countable {
 				case 'xlt':
 					$this->type = self::TYPE_XLS;
 					break;
-				case 'ods':
-				case 'odt':
-					$this->type = self::TYPE_ODS;
-					break;
 				default:
 					$this->type = self::TYPE_CSV;
 					break;
@@ -115,8 +115,7 @@ class PHPExcelReader implements SeekableIterator, Countable {
 
 		// Pre-checking XLS files, in case they are renamed CSV or XLSX files
 		if ($this->type == self::TYPE_XLS) {
-			self::Load(self::TYPE_XLS);
-			$this->handle = new SpreadsheetReader_XLS($filePath);
+			$this->handle = new PHPExcel_Reader_XLS($filePath);
 			if ($this->handle->error) {
 				$this->handle->__destruct();
 
@@ -133,31 +132,25 @@ class PHPExcelReader implements SeekableIterator, Countable {
 		// 2. Create handle
 		switch ($this->type) {
 			case self::TYPE_XLSX:
-				self::Load(self::TYPE_XLSX);
-				$this->handle = new SpreadsheetReader_XLSX($filePath);
+				$this->handle = new PHPExcel_Reader_XLSX($filePath);
 				break;
 			case self::TYPE_CSV:
-				self::Load(self::TYPE_CSV);
-				$this->handle = new SpreadsheetReader_CSV($filePath, $this->options, 'GBK');
+				$this->handle = new PHPExcel_Reader_CSV($filePath, 1);
 				break;
 			case self::TYPE_XLS:
 				// Everything already happens above
 				break;
-			case self::TYPE_ODS:
-				self::Load(self::TYPE_ODS);
-				$this->handle = new SpreadsheetReader_ODS($filePath, $this->options);
-				break;
 		}
 	}
-	
+
 	/**
 	 * get the type of file
 	 * @return string
 	 */
-	public function getType() {
+	public function getFileType() {
 		return $this->type;
 	}
-	
+
 	/**
 	 * Gets information about separate sheets in the given file
 	 *
@@ -182,25 +175,6 @@ class PHPExcelReader implements SeekableIterator, Countable {
 	}
 
 	/**
-	 * Autoloads the required class for the particular spreadsheet type
-	 *
-	 * @param TYPE_* Spreadsheet type, one of TYPE_* constants of this class
-	 */
-	private static function Load($type) {
-		if ( ! in_array($type, array(self::TYPE_XLSX, self::TYPE_XLS, self::TYPE_CSV, self::TYPE_ODS))) {
-			throw new Exception('SpreadsheetReader: Invalid type (' . $type . ')');
-		}
-
-		// 2nd parameter is to prevent autoloading for the class.
-		// If autoload works, the require line is unnecessary, if it doesn't, it ends badly.
-		if ( ! class_exists('SpreadsheetReader_' . $type, false)) {
-			require(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'SpreadsheetReader' . DIRECTORY_SEPARATOR . 'SpreadsheetReader_' . $type . '.php');
-		}
-	}
-
-	// !Iterator interface methods
-
-	/** 
 	 * Rewind the Iterator to the first element.
 	 * Similar to the reset() function for arrays in PHP
 	 */ 
@@ -281,7 +255,7 @@ class PHPExcelReader implements SeekableIterator, Countable {
 	 */
 	public function seek($position)	{
 		if ( ! $this->handle) {
-			throw new OutOfBoundsException('SpreadsheetReader: No file opened');
+			throw new OutOfBoundsException('PHPExcel_Reader: No file opened');
 		}
 
 		$Currentindex = $this->handle->key();
@@ -295,10 +269,10 @@ class PHPExcelReader implements SeekableIterator, Countable {
 			}
 
 			if ( ! $this->handle->valid()) {
-				throw new OutOfBoundsException('SpreadsheetError: position ' . $position . ' not found');
+				throw new OutOfBoundsException('PHPExcel_Reader: position ' . $position . ' not found');
 			}
 		}
 
 		return null;
 	}
-}
+}

+ 0 - 215
PHPExcelReader/SpreadsheetReader/OLERead.php

@@ -1,215 +0,0 @@
-<?php
-
-defined('IDENTIFIER_OLE') ||
-	define('IDENTIFIER_OLE', pack('CCCCCCCC', 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1));
-
-class PHPExcel_Shared_OLERead {
-	private $data = '';
-	
-	const IDENTIFIER_OLE 					= IDENTIFIER_OLE;	// OLE identifier
-	const BIG_BLOCK_SIZE					= 0x200;
-	const SMALL_BLOCK_SIZE					= 0x40;			// Size of a short sector = 64 bytes
-	const PROPERTY_STORAGE_BLOCK_SIZE		= 0x80;			// Size of a directory entry always = 128 bytes
-	const SMALL_BLOCK_THRESHOLD				= 0x1000;		// Minimum size of a standard stream = 4096 bytes, streams smaller than this are stored as short streams
-	
-	// header offsets
-	const NUM_BIG_BLOCK_DEPOT_BLOCKS_POS	= 0x2c;
-	const ROOT_START_BLOCK_POS				= 0x30;
-	const SMALL_BLOCK_DEPOT_BLOCK_POS		= 0x3c;
-	const EXTENSION_BLOCK_POS				= 0x44;
-	const NUM_EXTENSION_BLOCK_POS			= 0x48;
-	const BIG_BLOCK_DEPOT_BLOCKS_POS		= 0x4c;
-	
-	// property storage offsets (directory offsets)
-	const SIZE_OF_NAME_POS					= 0x40;
-	const TYPE_POS							= 0x42;
-	const START_BLOCK_POS					= 0x74;
-	const SIZE_POS							= 0x78;
-	
-	public $error = false;
-	public $workbook = null;
-	public $summaryInformation = null;
-	public $documentSummaryInformation = null;
-	
-	public function read($file){
-		if( ! is_readable($file)) {
-			throw new Exception('SpreadsheetReader_XLS: File not readable (' . $file . ')');
-		}
-		
-		$this->data = file_get_contents($file);
-		if( ! $this->data || substr($this->data, 0, 8) != self::IDENTIFIER_OLE){
-			$this->error = true;
-			return false;
-		}
-		
-		$this->numBigBlockDepotBlocks = self::_GetInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);
-		$this->rootStartBlock = self::_GetInt4d($this->data, self::ROOT_START_BLOCK_POS);
-		$this->sbdStartBlock = self::_GetInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS);
-		$this->extensionBlock = self::_GetInt4d($this->data, self::EXTENSION_BLOCK_POS);
-		$this->numExtensionBlocks = self::_GetInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS);
-		
-		$bigBlockDepotBlocks = array();
-		$pos = self::BIG_BLOCK_DEPOT_BLOCKS_POS;
-		$bbdBlocks = $this->numExtensionBlocks == 0 ? $this->numBigBlockDepotBlocks : (self::BIG_BLOCK_SIZE - self::BIG_BLOCK_DEPOT_BLOCKS_POS) / 4;
-		for ($i = 0; $i < $bbdBlocks; ++$i) {
-			$bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos);
-			$pos += 4;
-		}
-		
-		for ($j = 0; $j < $this->numExtensionBlocks; ++$j) {
-			$pos = ($this->extensionBlock + 1) * self::BIG_BLOCK_SIZE;
-			$blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, self::BIG_BLOCK_SIZE / 4 - 1);
-		
-			for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; ++$i) {
-				$bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos);
-				$pos += 4;
-			}
-		
-			$bbdBlocks += $blocksToRead;
-			if ($bbdBlocks < $this->numBigBlockDepotBlocks) {
-				$this->extensionBlock = self::_GetInt4d($this->data, $pos);
-			}
-		}
-		
-		$pos = 0;
-		$this->bigBlockChain = '';
-		$bbs = self::BIG_BLOCK_SIZE / 4;
-		for ($i = 0; $i < $this->numBigBlockDepotBlocks; ++$i) {
-			$pos = ($bigBlockDepotBlocks[$i] + 1) * self::BIG_BLOCK_SIZE;
-		
-			$this->bigBlockChain .= substr($this->data, $pos, 4*$bbs);
-			$pos += 4*$bbs;
-		}
-		
-		$pos = 0;
-		$sbdBlock = $this->sbdStartBlock;
-		$this->smallBlockChain = '';
-		while ($sbdBlock != -2) {
-			$pos = ($sbdBlock + 1) * self::BIG_BLOCK_SIZE;
-			$this->smallBlockChain .= substr($this->data, $pos, 4*$bbs);
-			$pos += 4*$bbs;
-			$sbdBlock = self::_GetInt4d($this->bigBlockChain, 4*$sbdBlock);
-		}
-		
-		$block = $this->rootStartBlock;				// read the directory stream
-		$this->entry = $this->_readData($block);
-		
-		$this->_readPropertySets();
-	}
-	
-	/**
-	 * Extract binary stream data
-	 *
-	 * @return string
-	 */
-	public function getStream($stream) {
-		if ($stream === NULL) {
-			return null;
-		}
-	
-		$streamData = '';
-		if ($this->props[$stream]['size'] < self::SMALL_BLOCK_THRESHOLD) {
-			$rootdata = $this->_readData($this->props[$this->rootentry]['startBlock']);
-			$block = $this->props[$stream]['startBlock'];
-	
-			while ($block != -2) {
-				$pos = $block * self::SMALL_BLOCK_SIZE;
-				$streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE);
-				$block = self::_GetInt4d($this->smallBlockChain, $block*4);
-			}
-		} 
-		else {
-			$numBlocks = $this->props[$stream]['size'] / self::BIG_BLOCK_SIZE;
-			if ($this->props[$stream]['size'] % self::BIG_BLOCK_SIZE != 0) {
-				++$numBlocks;
-			}
-	
-			if($numBlocks){
-				$block = $this->props[$stream]['startBlock'];
-		
-				while ($block != -2) {
-					$pos = ($block + 1) * self::BIG_BLOCK_SIZE;
-					$streamData .= substr($this->data, $pos, self::BIG_BLOCK_SIZE);
-					$block = self::_GetInt4d($this->bigBlockChain, $block*4);
-				}
-			}
-		}
-		
-		return $streamData;
-	}
-	
-	/**
-	 * Read a standard stream (by joining sectors using information from SAT)
-	 *
-	 * @param int $bl Sector ID where the stream starts
-	 * @return string Data for standard stream
-	 */
-	private function _readData($block) {
-		$data = '';
-	
-		while ($block != -2) {
-			$pos = ($block + 1) * self::BIG_BLOCK_SIZE;
-			$data .= substr($this->data, $pos, self::BIG_BLOCK_SIZE);
-			$block = self::_GetInt4d($this->bigBlockChain, 4*$block);
-		}
-		return $data;
-	}
-	
-	/**
-	 * Read entries in the directory stream.
-	 */
-	private function _readPropertySets() {
-		$offset = 0;
-	
-		$entryLen = strlen($this->entry);		// loop through entires, each entry is 128 bytes
-		while ($offset < $entryLen) {
-			$data = substr($this->entry, $offset, self::PROPERTY_STORAGE_BLOCK_SIZE);							// entry data (128 bytes)
-			$nameSize = ord($data[self::SIZE_OF_NAME_POS]) | (ord($data[self::SIZE_OF_NAME_POS + 1]) << 8);		// size in bytes of name
-			$name = str_replace("\x00", "", substr($data, 0, $nameSize));
-			$this->props[] = array (
-				'name' 		 =>	 $name,
-				'type' 		 =>	 ord($data[self::TYPE_POS]),			// type of entry
-				'size' 		 =>	 self::_GetInt4d($data, self::SIZE_POS),
-				'startBlock' =>	 self::_GetInt4d($data, self::START_BLOCK_POS)
-			);
-	
-			$upName = strtoupper($name);								// tmp helper to simplify checks
-			if (($upName === 'WORKBOOK') || ($upName === 'BOOK')) {		// Workbook directory entry (BIFF5 uses Book, BIFF8 uses Workbook)
-				$this->workbook = count($this->props) - 1;
-			}
-			else if ( $upName === 'ROOT ENTRY' || $upName === 'R') {
-				$this->rootentry = count($this->props) - 1;				// Root entry
-			}
-			
-			if ($name == chr(5) . 'SummaryInformation') {
-				$this->summaryInformation = count($this->props) - 1;			// Summary information
-			}
-	
-			if ($name == chr(5) . 'DocumentSummaryInformation') {
-				$this->documentSummaryInformation = count($this->props) - 1;	// Additional Document Summary information
-			}
-	
-			$offset += self::PROPERTY_STORAGE_BLOCK_SIZE;
-		}
-	
-	}
-	
-	/**
-	 * Read 4 bytes of data at specified position
-	 * FIX: represent numbers correctly on 64-bit system. Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems
-	 * http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334
-	 * 
-	 * @param string $data
-	 * @param int $pos
-	 * @return int
-	 */
-	private static function _GetInt4d($data, $pos){
-		$_or_24 = ord($data[$pos + 3]);
-		if ($_or_24 >= 128) {
-			$_ord_24 = -abs((256 - $_or_24) << 24);		// negative number
-		} else {
-			$_ord_24 = ($_or_24 & 127) << 24;
-		}
-		return ord($data[$pos]) | (ord($data[$pos + 1]) << 8) | (ord($data[$pos + 2]) << 16) | $_ord_24;
-	}
-}

+ 0 - 205
PHPExcelReader/SpreadsheetReader/SpreadsheetReader_CSV.php

@@ -1,205 +0,0 @@
-<?php
-
-class SpreadsheetReader_CSV implements Iterator, Countable {
-	private $options = array(
-		'Delimiter' => ';',
-		'Enclosure' => '"'
-	);
-	
-	private $encoding = 'UTF-8';
-	private $filePath = '';
-	private $handle = false;
-	private $index = 0;
-	private $currentRow = null;
-	private $rowCount = null;
-	
-	public function __construct($filePath, $options = null, $encoding = '') {
-		if ( ! is_readable($filePath)) {
-			throw new Exception('SpreadsheetReader_CSV: File not readable (' . $filePath . ')');
-		}
-		
-		$this->filePath = $filePath;
-		@ini_set('auto_detect_line_endings', true);
-		$this->options = array_merge($this->options, $options);
-		$encoding && $this->encoding = $encoding;
-		$this->handle = fopen($filePath, 'r');
-		
-		// Checking the file for byte-order mark to determine encoding
-		$BOM16 = bin2hex(fread($this->handle, 2));
-		if ($BOM16 == 'fffe') {
-			$this->Encoding = 'UTF-16LE';
-			$this->BOMLength = 2;
-		}
-		elseif ($BOM16 == 'feff') {
-			$this->Encoding = 'UTF-16BE';
-			$this->BOMLength = 2;
-		}
-		
-		if ( ! $this->BOMLength) {
-			fseek($this->handle, 0);
-			$BOM32 = bin2hex(fread($this->handle, 4));
-			if ($BOM32 == '0000feff') {
-				$this->Encoding = 'UTF-32';
-				$this->BOMLength = 4;
-			}
-			elseif ($BOM32 == 'fffe0000') {
-				$this->Encoding = 'UTF-32';
-				$this->BOMLength = 4;
-			}
-		}
-		
-		fseek($this->handle, 0);
-		$BOM8 = bin2hex(fread($this->handle, 3));
-		if ($BOM8 == 'efbbbf') {
-			$this->Encoding = 'UTF-8';
-			$this->BOMLength = 3;
-		}
-		
-		// Seeking the place right after BOM as the start of the real content
-		if ($this->BOMLength) {
-			fseek($this->handle, $this->BOMLength);
-		}
-		
-		// Checking for the delimiter if it should be determined automatically
-		if ( ! $this->options['Delimiter']) {
-			$Semicolon = ';';		// fgetcsv needs single-byte separators
-			$Tab = "\t";
-			$Comma = ',';
-		
-			// Reading the first row and checking if a specific separator character
-			// has more columns than others (it means that most likely that is the delimiter).
-			$SemicolonCount = count(fgetcsv($this->handle, null, $Semicolon));
-			fseek($this->handle, $this->BOMLength);
-			$TabCount = count(fgetcsv($this->handle, null, $Tab));
-			fseek($this->handle, $this->BOMLength);
-			$CommaCount = count(fgetcsv($this->handle, null, $Comma));
-			fseek($this->handle, $this->BOMLength);
-		
-			$Delimiter = $Semicolon;
-			if ($TabCount > $SemicolonCount || $CommaCount > $SemicolonCount) {
-				$Delimiter = $CommaCount > $TabCount ? $Comma : $Tab;
-			}
-		
-			$this->options['Delimiter'] = $Delimiter;
-		}
-	}
-	
-	/**
-	 * Returns information about sheets in the file.
-	 * @return array
-	 */
-	public function Sheets() {
-		return array(0 => basename($this->filePath));
-	}
-	
-	/**
-	 * Changes sheet to another.
-	 * @param bool
-	 */
-	public function ChangeSheet($index) {
-		if ($index == 0) {
-			$this->rewind();
-			return true;
-		}
-		
-		return false;
-	}
-	
-	/**
-	 * Rewind the Iterator to the first element.
-	 */
-	public function rewind() {
-		fseek($this->handle, 0);
-		$this->currentRow = null;
-		$this->index = 0;
-	}
-	
-	/**
-	 * Return the current element.
-	 * @return mixed
-	 */
-	public function current() {
-		if ($this->index == 0 && is_null($this->currentRow)) {
-			$this->rewind();
-			$this->next();
-			$this->index = 0;
-		}
-		
-		return $this->currentRow;
-	}
-	
-	/**
-	 * Move forward to next element.
-	 */
-	public function next() {
-		$this->currentRow = array();
-
-		if ($this->Encoding == 'UTF-16LE' || $this->Encoding == 'UTF-16BE')	{
-			while ( ! feof($this->handle)) {
-				$Char = ord(fgetc($this->handle));
-				if ( ! $Char || $Char == 10 || $Char == 13)	{
-					continue;												// While bytes are insignificant whitespace, do nothing
-				}
-				else {
-					if ($this->Encoding == 'UTF-16LE') {
-						fseek($this->handle, ftell($this->handle) - 1);		// When significant bytes are found, step back to the last place before them
-					}
-					else {
-						fseek($this->handle, ftell($this->handle) - 2);
-					}
-					break;
-				}
-			}
-		}
-		
-		$this->index++;
-		$this->currentRow = fgetcsv($this->handle, null, $this->options['Delimiter'], $this->options['Enclosure']);
-		if ($this->currentRow) {
-			if ($this->encoding != 'ASCII' && $this->encoding != 'UTF-8') {
-				foreach($this->currentRow as $key => $value) {
-					$this->currentRow[$key] =  trim(trim(
-						mb_convert_encoding($value, 'UTF-8', $this->encoding),
-						$this->options['Enclosure']
-					));
-				}
-			}
-		}
-	
-		return $this->currentRow;
-	}
-	
-	/**
-	 * Return the identifying key of the current element.
-	 * @return mixed
-	 */
-	public function key() {
-		return $this->index;
-	}
-	
-	/**
-	 * Check if there is a current element after calls to rewind() or next().
-	 * @return bool
-	 */
-	public function valid() {
-		return ($this->currentRow || ! feof($this->handle));
-	}
-	
-	/**
-	 * return the count of the contained items
-	 * @return int
-	 */
-	public function count() {
-		if (is_null($this->rowCount)) {
-			$total = 0;
-			
-			fseek($this->handle, 0);
-			while ($row = fgetcsv($this->handle, null, $this->options['Delimiter'], $this->options['Enclosure'])) {
-				$total++;
-			}
-			
-			$this->rowCount = $total;
-		}
-		
-		return $this->rowCount;
-	}
-}

+ 0 - 333
PHPExcelReader/SpreadsheetReader/SpreadsheetReader_ODS.php

@@ -1,333 +0,0 @@
-<?php
-
-class SpreadsheetReader_ODS implements Iterator, Countable {
-	private $Options = array(
-		'TempDir' => '',
-		'ReturnDateTimeObjects' => false
-	);
-
-	/**
-	 * @var string Path to temporary content file
-	 */
-	private $ContentPath = '';
-	/**
-	 * @var XMLReader XML reader object
-	 */
-	private $Content = false;
-
-	/**
-	 * @var array Data about separate sheets in the file
-	 */
-	private $Sheets = false;
-
-	private $CurrentRow = null;
-
-	/**
-	 * @var int Number of the sheet we're currently reading
-	 */
-	private $CurrentSheet = 0;
-
-	private $Index = 0;
-
-	private $TableOpen = false;
-	private $RowOpen = false;
-
-	/**
-	 * @param string Path to file
-	 * @param array Options:
-	 *	TempDir => string Temporary directory path
-	 *	ReturnDateTimeObjects => bool True => dates and times will be returned as PHP DateTime objects, false => as strings
-	 */
-	public function __construct($Filepath, array $Options = null)
-	{
-		if (!is_readable($Filepath))
-		{
-			throw new Exception('SpreadsheetReader_ODS: File not readable ('.$Filepath.')');
-		}
-
-		$this -> TempDir = isset($Options['TempDir']) && is_writable($Options['TempDir']) ?
-			$Options['TempDir'] :
-			sys_get_temp_dir();
-
-		$this -> TempDir = rtrim($this -> TempDir, DIRECTORY_SEPARATOR);
-		$this -> TempDir = $this -> TempDir.DIRECTORY_SEPARATOR.uniqid().DIRECTORY_SEPARATOR;
-
-		$Zip = new ZipArchive;
-		$Status = $Zip -> open($Filepath);
-
-		if ($Status !== true)
-		{
-			throw new Exception('SpreadsheetReader_ODS: File not readable ('.$Filepath.') (Error '.$Status.')');
-		}
-
-		if ($Zip -> locateName('content.xml') !== false)
-		{
-			$Zip -> extractTo($this -> TempDir, 'content.xml');
-			$this -> ContentPath = $this -> TempDir.'content.xml';
-		}
-
-		$Zip -> close();
-
-		if ($this -> ContentPath && is_readable($this -> ContentPath))
-		{
-			$this -> Content = new XMLReader;
-			$this -> Content -> open($this -> ContentPath);
-			$this -> Valid = true;
-		}
-	}
-
-	/**
-	 * Destructor, destroys all that remains (closes and deletes temp files)
-	 */
-	public function __destruct()
-	{
-		if ($this -> Content && $this -> Content instanceof XMLReader)
-		{
-			$this -> Content -> close();
-			unset($this -> Content);
-		}
-		if (file_exists($this -> ContentPath))
-		{
-			@unlink($this -> ContentPath);
-			unset($this -> ContentPath);
-		}
-	}
-
-	/**
-	 * Retrieves an array with information about sheets in the current file
-	 *
-	 * @return array List of sheets (key is sheet index, value is name)
-	 */
-	public function Sheets()
-	{
-		if ($this -> Sheets === false)
-		{
-			$this -> Sheets = array();
-
-			if ($this -> Valid)
-			{
-				$this -> SheetReader = new XMLReader;
-				$this -> SheetReader -> open($this -> ContentPath);
-
-				while ($this -> SheetReader -> read())
-				{
-					if ($this -> SheetReader -> name == 'table:table')
-					{
-						$this -> Sheets[] = $this -> SheetReader -> getAttribute('table:name');
-						$this -> SheetReader -> next();
-					}
-				}
-				
-				$this -> SheetReader -> close();
-			}
-		}
-		return $this -> Sheets;
-	}
-
-	/**
-	 * Changes the current sheet in the file to another
-	 *
-	 * @param int Sheet index
-	 *
-	 * @return bool True if sheet was successfully changed, false otherwise.
-	 */
-	public function ChangeSheet($Index)
-	{
-		$Index = (int)$Index;
-
-		$Sheets = $this -> Sheets();
-		if (isset($Sheets[$Index]))
-		{
-			$this -> CurrentSheet = $Index;
-			$this -> rewind();
-
-			return true;
-		}
-
-		return false;
-	}
-
-	// !Iterator interface methods
-	/** 
-	 * Rewind the Iterator to the first element.
-	 * Similar to the reset() function for arrays in PHP
-	 */ 
-	public function rewind()
-	{
-		if ($this -> Index > 0)
-		{
-			// If the worksheet was already iterated, XML file is reopened.
-			// Otherwise it should be at the beginning anyway
-			$this -> Content -> close();
-			$this -> Content -> open($this -> ContentPath);
-			$this -> Valid = true;
-
-			$this -> TableOpen = false;
-			$this -> RowOpen = false;
-
-			$this -> CurrentRow = null;
-		}
-
-		$this -> Index = 0;
-	}
-
-	/**
-	 * Return the current element.
-	 * Similar to the current() function for arrays in PHP
-	 *
-	 * @return mixed current element from the collection
-	 */
-	public function current()
-	{
-		if ($this -> Index == 0 && is_null($this -> CurrentRow))
-		{
-			$this -> next();
-			$this -> Index--;
-		}
-		return $this -> CurrentRow;
-	}
-
-	/** 
-	 * Move forward to next element. 
-	 * Similar to the next() function for arrays in PHP 
-	 */ 
-	public function next()
-	{
-		$this -> Index++;
-
-		$this -> CurrentRow = array();
-
-		if (!$this -> TableOpen)
-		{
-			$TableCounter = 0;
-			$SkipRead = false;
-
-			while ($this -> Valid = ($SkipRead || $this -> Content -> read()))
-			{
-				if ($SkipRead)
-				{
-					$SkipRead = false;
-				}
-
-				if ($this -> Content -> name == 'table:table' && $this -> Content -> nodeType != XMLReader::END_ELEMENT)
-				{
-					if ($TableCounter == $this -> CurrentSheet)
-					{
-						$this -> TableOpen = true;
-						break;
-					}
-
-					$TableCounter++;
-					$this -> Content -> next();
-					$SkipRead = true;
-				}
-			}
-		}
-
-		if ($this -> TableOpen && !$this -> RowOpen)
-		{
-			while ($this -> Valid = $this -> Content -> read())
-			{
-				switch ($this -> Content -> name)
-				{
-					case 'table:table':
-						$this -> TableOpen = false;
-						$this -> Content -> next('office:document-content');
-						$this -> Valid = false;
-						break 2;
-					case 'table:table-row':
-						if ($this -> Content -> nodeType != XMLReader::END_ELEMENT)
-						{
-							$this -> RowOpen = true;
-							break 2;
-						}
-						break;
-				}
-			}
-		}
-
-		if ($this -> RowOpen)
-		{
-			$LastCellContent = '';
-
-			while ($this -> Valid = $this -> Content -> read())
-			{
-				switch ($this -> Content -> name)
-				{
-					case 'table:table-cell':
-						if ($this -> Content -> nodeType == XMLReader::END_ELEMENT || $this -> Content -> isEmptyElement)
-						{
-							if ($this -> Content -> nodeType == XMLReader::END_ELEMENT)
-							{
-								$CellValue = $LastCellContent;
-							}
-							elseif ($this -> Content -> isEmptyElement)
-							{
-								$LastCellContent = '';
-								$CellValue = $LastCellContent;
-							}
-
-							$this -> CurrentRow[] = $LastCellContent;
-
-							if ($this -> Content -> getAttribute('table:number-columns-repeated') !== null)
-							{                                                                                            
-								$RepeatedColumnCount = $this -> Content -> getAttribute('table:number-columns-repeated');
-								// Checking if larger than one because the value is already added to the row once before
-								if ($RepeatedColumnCount > 1)
-								{
-									$this -> CurrentRow = array_pad($this -> CurrentRow, count($this -> CurrentRow) + $RepeatedColumnCount - 1, $LastCellContent);
-								}
-							}
-						}
-						else
-						{
-							$LastCellContent = '';
-						}
-					case 'text:p':
-						if ($this -> Content -> nodeType != XMLReader::END_ELEMENT)
-						{
-							$LastCellContent = $this -> Content -> readString();
-						}
-						break;
-					case 'table:table-row':
-						$this -> RowOpen = false;
-						break 2;
-				}
-			}
-		}
-
-		return $this -> CurrentRow;
-	}
-
-	/** 
-	 * Return the identifying key of the current element.
-	 * Similar to the key() function for arrays in PHP
-	 *
-	 * @return mixed either an integer or a string
-	 */ 
-	public function key()
-	{
-		return $this -> Index;
-	}
-
-	/** 
-	 * Check if there is a current element after calls to rewind() or next().
-	 * Used to check if we've iterated to the end of the collection
-	 *
-	 * @return boolean FALSE if there's nothing more to iterate over
-	 */ 
-	public function valid()
-	{
-		return $this -> Valid;
-	}
-
-	// !Countable interface method
-	/**
-	 * Ostensibly should return the count of the contained items but this just returns the number
-	 * of rows read so far. It's not really correct but at least coherent.
-	 */
-	public function count()
-	{
-		return $this -> Index + 1;
-	}
-}

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff