PHP read Excel

 
< ?php
/**
 * <?php
 * require "excel_class.php";
 * Read_Excel_File("Book1.xls",$return);
 * for ($i=0;$i<count($return[Sheet1]);$i++)
 * {
 * 	for ($j=0;$j<count($return[Sheet1][$i]);$j++)
 * 	{
 * 		echo $return[Sheet1][$i][$j]."|";
 * 	}
 * 	echo "<br>";
 * }
 * ?>
 * < ?
 * require "excel_class.php";
 * Read_Excel_File("Book1.xls",$return);
 * Create_Excel_File("ddd.xls",$return[Sheet1]);
 * ?>
 */
define('ABC_CRITICAL',      0);
define('ABC_ERROR',         1);
define('ABC_ALERT',         2);
define('ABC_WARNING',       3);
define('ABC_NOTICE',        4);
define('ABC_INFO',          5);
define('ABC_DEBUG',         6);
define('ABC_TRACE',         7);
define('ABC_VAR_DUMP',      8);
define('ABC_NO_LOG',      -1);
$php_version = split( "\.", phpversion() );
if( $php_version[0] == 4 && $php_version[1] < = 1 ) {
	if( !function_exists('var_export') ) {
		function var_export( $exp, $ret ) {
			ob_start();
			var_dump( $exp );
			$result = ob_get_contents();
			ob_end_clean();
			return $result;
		}}}function print_bt()
		{
			print "<code>\n";
			$cs = debug_backtrace();
			for( $i = 1; $i < count($cs) ; $i++ )
			{
				$item = $cs[ $i ];
				for( $j = 0; $j < count($item['args']); $j++ )
				if( is_string($item['args'][$j]) )
				$item['args'][$j] = "\"" . $item['args'][$j] . "\"";
				$args = join(",", $item['args'] );
				if( isset( $item['class'] ) )
				$str = sprintf("%s(%d): %s%s%s(%s)",
				$item['file'],
				$item['line'],
				$item['class'],
				$item['type'],
				$item['function'],
				$args );
				else
				$str = sprintf("%s(%d): %s(%s)",
				$item['file'],
				$item['line'],
				$item['function'],
				$args );
				echo $str . "<br>\n";
			}print "\n";
		}function _die( $str )
		{
			print "Script died with reason: $str<br />\n";
			print_bt();
			exit();
		}class DebugOut
		{
			var $priorities = array(ABC_CRITICAL    => 'critical',
			ABC_ERROR       => 'error',
			ABC_ALERT       => 'alert',
			ABC_WARNING     => 'warning',
			ABC_NOTICE      => 'notice',
			ABC_INFO        => 'info',
			ABC_DEBUG       => 'debug',
			ABC_TRACE       => 'trace',
			ABC_VAR_DUMP        => 'dump'
			);
			var $_ready = false;
			var $_currentPriority = ABC_DEBUG;
			var $_consumers = array();
			var  $_filename;
			var  $_fp;
			var  $_logger_name;
 
			function DebugOut($name, $logger_name, $level ){
				$this->_filename = $name;
				$this->_currentPriority = $level;
				$this->_logger_name = $logger_name;
				if ($level > ABC_NO_LOG){
					$this->_openfile();
				}     /*Destructor Registering*/
				register_shutdown_function(array($this,"close"));
			} function log($message, $priority = ABC_INFO) {
				// Abort early if the priority is above the maximum logging level.
				if ($priority > $this->_currentPriority) {
					return false;
				}        // Add to loglines array
				return $this->_writeLine($message, $priority, strftime('%b %d %H:%M:%S'));
			} function dump($variable,$name) {
				$priority = ABC_VAR_DUMP;
				if ($priority > $this->_currentPriority ) {
					return false;
				}       $time = strftime('%b %d %H:%M:%S');
				$message = var_export($variable,true);
				return fwrite($this->_fp,
				sprintf("%s %s [%s] variable %s = %s \r\n",
				$time,
				$this->_logger_name,
				$this->priorities[$priority],
				$name,
				$message)
				);
			} function info($message) {
				return $this->log($message, ABC_INFO);
			} function debug($message) {
				return $this->log($message, ABC_DEBUG);
			} function notice($message) {
				return $this->log($message, ABC_NOTICE);
			} function warning($message) {
				return $this->log($message, ABC_WARNING);
			} function trace($message) {
				return $this->log($message, ABC_TRACE);
			} function error($message) {
				return $this->log($message, ABC_ERROR);
			} /**
  * Writes a line to the logfile
  *
  * @param  string $line      The line to write
  * @param  integer $priority The priority of this line/msg
  * @return integer           Number of bytes written or -1 on error
  * @access private
  */
			function _writeLine($message, $priority, $time) {
				if( fwrite($this->_fp, sprintf("%s %s [%s] %s\r\n", $time, $this->_logger_name, $this->priorities[$priority], $message)) ) {
					return fflush($this->_fp);
				} else {
					return false;
				} } function _openfile() {
					if (($this->_fp = @fopen($this->_filename, 'a')) == false) {
						return false;
					}        return true;
				} function close(){
					if($this->_currentPriority != ABC_NO_LOG){
						$this->info("Logger stoped");
						return fclose($this->_fp);
					} } /*
					* Managerial Functions.
					*
					*/
					function Factory($name, $logger_name, $level) {
						$instance = new DebugOut($name, $logger_name, $level);
						return $instance;
					} function &getWriterSingleton($name, $logger_name, $level = ABC_DEBUG){
						static $instances;
						if (!isset($instances)){
							$instances = array();
						}      $signature = serialize(array($name, $level));
						if (!isset($instances[$signature])) {
							$instances[$signature] = DebugOut::Factory($name, $logger_name, $level);
						}
						return $instances[$signature];
					} function attach(&$logObserver) {
						if (!is_object($logObserver)) {
							return false;
						}    $logObserver->_listenerID = uniqid(rand());
						$this->_listeners[$logObserver->_listenerID] = &$logObserver;
					}}define ('ABC_BAD_DATE', -1);
					class ExcelDateUtil{
 
						/*
						* return 1900 Date as integer TIMESTAMP.
						* for UNIX date must be
						*
						*/
						function xls2tstamp($date) {
							$date=$date>25568?$date:25569;
							/*There was a bug if Converting date before 1-1-1970 (tstamp 0)*/
							$ofs=(70 * 365 + 17+2) * 86400;
							return ($date * 86400) - $ofs;
						}function getDateArray($xls_date){
							$ret = array();
							// leap year bug
							if ($xls_date == 60) {
								$ret['day']   = 29;
								$ret['month'] = 2;
								$ret['year']  = 1900;
								return $ret;
							} else if ($xls_date < 60) {
								// 29-02-1900 bug
								$xls_date++;
							}    // Modified Julian to DMY calculation with an addition of 2415019
							$l = $xls_date + 68569 + 2415019;
							$n = (int)(( 4 * $l ) / 146097);
							$l = $l - (int)(( 146097 * $n + 3 ) / 4);
							$i = (int)(( 4000 * ( $l + 1 ) ) / 1461001);
							$l = $l - (int)(( 1461 * $i ) / 4) + 31;
							$j = (int)(( 80 * $l ) / 2447);
							$ret['day'] = $l - (int)(( 2447 * $j ) / 80);
							$l = (int)($j / 11);
							$ret['month'] = $j + 2 - ( 12 * $l );
							$ret['year'] = 100 * ( $n - 49 ) + $i + $l;
							return $ret;
						}function isInternalDateFormat($format) {
							$retval =false;
							switch(format) {
								// Internal Date Formats as described on page 427 in
								// Microsoft Excel Dev's Kit...
								case 0x0e:
								case 0x0f:
								case 0x10:
								case 0x11:
								case 0x12:
								case 0x13:
								case 0x14:
								case 0x15:
								case 0x16:
								case 0x2d:
								case 0x2e:
								case 0x2f:
									// Additional internal date formats found by inspection
									// Using Excel v.X 10.1.0 (Mac)
								case 0xa4:
								case 0xa5:
								case 0xa6:
								case 0xa7:
								case 0xa8:
								case 0xa9:
								case 0xaa:
								case 0xab:
								case 0xac:
								case 0xad:
									$retval = true; break;
								default: $retval = false; break;
							}         return $retval;
						}}define('EXCEL_FONT_RID',0x31);
						define('XF_SCRIPT_NONE',0);
						define('XF_SCRIPT_SUPERSCRIPT',1);
						define('XF_SCRIPT_SUBSCRIPT',2);
						define('XF_UNDERLINE_NONE',0x0);
						define('XF_UNDERLINE_SINGLE',0x1);
						define('XF_UNDERLINE_DOUBLE',0x2);
						define('XF_UNDERLINE_SINGLE_ACCOUNTING',0x3);
						define('XF_UNDERLINE_DOUBLE_ACCOUNTING',0x4);
						define('XF_STYLE_ITALIC', 0x2);
						define('XF_STYLE_STRIKEOUT', 0x8);
						define('XF_BOLDNESS_REGULAR',0x190);
						define('XF_BOLDNESS_BOLD',0x2BC);
 
						class ExcelFont {
 
							function basicFontRecord() {
								return  array('size'     => 10,
								'script'   => XF_SCRIPT_NONE,
								'undeline' => XF_UNDERLINE_NONE,
								'italic'   => false,
								'strikeout'=> false,
								'bold'     => false,
								'boldness' => XF_BOLDNESS_REGULAR,
								'palete'   => 0,
								'name'     => 'Arial');
							} function getFontRecord(&$wb,$ptr) {
								$retval = array('size'     => 0,
								'script'   => XF_SCRIPT_NONE,
								'undeline' => XF_UNDERLINE_NONE,
								'italic'   => false,
								'strikeout'=> false,
								'bold'     => false,
								'boldness' => XF_BOLDNESS_REGULAR,
								'palete'   => 0,
								'name'     => '');
								$retval['size'] = (ord($wb[$ptr])+ 256*ord($wb[$ptr+1]))/20;
								$style=ord($wb[$ptr+2]);
								if (($style & XF_STYLE_ITALIC) != 0) {
									$retval['italic'] = true;
								}    if (($style & XF_STYLE_STRIKEOUT) != 0) {
									$retval['strikeout'] = true;
								}    $retval['palete'] = ord($wb[$ptr+4])+256*ord($wb[$ptr+5]);
								$retval['boldness'] = ord($wb[$ptr+6])+256*ord($wb[$ptr+7]);
								$retval['bold'] = $retval['boldness'] == XF_BOLDNESS_REGULAR ? false:true;
								$retval['script'] =  ord($wb[$ptr+8])+256*ord($wb[$ptr+9]);
								$retval['underline'] = ord($wb[$ptr+10]);
								$length = ord($wb[$ptr+14]);
								if($length >0) {
									if(ord($wb[$ptr+15]) == 0) { // Compressed Unicode
										$retval['name'] = substr($wb,$ptr+16,$length);
									} else { // Uncompressed Unicode
										$retval['name'] = ExcelFont::getUnicodeString($wb,$ptr+15,$length);
									}    }    return $retval;
							} function toString(&$record,$index) {
								$retval = sprintf("Font Index = %d \nFont Size =%d\nItalic = %s\nStrikeoout=%s\nPalete=%s\nBoldness = %s Bold=%s\n Script = %d\n Underline = %d\n FontName=%s<hr />",
								$index,
								$record['size'],
								$record['italic']    == true?"true":"false",
								$record['strikeout'] == true?"true":"false",
								$record['palete'],
								$record['boldness'],
								$record['bold'] == true?"true":"false",
								$record['script'],
								$record['underline'],
								$record['name']
								);
								return $retval;
							} function getUnicodeString(&$string,$offset,$length) {
								$bstring = "";
								$index   = $offset + 1;   // start with low bits.
								for ($k = 0; $k < $length; $k++)
								{
									$bstring = $bstring.$string[$index];
									$index        += 2;
								}        return substr($bstring,0,$length);
							} function ExcelToCSS($rec, $app_font=true, $app_size=true, $app_italic=true, $app_bold=true){
								$ret = "";
								if($app_font==true){
									$ret = $ret."font-family:".$rec['name']."; ";
								}    if($app_size==true){
									$ret = $ret."font-size:".$rec['size']."pt; ";
								}    if($app_bold==true){
									if($rec['bold']==true){
										$ret = $ret."font-weight:bold; ";
									} else {
										$ret = $ret."font-weight:normal; ";
									}    }    if($app_italic==true){
										if($rec['italic']==true){
											$ret = $ret."font-style:italic; ";
										} else {
											$ret = $ret."font-style:normal; ";
										}    }    return $ret;
							}}define ( DP_EMPTY, 0 );
							define ( DP_STRING_SOURCE, 1 );
							define ( DP_FILE_SOURCE, 2 );
							//------------------------------------------------------------------------
							class ExcelParserUtil
							{
								function str2long($str) {
									return ord($str[0]) + 256*(ord($str[1]) +
									256*(ord($str[2]) + 256*(ord($str[3])) ));
								}}//------------------------------------------------------------------------
								class DataProvider
								{
									function DataProvider( $data, $dataType )
									{
										switch( $dataType )
										{
											case DP_FILE_SOURCE:
												if( !( $this->_data = @fopen( $data, "rb" )) )
												return;
												$this->_size = @filesize( $data );
												if( !$this->_size )
												_die("Failed to determine file size.");
												break;
											case DP_STRING_SOURCE:
												$this->_data = $data;
												$this->_size = strlen( $data );
												break;
											default:
												_die("Invalid data type provided.");
										}$this->_type = $dataType;
										register_shutdown_function( array( $this, "close") );
									}function get( $offset, $length )
									{
										if( !$this->isValid() )
										_die("Data provider is empty.");
										if( $this->_baseOfs + $offset + $length > $this->_size )
										_die("Invalid offset/length.");
										switch( $this->_type )
										{
											case DP_FILE_SOURCE:
												{
													if( @fseek( $this->_data, $this->_baseOfs + $offset, SEEK_SET ) == -1 )
													_die("Failed to seek file position specified by offest.");
													return @fread( $this->_data, $length );
												}case DP_STRING_SOURCE:
												{
													$rc = substr( $this->_data, $this->_baseOfs + $offset, $length );
													return $rc;
												}default:
												_die("Invalid data type or class was not initialized.");
										}}function getByte( $offset )
										{
											return $this->get( $offset, 1 );
										}function getOrd( $offset )
										{
											return ord( $this->getByte( $offset ) );
										}function getLong( $offset )
										{
											$str = $this->get( $offset, 4 );
											return ExcelParserUtil::str2long( $str );
										}function getSize()
										{
											if( !$this->isValid() )
											_die("Data provider is empty.");
											return $this->_size;
										}function getBlocks()
										{
											if( !$this->isValid() )
											_die("Data provider is empty.");
											return (int)(($this->_size - 1) / 0x200) - 1;
										}function ReadFromFat( $chain, $gran = 0x200 )
										{
											$rc = '';
											for( $i = 0; $i < count($chain); $i++ )
											$rc .= $this->get( $chain[$i] * $gran, $gran );
											return $rc;
										}function close()
										{
											switch($this->_type )
											{
												case DP_FILE_SOURCE:
													@fclose( $this->_data );
												case DP_STRING_SOURCE:
													$this->_data = null;
												default:
													$_type = DP_EMPTY;
													break;
											}}function isValid()
											{
												return $this->_type != DP_EMPTY;
											}var $_type = DP_EMPTY;
											var $_data = null;
											var $_size = -1;
											var $_baseOfs = 0;
								}class ExcelFileParser {
									var $dp = null;
									var $max_blocks;
									var $max_sblocks;
									// Internal variables
									var $fat;
									var $sfat;
									// Removed: var $sbd;
									// Removed: var $syear;
									var $formats;
									var $xf;
									var $fonts;
									var $dbglog;
 
									function ExcelFileParser($logfile="",$level=ABC_NO_LOG) {
										$this->dbglog = &DebugOut::getWriterSingleton($logfile,"",$level);
										$this->dbglog->info("Logger started");
									}function populateFormat() {
										$this->dbglog->trace(" populateFormat() function call");
										$ret = array (
										0=> "General",
										1=> "0",
										2=> "0.00",
										3=> "#,##0",
										4=> "#,##0.00",
										5=> "($#,##0_);($#,##0)",
										6=> "($#,##0_);[Red]($#,##0)",
										7=> "($#,##0.00);($#,##0.00)",
										8=> "($#,##0.00_);[Red]($#,##0.00)",
										9=> "0%",
										0xa=> "0.00%",
										0xb=> "0.00E+00",
										0xc=> "# ?/?",
										0xd=> "# ??/??",
										0xe=> "m/d/yy",
										0xf=> "d-mmm-yy",
										0x10=> "d-mmm",
										0x11=> "mmm-yy",
										0x12=> "h:mm AM/PM",
										0x13=> "h:mm:ss AM/PM",
										0x14=> "h:mm",
										0x15=> "h:mm:ss",
										0x16=> "m/d/yy h:mm",
										// 0x17 - 0x24 reserved for international and undocumented
										0x17=> "0x17",
										0x18=> "0x18",
										0x19=> "0x19",
										0x1a=> "0x1a",
										0x1b=> "0x1b",
										0x1c=> "0x1c",
										0x1d=> "0x1d",
										0x1e=> "0x1e",
										0x1f=> "0x1f",
										0x20=> "0x20",
										0x21=> "0x21",
										0x22=> "0x22",
										0x23=> "0x23",
										0x24=> "0x24",
										// 0x17 - 0x24 reserved for international and undocumented
										0x25=> "(#,##0_);(#,##0)",
										0x26=> "(#,##0_);[Red](#,##0)",
										0x27=> "(#,##0.00_);(#,##0.00)",
										0x28=> "(#,##0.00_);[Red](#,##0.00)",
										0x29=> "_(*#,##0_);_(*(#,##0);_(* \"-\"_);_(@_)",
										0x2a=> "_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)",
										0x2b=> "_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)",
										0x2c=> "_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)",
										0x2d=> "mm:ss",
										0x2e=> "[h]:mm:ss",
										0x2f=> "mm:ss.0",
										0x30=> "##0.0E+0",
										0x31=> "@");
										$this->dbglog->dump($ret,"\$ret");
										$this->dbglog->trace("populateFormat() function return");
										return $ret;
									}function xls2tstamp($date) {
										$date=$date>25568?$date:25569;
										/*There was a bug if Converting date before 1-1-1970 (tstamp 0)*/
										$ofs=(70 * 365 + 17+2) * 86400;
										return ($date * 86400) - $ofs;
									}function getDateArray($date) {
										return ExcelDateUtil::getDateArray($date);
									}function isDateFormat($val){
										$f_i=$this->xf['format'][$val];
										if(preg_match("/[m|d|y]/i",$this->format[$f_i])!=0){
											if(strrpos($this->format[$f_i],'[')!=FALSE) {
												$tmp = preg_replace("/(\[\/?)(\w+)([^\]]*\])/","'