php 将excel导入mysql


Posted in PHP onNovember 09, 2009

这里介绍一个直接将excel文件导入mysql的例子。我花了一晚上的时间测试,无论导入简繁体都不会出现乱码,非常好用。
PHP-ExcelReader,下载地址: http://sourceforge.net/projects/phpexcelreader
说明:
测试环境:MYSQL数据库采用utf8编码.导入EXCEL文档是xls格式,经过测试,xlsx 格式[excel 2007]也OK.
文中红色标注为需要注意的地方,请替换成你配置好的数据,如数据库配置等。运行http://localost/test.php实现导入。
以下是我贴出的详细代码,其中test.php为我写的测试文件,reader.php和oleread.inc文件是从上面提供的网址中下载的。
1. test.php

require_once './includes/reader.php'; 
// ExcelFile($filename, $encoding); 
$data = new Spreadsheet_Excel_Reader(); 
// Set output Encoding. 
$data->setOutputEncoding('gbk'); 
//”data.xls”是指要导入到mysql中的excel文件 
$data->read('date.xls'); 
@ $db = mysql_connect('localhost', 'root', '1234') or 
die("Could not connect to database.");//连接数据库 
mysql_query("set names 'gbk'");//输出中文 
mysql_select_db('wenhuaedu'); //选择数据库 
error_reporting(E_ALL ^ E_NOTICE); 
for ($i = 1; $i <= $data->sheets[0]['numRows']; $i++) { 
//以下注释的for循环打印excel表数据 
/* 
for ($j = 1; $j <= $data->sheets[0]['numCols']; $j++) { 
echo """.$data->sheets[0]['cells'][$i][$j]."","; 
} 
echo "n"; 
*/ 
//以下代码是将excel表数据【3个字段】插入到mysql中,根据你的excel表字段的多少,改写以下代码吧! 
$sql = "INSERT INTO test VALUES('". 
$data->sheets[0]['cells'][$i][1]."','". 
$data->sheets[0]['cells'][$i][2]."','". 
$data->sheets[0]['cells'][$i][3]."')"; 
echo $sql.'<br />'; 
$res = mysql_query($sql);

贴出其中包含的文件
OLERead.php
<?php 
define('NUM_BIG_BLOCK_DEPOT_BLOCKS_POS', 0x2c); 
define('SMALL_BLOCK_DEPOT_BLOCK_POS', 0x3c); 
define('ROOT_START_BLOCK_POS', 0x30); 
define('BIG_BLOCK_SIZE', 0x200); 
define('SMALL_BLOCK_SIZE', 0x40); 
define('EXTENSION_BLOCK_POS', 0x44); 
define('NUM_EXTENSION_BLOCK_POS', 0x48); 
define('PROPERTY_STORAGE_BLOCK_SIZE', 0x80); 
define('BIG_BLOCK_DEPOT_BLOCKS_POS', 0x4c); 
define('SMALL_BLOCK_THRESHOLD', 0x1000); 
// property storage offsets 
define('SIZE_OF_NAME_POS', 0x40); 
define('TYPE_POS', 0x42); 
define('START_BLOCK_POS', 0x74); 
define('SIZE_POS', 0x78); 
define('IDENTIFIER_OLE', pack("CCCCCCCC",0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1)); 
//echo 'ROOT_START_BLOCK_POS = '.ROOT_START_BLOCK_POS."\n"; 
//echo bin2hex($data[ROOT_START_BLOCK_POS])."\n"; 
//echo "a="; 
//echo $data[ROOT_START_BLOCK_POS]; 
//function log 
function GetInt4d($data, $pos) 
{ 
$value = ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | (ord($data[$pos+3]) << 24); 
if ($value>=4294967294) 
{ 
$value=-2; 
} 
return $value; 
} 
class OLERead { 
var $data = ''; 
function OLERead(){ 
} 
function read($sFileName){ 
// check if file exist and is readable (Darko Miljanovic) 
if(!is_readable($sFileName)) { 
$this->error = 1; 
return false; 
} 
$this->data = @file_get_contents($sFileName); 
if (!$this->data) { 
$this->error = 1; 
return false; 
} 
//echo IDENTIFIER_OLE; 
//echo 'start'; 
if (substr($this->data, 0, 8) != IDENTIFIER_OLE) { 
$this->error = 1; 
return false; 
} 
$this->numBigBlockDepotBlocks = GetInt4d($this->data, NUM_BIG_BLOCK_DEPOT_BLOCKS_POS); 
$this->sbdStartBlock = GetInt4d($this->data, SMALL_BLOCK_DEPOT_BLOCK_POS); 
$this->rootStartBlock = GetInt4d($this->data, ROOT_START_BLOCK_POS); 
$this->extensionBlock = GetInt4d($this->data, EXTENSION_BLOCK_POS); 
$this->numExtensionBlocks = GetInt4d($this->data, NUM_EXTENSION_BLOCK_POS); 
/* 
echo $this->numBigBlockDepotBlocks." "; 
echo $this->sbdStartBlock." "; 
echo $this->rootStartBlock." "; 
echo $this->extensionBlock." "; 
echo $this->numExtensionBlocks." "; 
*/ 
//echo "sbdStartBlock = $this->sbdStartBlock\n"; 
$bigBlockDepotBlocks = array(); 
$pos = BIG_BLOCK_DEPOT_BLOCKS_POS; 
// echo "pos = $pos"; 
$bbdBlocks = $this->numBigBlockDepotBlocks; 
if ($this->numExtensionBlocks != 0) { 
$bbdBlocks = (BIG_BLOCK_SIZE - BIG_BLOCK_DEPOT_BLOCKS_POS)/4; 
} 
for ($i = 0; $i < $bbdBlocks; $i++) { 
$bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos); 
$pos += 4; 
} 
for ($j = 0; $j < $this->numExtensionBlocks; $j++) { 
$pos = ($this->extensionBlock + 1) * BIG_BLOCK_SIZE; 
$blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, BIG_BLOCK_SIZE / 4 - 1); 
for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; $i++) { 
$bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos); 
$pos += 4; 
} 
$bbdBlocks += $blocksToRead; 
if ($bbdBlocks < $this->numBigBlockDepotBlocks) { 
$this->extensionBlock = GetInt4d($this->data, $pos); 
} 
} 
// var_dump($bigBlockDepotBlocks); 
// readBigBlockDepot 
$pos = 0; 
$index = 0; 
$this->bigBlockChain = array(); 
for ($i = 0; $i < $this->numBigBlockDepotBlocks; $i++) { 
$pos = ($bigBlockDepotBlocks[$i] + 1) * BIG_BLOCK_SIZE; 
//echo "pos = $pos"; 
for ($j = 0 ; $j < BIG_BLOCK_SIZE / 4; $j++) { 
$this->bigBlockChain[$index] = GetInt4d($this->data, $pos); 
$pos += 4 ; 
$index++; 
} 
} 
//var_dump($this->bigBlockChain); 
//echo '=====2'; 
// readSmallBlockDepot(); 
$pos = 0; 
$index = 0; 
$sbdBlock = $this->sbdStartBlock; 
$this->smallBlockChain = array(); 
while ($sbdBlock != -2) { 
$pos = ($sbdBlock + 1) * BIG_BLOCK_SIZE; 
for ($j = 0; $j < BIG_BLOCK_SIZE / 4; $j++) { 
$this->smallBlockChain[$index] = GetInt4d($this->data, $pos); 
$pos += 4; 
$index++; 
} 
$sbdBlock = $this->bigBlockChain[$sbdBlock]; 
} 
// readData(rootStartBlock) 
$block = $this->rootStartBlock; 
$pos = 0; 
$this->entry = $this->__readData($block); 
/* 
while ($block != -2) { 
$pos = ($block + 1) * BIG_BLOCK_SIZE; 
$this->entry = $this->entry.substr($this->data, $pos, BIG_BLOCK_SIZE); 
$block = $this->bigBlockChain[$block]; 
} 
*/ 
//echo '==='.$this->entry."==="; 
$this->__readPropertySets(); 
} 
function __readData($bl) { 
$block = $bl; 
$pos = 0; 
$data = ''; 
while ($block != -2) { 
$pos = ($block + 1) * BIG_BLOCK_SIZE; 
$data = $data.substr($this->data, $pos, BIG_BLOCK_SIZE); 
//echo "pos = $pos data=$data\n"; 
$block = $this->bigBlockChain[$block]; 
} 
return $data; 
} 
function __readPropertySets(){ 
$offset = 0; 
//var_dump($this->entry); 
while ($offset < strlen($this->entry)) { 
$d = substr($this->entry, $offset, PROPERTY_STORAGE_BLOCK_SIZE); 
$nameSize = ord($d[SIZE_OF_NAME_POS]) | (ord($d[SIZE_OF_NAME_POS+1]) << 8); 
$type = ord($d[TYPE_POS]); 
//$maxBlock = strlen($d) / BIG_BLOCK_SIZE - 1; 
$startBlock = GetInt4d($d, START_BLOCK_POS); 
$size = GetInt4d($d, SIZE_POS); 
$name = ''; 
for ($i = 0; $i < $nameSize ; $i++) { 
$name .= $d[$i]; 
} 
$name = str_replace("\x00", "", $name); 
$this->props[] = array ( 
'name' => $name, 
'type' => $type, 
'startBlock' => $startBlock, 
'size' => $size); 
if (($name == "Workbook") || ($name == "Book")) { 
$this->wrkbook = count($this->props) - 1; 
} 
if ($name == "Root Entry") { 
$this->rootentry = count($this->props) - 1; 
} 
//echo "name ==$name=\n"; 
$offset += PROPERTY_STORAGE_BLOCK_SIZE; 
} 
} 
function getWorkBook(){ 
if ($this->props[$this->wrkbook]['size'] < SMALL_BLOCK_THRESHOLD){ 
// getSmallBlockStream(PropertyStorage ps) 
$rootdata = $this->__readData($this->props[$this->rootentry]['startBlock']); 
$streamData = ''; 
$block = $this->props[$this->wrkbook]['startBlock']; 
//$count = 0; 
$pos = 0; 
while ($block != -2) { 
$pos = $block * SMALL_BLOCK_SIZE; 
$streamData .= substr($rootdata, $pos, SMALL_BLOCK_SIZE); 
$block = $this->smallBlockChain[$block]; 
} 
return $streamData; 
}else{ 
$numBlocks = $this->props[$this->wrkbook]['size'] / BIG_BLOCK_SIZE; 
if ($this->props[$this->wrkbook]['size'] % BIG_BLOCK_SIZE != 0) { 
$numBlocks++; 
} 
if ($numBlocks == 0) return ''; 
//echo "numBlocks = $numBlocks\n"; 
//byte[] streamData = new byte[numBlocks * BIG_BLOCK_SIZE]; 
//print_r($this->wrkbook); 
$streamData = ''; 
$block = $this->props[$this->wrkbook]['startBlock']; 
//$count = 0; 
$pos = 0; 
//echo "block = $block"; 
while ($block != -2) { 
$pos = ($block + 1) * BIG_BLOCK_SIZE; 
$streamData .= substr($this->data, $pos, BIG_BLOCK_SIZE); 
$block = $this->bigBlockChain[$block]; 
} 
//echo 'stream'.$streamData; 
return $streamData; 
} 
} 
} 
?>

还有一个
reader.php
<?php 
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 
/** 
* A class for reading Microsoft Excel Spreadsheets. 
* 
* Originally developed by Vadim Tkachenko under the name PHPExcelReader. 
* (http://sourceforge.net/projects/phpexcelreader) 
* Based on the Java version by Andy Khan (http://www.andykhan.com). Now 
* maintained by David Sanders. Reads only Biff 7 and Biff 8 formats. 
* 
* PHP versions 4 and 5 
* 
* LICENSE: This source file is subject to version 3.0 of the PHP license 
* that is available through the world-wide-web at the following URI: 
* http://www.php.net/license/3_0.txt. If you did not receive a copy of 
* the PHP License and are unable to obtain it through the web, please 
* send a note to license@php.net so we can mail you a copy immediately. 
* 
* @category Spreadsheet 
* @package Spreadsheet_Excel_Reader 
* @author Vadim Tkachenko <vt@apachephp.com> 
* @license http://www.php.net/license/3_0.txt PHP License 3.0 
* @version CVS: $Id: reader.php 19 2007-03-13 12:42:41Z shangxiao $ 
* @link http://pear.php.net/package/Spreadsheet_Excel_Reader 
* @see OLE, Spreadsheet_Excel_Writer 
*/ 
//require_once 'PEAR.php'; 
require_once 'OLERead.php'; 
//require_once 'OLE.php'; 
define('SPREADSHEET_EXCEL_READER_BIFF8', 0x600); 
define('SPREADSHEET_EXCEL_READER_BIFF7', 0x500); 
define('SPREADSHEET_EXCEL_READER_WORKBOOKGLOBALS', 0x5); 
define('SPREADSHEET_EXCEL_READER_WORKSHEET', 0x10); 
define('SPREADSHEET_EXCEL_READER_TYPE_BOF', 0x809); 
define('SPREADSHEET_EXCEL_READER_TYPE_EOF', 0x0a); 
define('SPREADSHEET_EXCEL_READER_TYPE_BOUNDSHEET', 0x85); 
define('SPREADSHEET_EXCEL_READER_TYPE_DIMENSION', 0x200); 
define('SPREADSHEET_EXCEL_READER_TYPE_ROW', 0x208); 
define('SPREADSHEET_EXCEL_READER_TYPE_DBCELL', 0xd7); 
define('SPREADSHEET_EXCEL_READER_TYPE_FILEPASS', 0x2f); 
define('SPREADSHEET_EXCEL_READER_TYPE_NOTE', 0x1c); 
define('SPREADSHEET_EXCEL_READER_TYPE_TXO', 0x1b6); 
define('SPREADSHEET_EXCEL_READER_TYPE_RK', 0x7e); 
define('SPREADSHEET_EXCEL_READER_TYPE_RK2', 0x27e); 
define('SPREADSHEET_EXCEL_READER_TYPE_MULRK', 0xbd); 
define('SPREADSHEET_EXCEL_READER_TYPE_MULBLANK', 0xbe); 
define('SPREADSHEET_EXCEL_READER_TYPE_INDEX', 0x20b); 
define('SPREADSHEET_EXCEL_READER_TYPE_SST', 0xfc); 
define('SPREADSHEET_EXCEL_READER_TYPE_EXTSST', 0xff); 
define('SPREADSHEET_EXCEL_READER_TYPE_CONTINUE', 0x3c); 
define('SPREADSHEET_EXCEL_READER_TYPE_LABEL', 0x204); 
define('SPREADSHEET_EXCEL_READER_TYPE_LABELSST', 0xfd); 
define('SPREADSHEET_EXCEL_READER_TYPE_NUMBER', 0x203); 
define('SPREADSHEET_EXCEL_READER_TYPE_NAME', 0x18); 
define('SPREADSHEET_EXCEL_READER_TYPE_ARRAY', 0x221); 
define('SPREADSHEET_EXCEL_READER_TYPE_STRING', 0x207); 
define('SPREADSHEET_EXCEL_READER_TYPE_FORMULA', 0x406); 
define('SPREADSHEET_EXCEL_READER_TYPE_FORMULA2', 0x6); 
define('SPREADSHEET_EXCEL_READER_TYPE_FORMAT', 0x41e); 
define('SPREADSHEET_EXCEL_READER_TYPE_XF', 0xe0); 
define('SPREADSHEET_EXCEL_READER_TYPE_BOOLERR', 0x205); 
define('SPREADSHEET_EXCEL_READER_TYPE_UNKNOWN', 0xffff); 
define('SPREADSHEET_EXCEL_READER_TYPE_NINETEENFOUR', 0x22); 
define('SPREADSHEET_EXCEL_READER_TYPE_MERGEDCELLS', 0xE5); 
define('SPREADSHEET_EXCEL_READER_UTCOFFSETDAYS' , 25569); 
define('SPREADSHEET_EXCEL_READER_UTCOFFSETDAYS1904', 24107); 
define('SPREADSHEET_EXCEL_READER_MSINADAY', 86400); 
//define('SPREADSHEET_EXCEL_READER_MSINADAY', 24 * 60 * 60); 
//define('SPREADSHEET_EXCEL_READER_DEF_NUM_FORMAT', "%.2f"); 
define('SPREADSHEET_EXCEL_READER_DEF_NUM_FORMAT', "%s"); 
/* 
* Place includes, constant defines and $_GLOBAL settings here. 
* Make sure they have appropriate docblocks to avoid phpDocumentor 
* construing they are documented by the page-level docblock. 
*/ 
/** 
* A class for reading Microsoft Excel Spreadsheets. 
* 
* Originally developed by Vadim Tkachenko under the name PHPExcelReader. 
* (http://sourceforge.net/projects/phpexcelreader) 
* Based on the Java version by Andy Khan (http://www.andykhan.com). Now 
* maintained by David Sanders. Reads only Biff 7 and Biff 8 formats. 
* 
* @category Spreadsheet 
* @package Spreadsheet_Excel_Reader 
* @author Vadim Tkachenko <vt@phpapache.com> 
* @copyright 1997-2005 The PHP Group 
* @license http://www.php.net/license/3_0.txt PHP License 3.0 
* @version Release: @package_version@ 
* @link http://pear.php.net/package/PackageName 
* @see OLE, Spreadsheet_Excel_Writer 
*/ 
class Spreadsheet_Excel_Reader 
{ 
/** 
* Array of worksheets found 
* 
* @var array 
* @access public 
*/ 
var $boundsheets = array(); 
/** 
* Array of format records found 
* 
* @var array 
* @access public 
*/ 
var $formatRecords = array(); 
/** 
* todo 
* 
* @var array 
* @access public 
*/ 
var $sst = array(); 
/** 
* Array of worksheets 
* 
* The data is stored in 'cells' and the meta-data is stored in an array 
* called 'cellsInfo' 
* 
* Example: 
* 
* $sheets --> 'cells' --> row --> column --> Interpreted value 
* --> 'cellsInfo' --> row --> column --> 'type' - Can be 'date', 'number', or 'unknown' 
* --> 'raw' - The raw data that Excel stores for that data cell 
* 
* @var array 
* @access public 
*/ 
var $sheets = array(); 
/** 
* The data returned by OLE 
* 
* @var string 
* @access public 
*/ 
var $data; 
/** 
* OLE object for reading the file 
* 
* @var OLE object 
* @access private 
*/ 
var $_ole; 
/** 
* Default encoding 
* 
* @var string 
* @access private 
*/ 
var $_defaultEncoding; 
/** 
* Default number format 
* 
* @var integer 
* @access private 
*/ 
var $_defaultFormat = SPREADSHEET_EXCEL_READER_DEF_NUM_FORMAT; 
/** 
* todo 
* List of formats to use for each column 
* 
* @var array 
* @access private 
*/ 
var $_columnsFormat = array(); 
/** 
* todo 
* 
* @var integer 
* @access private 
*/ 
var $_rowoffset = 1; 
/** 
* todo 
* 
* @var integer 
* @access private 
*/ 
var $_coloffset = 1; 
/** 
* List of default date formats used by Excel 
* 
* @var array 
* @access public 
*/ 
var $dateFormats = array ( 
0xe => "d/m/Y", 
0xf => "d-M-Y", 
0x10 => "d-M", 
0x11 => "M-Y", 
0x12 => "h:i a", 
0x13 => "h:i:s a", 
0x14 => "H:i", 
0x15 => "H:i:s", 
0x16 => "d/m/Y H:i", 
0x2d => "i:s", 
0x2e => "H:i:s", 
0x2f => "i:s.S"); 
/** 
* Default number formats used by Excel 
* 
* @var array 
* @access public 
*/ 
var $numberFormats = array( 
0x1 => "%1.0f", // "0" 
0x2 => "%1.2f", // "0.00", 
0x3 => "%1.0f", //"#,##0", 
0x4 => "%1.2f", //"#,##0.00", 
0x5 => "%1.0f", /*"$#,##0;($#,##0)",*/ 
0x6 => '$%1.0f', /*"$#,##0;($#,##0)",*/ 
0x7 => '$%1.2f', //"$#,##0.00;($#,##0.00)", 
0x8 => '$%1.2f', //"$#,##0.00;($#,##0.00)", 
0x9 => '%1.0f%%', // "0%" 
0xa => '%1.2f%%', // "0.00%" 
0xb => '%1.2f', // 0.00E00", 
0x25 => '%1.0f', // "#,##0;(#,##0)", 
0x26 => '%1.0f', //"#,##0;(#,##0)", 
0x27 => '%1.2f', //"#,##0.00;(#,##0.00)", 
0x28 => '%1.2f', //"#,##0.00;(#,##0.00)", 
0x29 => '%1.0f', //"#,##0;(#,##0)", 
0x2a => '$%1.0f', //"$#,##0;($#,##0)", 
0x2b => '%1.2f', //"#,##0.00;(#,##0.00)", 
0x2c => '$%1.2f', //"$#,##0.00;($#,##0.00)", 
0x30 => '%1.0f'); //"##0.0E0"; 
// }}} 
// {{{ Spreadsheet_Excel_Reader() 
/** 
* Constructor 
* 
* Some basic initialisation 
*/ 
function Spreadsheet_Excel_Reader() 
{ 
@$this->_ole =& new OLERead(); 
@$this->setUTFEncoder('iconv'); 
} 
// }}} 
// {{{ setOutputEncoding() 
/** 
* Set the encoding method 
* 
* @param string Encoding to use 
* @access public 
*/ 
function setOutputEncoding($encoding) 
{ 
$this->_defaultEncoding = $encoding; 
} 
// }}} 
// {{{ setUTFEncoder() 
/** 
* $encoder = 'iconv' or 'mb' 
* set iconv if you would like use 'iconv' for encode UTF-16LE to your encoding 
* set mb if you would like use 'mb_convert_encoding' for encode UTF-16LE to your encoding 
* 
* @access public 
* @param string Encoding type to use. Either 'iconv' or 'mb' 
*/ 
function setUTFEncoder($encoder = 'iconv') 
{ 
$this->_encoderFunction = ''; 
if ($encoder == 'iconv') { 
$this->_encoderFunction = function_exists('iconv') ? 'iconv' : ''; 
} elseif ($encoder == 'mb') { 
$this->_encoderFunction = function_exists('mb_convert_encoding') ? 
'mb_convert_encoding' : 
''; 
} 
} 
// }}} 
// {{{ setRowColOffset() 
/** 
* todo 
* 
* @access public 
* @param offset 
*/ 
function setRowColOffset($iOffset) 
{ 
$this->_rowoffset = $iOffset; 
$this->_coloffset = $iOffset; 
} 
// }}} 
// {{{ setDefaultFormat() 
/** 
* Set the default number format 
* 
* @access public 
* @param Default format 
*/ 
function setDefaultFormat($sFormat) 
{ 
$this->_defaultFormat = $sFormat; 
} 
// }}} 
// {{{ setColumnFormat() 
/** 
* Force a column to use a certain format 
* 
* @access public 
* @param integer Column number 
* @param string Format 
*/ 
function setColumnFormat($column, $sFormat) 
{ 
$this->_columnsFormat[$column] = $sFormat; 
} 
// }}} 
// {{{ read() 
/** 
* Read the spreadsheet file using OLE, then parse 
* 
* @access public 
* @param filename 
* @todo return a valid value 
*/ 
function read($sFileName) 
{ 
/* 
require_once 'OLE.php'; 
$ole = new OLE(); 
$ole->read($sFileName); 
foreach ($ole->_list as $i => $pps) { 
if (($pps->Name == 'Workbook' || $pps->Name == 'Book') && 
$pps->Size >= SMALL_BLOCK_THRESHOLD) { 
$this->data = $ole->getData($i, 0, $ole->getDataLength($i)); 
} elseif ($pps->Name == 'Root Entry') { 
$this->data = $ole->getData($i, 0, $ole->getDataLength($i)); 
} 
//var_dump(strlen($ole->getData($i, 0, $ole->getDataLength($i))), $pps->Name, md5($this->data), $ole->getDataLength($i)); 
} 
//exit; 
$this->_parse(); 
return sizeof($this->sheets) > 0; 
*/ 
$res = $this->_ole->read($sFileName); 
// oops, something goes wrong (Darko Miljanovic) 
if($res === false) { 
// check error code 
if($this->_ole->error == 1) { 
// bad file 
die('The filename ' . $sFileName . ' is not readable'); 
} 
// check other error codes here (eg bad fileformat, etc) 
} 
$this->data = $this->_ole->getWorkBook(); 
/* 
$res = $this->_ole->read($sFileName); 
if ($this->isError($res)) { 
// var_dump($res); 
return $this->raiseError($res); 
} 
$total = $this->_ole->ppsTotal(); 
for ($i = 0; $i < $total; $i++) { 
if ($this->_ole->isFile($i)) { 
$type = unpack("v", $this->_ole->getData($i, 0, 2)); 
if ($type[''] == 0x0809) { // check if it's a BIFF stream 
$this->_index = $i; 
$this->data = $this->_ole->getData($i, 0, $this->_ole->getDataLength($i)); 
break; 
} 
} 
} 
if ($this->_index === null) { 
return $this->raiseError("$file doesn't seem to be an Excel file"); 
} 
*/ 
//echo "data =".$this->data; 
//$this->readRecords(); 
$this->_parse(); 
} 
// }}} 
// {{{ _parse() 
/** 
* Parse a workbook 
* 
* @access private 
* @return bool 
*/ 
function _parse() 
{ 
$pos = 0; 
$code = ord($this->data[$pos]) | ord($this->data[$pos+1])<<8; 
$length = ord($this->data[$pos+2]) | ord($this->data[$pos+3])<<8; 
$version = ord($this->data[$pos + 4]) | ord($this->data[$pos + 5])<<8; 
$substreamType = ord($this->data[$pos + 6]) | ord($this->data[$pos + 7])<<8; 
//echo "Start parse code=".base_convert($code,10,16)." version=".base_convert($version,10,16)." substreamType=".base_convert($substreamType,10,16).""."\n"; 
if (($version != SPREADSHEET_EXCEL_READER_BIFF8) && 
($version != SPREADSHEET_EXCEL_READER_BIFF7)) { 
return false; 
} 
if ($substreamType != SPREADSHEET_EXCEL_READER_WORKBOOKGLOBALS){ 
return false; 
} 
//print_r($rec); 
$pos += $length + 4; 
$code = ord($this->data[$pos]) | ord($this->data[$pos+1])<<8; 
$length = ord($this->data[$pos+2]) | ord($this->data[$pos+3])<<8; 
while ($code != SPREADSHEET_EXCEL_READER_TYPE_EOF) { 
switch ($code) { 
case SPREADSHEET_EXCEL_READER_TYPE_SST: 
//echo "Type_SST\n"; 
$spos = $pos + 4; 
$limitpos = $spos + $length; 
$uniqueStrings = $this->_GetInt4d($this->data, $spos+4); 
$spos += 8; 
for ($i = 0; $i < $uniqueStrings; $i++) { 
// Read in the number of characters 
if ($spos == $limitpos) { 
$opcode = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8; 
$conlength = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8; 
if ($opcode != 0x3c) { 
return -1; 
} 
$spos += 4; 
$limitpos = $spos + $conlength; 
} 
$numChars = ord($this->data[$spos]) | (ord($this->data[$spos+1]) << 8); 
//echo "i = $i pos = $pos numChars = $numChars "; 
$spos += 2; 
$optionFlags = ord($this->data[$spos]); 
$spos++; 
$asciiEncoding = (($optionFlags & 0x01) == 0) ; 
$extendedString = ( ($optionFlags & 0x04) != 0); 
// See if string contains formatting information 
$richString = ( ($optionFlags & 0x08) != 0); 
if ($richString) { 
// Read in the crun 
$formattingRuns = ord($this->data[$spos]) | (ord($this->data[$spos+1]) << 8); 
$spos += 2; 
} 
if ($extendedString) { 
// Read in cchExtRst 
$extendedRunLength = $this->_GetInt4d($this->data, $spos); 
$spos += 4; 
} 
$len = ($asciiEncoding)? $numChars : $numChars*2; 
if ($spos + $len < $limitpos) { 
$retstr = substr($this->data, $spos, $len); 
$spos += $len; 
}else{ 
// found countinue 
$retstr = substr($this->data, $spos, $limitpos - $spos); 
$bytesRead = $limitpos - $spos; 
$charsLeft = $numChars - (($asciiEncoding) ? $bytesRead : ($bytesRead / 2)); 
$spos = $limitpos; 
while ($charsLeft > 0){ 
$opcode = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8; 
$conlength = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8; 
if ($opcode != 0x3c) { 
return -1; 
} 
$spos += 4; 
$limitpos = $spos + $conlength; 
$option = ord($this->data[$spos]); 
$spos += 1; 
if ($asciiEncoding && ($option == 0)) { 
$len = min($charsLeft, $limitpos - $spos); // min($charsLeft, $conlength); 
$retstr .= substr($this->data, $spos, $len); 
$charsLeft -= $len; 
$asciiEncoding = true; 
}elseif (!$asciiEncoding && ($option != 0)){ 
$len = min($charsLeft * 2, $limitpos - $spos); // min($charsLeft, $conlength); 
$retstr .= substr($this->data, $spos, $len); 
$charsLeft -= $len/2; 
$asciiEncoding = false; 
}elseif (!$asciiEncoding && ($option == 0)) { 
// Bummer - the string starts off as Unicode, but after the 
// continuation it is in straightforward ASCII encoding 
$len = min($charsLeft, $limitpos - $spos); // min($charsLeft, $conlength); 
for ($j = 0; $j < $len; $j++) { 
$retstr .= $this->data[$spos + $j].chr(0); 
} 
$charsLeft -= $len; 
$asciiEncoding = false; 
}else{ 
$newstr = ''; 
for ($j = 0; $j < strlen($retstr); $j++) { 
$newstr = $retstr[$j].chr(0); 
} 
$retstr = $newstr; 
$len = min($charsLeft * 2, $limitpos - $spos); // min($charsLeft, $conlength); 
$retstr .= substr($this->data, $spos, $len); 
$charsLeft -= $len/2; 
$asciiEncoding = false; 
//echo "Izavrat\n"; 
} 
$spos += $len; 
} 
} 
$retstr = ($asciiEncoding) ? $retstr : $this->_encodeUTF16($retstr); 
// echo "Str $i = $retstr\n"; 
if ($richString){ 
$spos += 4 * $formattingRuns; 
} 
// For extended strings, skip over the extended string data 
if ($extendedString) { 
$spos += $extendedRunLength; 
} 
//if ($retstr == 'Derby'){ 
// echo "bb\n"; 
//} 
$this->sst[]=$retstr; 
} 
/*$continueRecords = array(); 
while ($this->getNextCode() == Type_CONTINUE) { 
$continueRecords[] = &$this->nextRecord(); 
} 
//echo " 1 Type_SST\n"; 
$this->shareStrings = new SSTRecord($r, $continueRecords); 
//print_r($this->shareStrings->strings); 
*/ 
// echo 'SST read: '.($time_end-$time_start)."\n"; 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_FILEPASS: 
return false; 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_NAME: 
//echo "Type_NAME\n"; 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_FORMAT: 
$indexCode = ord($this->data[$pos+4]) | ord($this->data[$pos+5]) << 8; 
if ($version == SPREADSHEET_EXCEL_READER_BIFF8) { 
$numchars = ord($this->data[$pos+6]) | ord($this->data[$pos+7]) << 8; 
if (ord($this->data[$pos+8]) == 0){ 
$formatString = substr($this->data, $pos+9, $numchars); 
} else { 
$formatString = substr($this->data, $pos+9, $numchars*2); 
} 
} else { 
$numchars = ord($this->data[$pos+6]); 
$formatString = substr($this->data, $pos+7, $numchars*2); 
} 
$this->formatRecords[$indexCode] = $formatString; 
// echo "Type.FORMAT\n"; 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_XF: 
//global $dateFormats, $numberFormats; 
$indexCode = ord($this->data[$pos+6]) | ord($this->data[$pos+7]) << 8; 
//echo "\nType.XF ".count($this->formatRecords['xfrecords'])." $indexCode "; 
if (array_key_exists($indexCode, $this->dateFormats)) { 
//echo "isdate ".$dateFormats[$indexCode]; 
$this->formatRecords['xfrecords'][] = array( 
'type' => 'date', 
'format' => $this->dateFormats[$indexCode] 
); 
}elseif (array_key_exists($indexCode, $this->numberFormats)) { 
//echo "isnumber ".$this->numberFormats[$indexCode]; 
$this->formatRecords['xfrecords'][] = array( 
'type' => 'number', 
'format' => $this->numberFormats[$indexCode] 
); 
}else{ 
$isdate = FALSE; 
if ($indexCode > 0){ 
if (isset($this->formatRecords[$indexCode])) 
$formatstr = $this->formatRecords[$indexCode]; 
//echo '.other.'; 
//echo "\ndate-time=$formatstr=\n"; 
if ($formatstr) 
if (preg_match("/[^hmsday\/\-:\s]/i", $formatstr) == 0) { // found day and time format 
$isdate = TRUE; 
$formatstr = str_replace('mm', 'i', $formatstr); 
$formatstr = str_replace('h', 'H', $formatstr); 
//echo "\ndate-time $formatstr \n"; 
} 
} 
if ($isdate){ 
$this->formatRecords['xfrecords'][] = array( 
'type' => 'date', 
'format' => $formatstr, 
); 
}else{ 
$this->formatRecords['xfrecords'][] = array( 
'type' => 'other', 
'format' => '', 
'code' => $indexCode 
); 
} 
} 
//echo "\n"; 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_NINETEENFOUR: 
//echo "Type.NINETEENFOUR\n"; 
$this->nineteenFour = (ord($this->data[$pos+4]) == 1); 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_BOUNDSHEET: 
//echo "Type.BOUNDSHEET\n"; 
$rec_offset = $this->_GetInt4d($this->data, $pos+4); 
$rec_typeFlag = ord($this->data[$pos+8]); 
$rec_visibilityFlag = ord($this->data[$pos+9]); 
$rec_length = ord($this->data[$pos+10]); 
if ($version == SPREADSHEET_EXCEL_READER_BIFF8){ 
$chartype = ord($this->data[$pos+11]); 
if ($chartype == 0){ 
$rec_name = substr($this->data, $pos+12, $rec_length); 
} else { 
$rec_name = $this->_encodeUTF16(substr($this->data, $pos+12, $rec_length*2)); 
} 
}elseif ($version == SPREADSHEET_EXCEL_READER_BIFF7){ 
$rec_name = substr($this->data, $pos+11, $rec_length); 
} 
$this->boundsheets[] = array('name'=>$rec_name, 
'offset'=>$rec_offset); 
break; 
} 
//echo "Code = ".base_convert($r['code'],10,16)."\n"; 
$pos += $length + 4; 
$code = ord($this->data[$pos]) | ord($this->data[$pos+1])<<8; 
$length = ord($this->data[$pos+2]) | ord($this->data[$pos+3])<<8; 
//$r = &$this->nextRecord(); 
//echo "1 Code = ".base_convert($r['code'],10,16)."\n"; 
} 
foreach ($this->boundsheets as $key=>$val){ 
$this->sn = $key; 
$this->_parsesheet($val['offset']); 
} 
return true; 
} 
/** 
* Parse a worksheet 
* 
* @access private 
* @param todo 
* @todo fix return codes 
*/ 
function _parsesheet($spos) 
{ 
$cont = true; 
// read BOF 
$code = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8; 
$length = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8; 
$version = ord($this->data[$spos + 4]) | ord($this->data[$spos + 5])<<8; 
$substreamType = ord($this->data[$spos + 6]) | ord($this->data[$spos + 7])<<8; 
if (($version != SPREADSHEET_EXCEL_READER_BIFF8) && ($version != SPREADSHEET_EXCEL_READER_BIFF7)) { 
return -1; 
} 
if ($substreamType != SPREADSHEET_EXCEL_READER_WORKSHEET){ 
return -2; 
} 
//echo "Start parse code=".base_convert($code,10,16)." version=".base_convert($version,10,16)." substreamType=".base_convert($substreamType,10,16).""."\n"; 
$spos += $length + 4; 
//var_dump($this->formatRecords); 
//echo "code $code $length"; 
while($cont) { 
//echo "mem= ".memory_get_usage()."\n"; 
// $r = &$this->file->nextRecord(); 
$lowcode = ord($this->data[$spos]); 
if ($lowcode == SPREADSHEET_EXCEL_READER_TYPE_EOF) break; 
$code = $lowcode | ord($this->data[$spos+1])<<8; 
$length = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8; 
$spos += 4; 
$this->sheets[$this->sn]['maxrow'] = $this->_rowoffset - 1; 
$this->sheets[$this->sn]['maxcol'] = $this->_coloffset - 1; 
//echo "Code=".base_convert($code,10,16)." $code\n"; 
unset($this->rectype); 
$this->multiplier = 1; // need for format with % 
switch ($code) { 
case SPREADSHEET_EXCEL_READER_TYPE_DIMENSION: 
//echo 'Type_DIMENSION '; 
if (!isset($this->numRows)) { 
if (($length == 10) || ($version == SPREADSHEET_EXCEL_READER_BIFF7)){ 
$this->sheets[$this->sn]['numRows'] = ord($this->data[$spos+2]) | ord($this->data[$spos+3]) << 8; 
$this->sheets[$this->sn]['numCols'] = ord($this->data[$spos+6]) | ord($this->data[$spos+7]) << 8; 
} else { 
$this->sheets[$this->sn]['numRows'] = ord($this->data[$spos+4]) | ord($this->data[$spos+5]) << 8; 
$this->sheets[$this->sn]['numCols'] = ord($this->data[$spos+10]) | ord($this->data[$spos+11]) << 8; 
} 
} 
//echo 'numRows '.$this->numRows.' '.$this->numCols."\n"; 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_MERGEDCELLS: 
$cellRanges = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8; 
for ($i = 0; $i < $cellRanges; $i++) { 
$fr = ord($this->data[$spos + 8*$i + 2]) | ord($this->data[$spos + 8*$i + 3])<<8; 
$lr = ord($this->data[$spos + 8*$i + 4]) | ord($this->data[$spos + 8*$i + 5])<<8; 
$fc = ord($this->data[$spos + 8*$i + 6]) | ord($this->data[$spos + 8*$i + 7])<<8; 
$lc = ord($this->data[$spos + 8*$i + 8]) | ord($this->data[$spos + 8*$i + 9])<<8; 
//$this->sheets[$this->sn]['mergedCells'][] = array($fr + 1, $fc + 1, $lr + 1, $lc + 1); 
if ($lr - $fr > 0) { 
$this->sheets[$this->sn]['cellsInfo'][$fr+1][$fc+1]['rowspan'] = $lr - $fr + 1; 
} 
if ($lc - $fc > 0) { 
$this->sheets[$this->sn]['cellsInfo'][$fr+1][$fc+1]['colspan'] = $lc - $fc + 1; 
} 
} 
//echo "Merged Cells $cellRanges $lr $fr $lc $fc\n"; 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_RK: 
case SPREADSHEET_EXCEL_READER_TYPE_RK2: 
//echo 'SPREADSHEET_EXCEL_READER_TYPE_RK'."\n"; 
$row = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8; 
$column = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8; 
$rknum = $this->_GetInt4d($this->data, $spos + 6); 
$numValue = $this->_GetIEEE754($rknum); 
//echo $numValue." "; 
if ($this->isDate($spos)) { 
list($string, $raw) = $this->createDate($numValue); 
}else{ 
$raw = $numValue; 
if (isset($this->_columnsFormat[$column + 1])){ 
$this->curformat = $this->_columnsFormat[$column + 1]; 
} 
$string = sprintf($this->curformat, $numValue * $this->multiplier); 
//$this->addcell(RKRecord($r)); 
} 
$this->addcell($row, $column, $string, $raw); 
//echo "Type_RK $row $column $string $raw {$this->curformat}\n"; 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_LABELSST: 
$row = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8; 
$column = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8; 
$xfindex = ord($this->data[$spos+4]) | ord($this->data[$spos+5])<<8; 
$index = $this->_GetInt4d($this->data, $spos + 6); 
//var_dump($this->sst); 
$this->addcell($row, $column, $this->sst[$index]); 
//echo "LabelSST $row $column $string\n"; 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_MULRK: 
$row = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8; 
$colFirst = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8; 
$colLast = ord($this->data[$spos + $length - 2]) | ord($this->data[$spos + $length - 1])<<8; 
$columns = $colLast - $colFirst + 1; 
$tmppos = $spos+4; 
for ($i = 0; $i < $columns; $i++) { 
$numValue = $this->_GetIEEE754($this->_GetInt4d($this->data, $tmppos + 2)); 
if ($this->isDate($tmppos-4)) { 
list($string, $raw) = $this->createDate($numValue); 
}else{ 
$raw = $numValue; 
if (isset($this->_columnsFormat[$colFirst + $i + 1])){ 
$this->curformat = $this->_columnsFormat[$colFirst + $i + 1]; 
} 
$string = sprintf($this->curformat, $numValue * $this->multiplier); 
} 
//$rec['rknumbers'][$i]['xfindex'] = ord($rec['data'][$pos]) | ord($rec['data'][$pos+1]) << 8; 
$tmppos += 6; 
$this->addcell($row, $colFirst + $i, $string, $raw); 
//echo "MULRK $row ".($colFirst + $i)." $string\n"; 
} 
//MulRKRecord($r); 
// Get the individual cell records from the multiple record 
//$num = ; 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_NUMBER: 
$row = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8; 
$column = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8; 
$tmp = unpack("ddouble", substr($this->data, $spos + 6, 8)); // It machine machine dependent 
if ($this->isDate($spos)) { 
list($string, $raw) = $this->createDate($tmp['double']); 
// $this->addcell(DateRecord($r, 1)); 
}else{ 
//$raw = $tmp['']; 
if (isset($this->_columnsFormat[$column + 1])){ 
$this->curformat = $this->_columnsFormat[$column + 1]; 
} 
$raw = $this->createNumber($spos); 
$string = sprintf($this->curformat, $raw * $this->multiplier); 
// $this->addcell(NumberRecord($r)); 
} 
$this->addcell($row, $column, $string, $raw); 
//echo "Number $row $column $string\n"; 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_FORMULA: 
case SPREADSHEET_EXCEL_READER_TYPE_FORMULA2: 
$row = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8; 
$column = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8; 
if ((ord($this->data[$spos+6])==0) && (ord($this->data[$spos+12])==255) && (ord($this->data[$spos+13])==255)) { 
//String formula. Result follows in a STRING record 
//echo "FORMULA $row $column Formula with a string<br>\n"; 
} elseif ((ord($this->data[$spos+6])==1) && (ord($this->data[$spos+12])==255) && (ord($this->data[$spos+13])==255)) { 
//Boolean formula. Result is in +2; 0=false,1=true 
} elseif ((ord($this->data[$spos+6])==2) && (ord($this->data[$spos+12])==255) && (ord($this->data[$spos+13])==255)) { 
//Error formula. Error code is in +2; 
} elseif ((ord($this->data[$spos+6])==3) && (ord($this->data[$spos+12])==255) && (ord($this->data[$spos+13])==255)) { 
//Formula result is a null string. 
} else { 
// result is a number, so first 14 bytes are just like a _NUMBER record 
$tmp = unpack("ddouble", substr($this->data, $spos + 6, 8)); // It machine machine dependent 
if ($this->isDate($spos)) { 
list($string, $raw) = $this->createDate($tmp['double']); 
// $this->addcell(DateRecord($r, 1)); 
}else{ 
//$raw = $tmp['']; 
if (isset($this->_columnsFormat[$column + 1])){ 
$this->curformat = $this->_columnsFormat[$column + 1]; 
} 
$raw = $this->createNumber($spos); 
$string = sprintf($this->curformat, $raw * $this->multiplier); 
// $this->addcell(NumberRecord($r)); 
} 
$this->addcell($row, $column, $string, $raw); 
//echo "Number $row $column $string\n"; 
} 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_BOOLERR: 
$row = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8; 
$column = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8; 
$string = ord($this->data[$spos+6]); 
$this->addcell($row, $column, $string); 
//echo 'Type_BOOLERR '."\n"; 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_ROW: 
case SPREADSHEET_EXCEL_READER_TYPE_DBCELL: 
case SPREADSHEET_EXCEL_READER_TYPE_MULBLANK: 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_LABEL: 
$row = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8; 
$column = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8; 
$this->addcell($row, $column, substr($this->data, $spos + 8, ord($this->data[$spos + 6]) | ord($this->data[$spos + 7])<<8)); 
// $this->addcell(LabelRecord($r)); 
break; 
case SPREADSHEET_EXCEL_READER_TYPE_EOF: 
$cont = false; 
break; 
default: 
//echo ' unknown :'.base_convert($r['code'],10,16)."\n"; 
break; 
} 
$spos += $length; 
} 
if (!isset($this->sheets[$this->sn]['numRows'])) 
$this->sheets[$this->sn]['numRows'] = $this->sheets[$this->sn]['maxrow']; 
if (!isset($this->sheets[$this->sn]['numCols'])) 
$this->sheets[$this->sn]['numCols'] = $this->sheets[$this->sn]['maxcol']; 
} 
/** 
* Check whether the current record read is a date 
* 
* @param todo 
* @return boolean True if date, false otherwise 
*/ 
function isDate($spos) 
{ 
//$xfindex = GetInt2d(, 4); 
$xfindex = ord($this->data[$spos+4]) | ord($this->data[$spos+5]) << 8; 
//echo 'check is date '.$xfindex.' '.$this->formatRecords['xfrecords'][$xfindex]['type']."\n"; 
//var_dump($this->formatRecords['xfrecords'][$xfindex]); 
if ($this->formatRecords['xfrecords'][$xfindex]['type'] == 'date') { 
$this->curformat = $this->formatRecords['xfrecords'][$xfindex]['format']; 
$this->rectype = 'date'; 
return true; 
} else { 
if ($this->formatRecords['xfrecords'][$xfindex]['type'] == 'number') { 
$this->curformat = $this->formatRecords['xfrecords'][$xfindex]['format']; 
$this->rectype = 'number'; 
if (($xfindex == 0x9) || ($xfindex == 0xa)){ 
$this->multiplier = 100; 
} 
}else{ 
$this->curformat = $this->_defaultFormat; 
$this->rectype = 'unknown'; 
} 
return false; 
} 
} 
//}}} 
//{{{ createDate() 
/** 
* Convert the raw Excel date into a human readable format 
* 
* Dates in Excel are stored as number of seconds from an epoch. On 
* Windows, the epoch is 30/12/1899 and on Mac it's 01/01/1904 
* 
* @access private 
* @param integer The raw Excel value to convert 
* @return array First element is the converted date, the second element is number a unix timestamp 
*/ 
function createDate($numValue) 
{ 
if ($numValue > 1) { 
$utcDays = $numValue - ($this->nineteenFour ? SPREADSHEET_EXCEL_READER_UTCOFFSETDAYS1904 : SPREADSHEET_EXCEL_READER_UTCOFFSETDAYS); 
$utcValue = round(($utcDays+1) * SPREADSHEET_EXCEL_READER_MSINADAY); 
$string = date ($this->curformat, $utcValue); 
$raw = $utcValue; 
} else { 
$raw = $numValue; 
$hours = floor($numValue * 24); 
$mins = floor($numValue * 24 * 60) - $hours * 60; 
$secs = floor($numValue * SPREADSHEET_EXCEL_READER_MSINADAY) - $hours * 60 * 60 - $mins * 60; 
$string = date ($this->curformat, mktime($hours, $mins, $secs)); 
} 
return array($string, $raw); 
} 
function createNumber($spos) 
{ 
$rknumhigh = $this->_GetInt4d($this->data, $spos + 10); 
$rknumlow = $this->_GetInt4d($this->data, $spos + 6); 
//for ($i=0; $i<8; $i++) { echo ord($this->data[$i+$spos+6]) . " "; } echo "<br>"; 
$sign = ($rknumhigh & 0x80000000) >> 31; 
$exp = ($rknumhigh & 0x7ff00000) >> 20; 
$mantissa = (0x100000 | ($rknumhigh & 0x000fffff)); 
$mantissalow1 = ($rknumlow & 0x80000000) >> 31; 
$mantissalow2 = ($rknumlow & 0x7fffffff); 
$value = $mantissa / pow( 2 , (20- ($exp - 1023))); 
if ($mantissalow1 != 0) $value += 1 / pow (2 , (21 - ($exp - 1023))); 
$value += $mantissalow2 / pow (2 , (52 - ($exp - 1023))); 
//echo "Sign = $sign, Exp = $exp, mantissahighx = $mantissa, mantissalow1 = $mantissalow1, mantissalow2 = $mantissalow2<br>\n"; 
if ($sign) {$value = -1 * $value;} 
return $value; 
} 
function addcell($row, $col, $string, $raw = '') 
{ 
//echo "ADD cel $row-$col $string\n"; 
$this->sheets[$this->sn]['maxrow'] = max($this->sheets[$this->sn]['maxrow'], $row + $this->_rowoffset); 
$this->sheets[$this->sn]['maxcol'] = max($this->sheets[$this->sn]['maxcol'], $col + $this->_coloffset); 
$this->sheets[$this->sn]['cells'][$row + $this->_rowoffset][$col + $this->_coloffset] = $string; 
if ($raw) 
$this->sheets[$this->sn]['cellsInfo'][$row + $this->_rowoffset][$col + $this->_coloffset]['raw'] = $raw; 
if (isset($this->rectype)) 
$this->sheets[$this->sn]['cellsInfo'][$row + $this->_rowoffset][$col + $this->_coloffset]['type'] = $this->rectype; 
} 
function _GetIEEE754($rknum) 
{ 
if (($rknum & 0x02) != 0) { 
$value = $rknum >> 2; 
} else { 
//mmp 
// first comment out the previously existing 7 lines of code here 
// $tmp = unpack("d", pack("VV", 0, ($rknum & 0xfffffffc))); 
// //$value = $tmp['']; 
// if (array_key_exists(1, $tmp)) { 
// $value = $tmp[1]; 
// } else { 
// $value = $tmp['']; 
// } 
// I got my info on IEEE754 encoding from 
// http://research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html 
// The RK format calls for using only the most significant 30 bits of the 
// 64 bit floating point value. The other 34 bits are assumed to be 0 
// So, we use the upper 30 bits of $rknum as follows 
$sign = ($rknum & 0x80000000) >> 31; 
$exp = ($rknum & 0x7ff00000) >> 20; 
$mantissa = (0x100000 | ($rknum & 0x000ffffc)); 
$value = $mantissa / pow( 2 , (20- ($exp - 1023))); 
if ($sign) {$value = -1 * $value;} 
//end of changes by mmp 
} 
if (($rknum & 0x01) != 0) { 
$value /= 100; 
} 
return $value; 
} 
function _encodeUTF16($string) 
{ 
$result = $string; 
if ($this->_defaultEncoding){ 
switch ($this->_encoderFunction){ 
case 'iconv' : $result = iconv('UTF-16LE', $this->_defaultEncoding, $string); 
break; 
case 'mb_convert_encoding' : $result = mb_convert_encoding($string, $this->_defaultEncoding, 'UTF-16LE' ); 
break; 
} 
} 
return $result; 
} 
function _GetInt4d($data, $pos) 
{ 
$value = ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | (ord($data[$pos+3]) << 24); 
if ($value>=4294967294) 
{ 
$value=-2; 
} 
return $value; 
} 
} 
/* 
* Local variables: 
* tab-width: 4 
* c-basic-offset: 4 
* c-hanging-comment-ender-p: nil 
* End: 
*/ 
?>

PHP 相关文章推荐
php预定义常量
Dec 25 PHP
使用adodb lite解决问题
Dec 31 PHP
php 用sock技术发送邮件的函数
Jul 21 PHP
PHPMailer 中文使用说明小结
Jan 22 PHP
PHP 观察者模式的实现代码
May 10 PHP
Yii2使用小技巧之通过 Composer 添加 FontAwesome 字体资源
Jun 22 PHP
PHP把MSSQL数据导入到MYSQL的方法
Dec 27 PHP
php实现的简单检验登陆类
Jun 18 PHP
php获取远程文件大小
Oct 20 PHP
PHP简单实现DES加密解密的方法
Jul 12 PHP
PHP空值检测函数与方法汇总
Nov 19 PHP
PHP Laravel中的Trait使用方法
Jan 20 PHP
PHP CKEditor 上传图片实现代码
Nov 06 #PHP
PHP 压缩文件夹的类代码
Nov 05 #PHP
PHP 向右侧拉菜单实现代码,测试使用中
Nov 03 #PHP
网页游戏开发入门教程三(简单程序应用)
Nov 02 #PHP
网页游戏开发入门教程二(游戏模式+系统)
Nov 02 #PHP
初学CAKEPHP 基础教程
Nov 02 #PHP
PHP+MySQL 制作简单的留言本
Nov 02 #PHP
You might like
PHP错误Allowed memory size of 67108864 bytes exhausted的3种解决办法
2014/07/28 PHP
PHP内置的Math函数效率测试
2014/12/01 PHP
php实现读取手机客户端浏览器的类
2015/01/09 PHP
JavaScript 解析Json字符串的性能比较分析代码
2009/12/16 Javascript
JQuery 选择器、过滤器介绍
2011/02/14 Javascript
IE6背景图片不缓存问题解决方案及图片使用策略多个方法小结
2012/05/14 Javascript
关于jquery.validate1.9.0前台验证的使用介绍
2013/04/26 Javascript
Js中使用hasOwnProperty方法检索ajax响应对象的例子
2014/12/08 Javascript
在Javascript中处理数组之toSource()方法的使用
2015/06/09 Javascript
javascript遇到html5的一些表单属性
2015/07/05 Javascript
JavaScript类型系统之基本数据类型与包装类型
2016/01/06 Javascript
JS延时器提示框的应用实例代码解析
2016/04/27 Javascript
微信小程序开发之数据存储 参数传递 数据缓存
2017/04/13 Javascript
js微信应用场景之微信音乐相册案例分享
2017/08/11 Javascript
React 使用browserHistory项目访问404问题解决
2018/06/01 Javascript
bootstrap 弹出框modal添加垂直方向滚轴效果
2018/07/09 Javascript
JavaScript 中的六种循环方法
2021/01/06 Javascript
[00:34]TI7不朽珍藏III——纯金地穴编织者饰品展示
2017/07/15 DOTA
python双向链表实现实例代码
2013/11/21 Python
Python日期的加减等操作的示例
2017/08/15 Python
Python拼接字符串的7种方法总结
2018/11/01 Python
django认证系统 Authentication使用详解
2019/07/22 Python
Python Web静态服务器非堵塞模式实现方法示例
2019/11/21 Python
Python+OpenCV检测灯光亮点的实现方法
2020/11/02 Python
python爬虫看看虎牙女主播中谁最“顶”步骤详解
2020/12/01 Python
全球最大的游戏市场:G2A
2018/07/05 全球购物
爷爷追悼会答谢词
2014/01/24 职场文书
服务员岗位责任制
2014/02/11 职场文书
节约电力资源的建议书
2014/03/12 职场文书
团日活动总结
2014/04/28 职场文书
和谐家庭演讲稿
2014/05/24 职场文书
授权委托书(公民个人适用)
2014/09/19 职场文书
解除同居协议书
2015/01/29 职场文书
《雪地里的小画家》教学反思
2016/02/16 职场文书
Python将CSV文件转化为HTML文件的操作方法
2021/06/30 Python
Eclipse+Java+Swing+Mysql实现电影购票系统(详细代码)
2022/01/18 Java/Android