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;
}classOLERead {var $data = '';functionOLERead(){
}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);
}
}/*何问起 hovertree.com*/
//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;
}
}functiongetWorkBook(){if ($this->props[$this->wrkbook]['size']
$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;
}
}
}?>