Added PHP files needed to read XLS files. refs #1249
Showing
2 changed files
with
273 additions
and
0 deletions
com/ExcelReader/oleread.inc
0 → 100755
| 1 | <?php | ||
| 2 | namespace Tz\Wordpress\Tools\ExcelReader; | ||
| 3 | |||
| 4 | define('NUM_BIG_BLOCK_DEPOT_BLOCKS_POS', 0x2c); | ||
| 5 | define('SMALL_BLOCK_DEPOT_BLOCK_POS', 0x3c); | ||
| 6 | define('ROOT_START_BLOCK_POS', 0x30); | ||
| 7 | define('BIG_BLOCK_SIZE', 0x200); | ||
| 8 | define('SMALL_BLOCK_SIZE', 0x40); | ||
| 9 | define('EXTENSION_BLOCK_POS', 0x44); | ||
| 10 | define('NUM_EXTENSION_BLOCK_POS', 0x48); | ||
| 11 | define('PROPERTY_STORAGE_BLOCK_SIZE', 0x80); | ||
| 12 | define('BIG_BLOCK_DEPOT_BLOCKS_POS', 0x4c); | ||
| 13 | define('SMALL_BLOCK_THRESHOLD', 0x1000); | ||
| 14 | // property storage offsets | ||
| 15 | define('SIZE_OF_NAME_POS', 0x40); | ||
| 16 | define('TYPE_POS', 0x42); | ||
| 17 | define('START_BLOCK_POS', 0x74); | ||
| 18 | define('SIZE_POS', 0x78); | ||
| 19 | define('IDENTIFIER_OLE', pack("CCCCCCCC",0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1)); | ||
| 20 | |||
| 21 | //echo 'ROOT_START_BLOCK_POS = '.ROOT_START_BLOCK_POS."\n"; | ||
| 22 | |||
| 23 | //echo bin2hex($data[ROOT_START_BLOCK_POS])."\n"; | ||
| 24 | //echo "a="; | ||
| 25 | //echo $data[ROOT_START_BLOCK_POS]; | ||
| 26 | //function log | ||
| 27 | |||
| 28 | function GetInt4d($data, $pos) | ||
| 29 | { | ||
| 30 | $value = ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | (ord($data[$pos+3]) << 24); | ||
| 31 | if ($value>=4294967294) | ||
| 32 | { | ||
| 33 | $value=-2; | ||
| 34 | } | ||
| 35 | return $value; | ||
| 36 | } | ||
| 37 | |||
| 38 | |||
| 39 | class OLERead { | ||
| 40 | var $data = ''; | ||
| 41 | |||
| 42 | |||
| 43 | function OLERead(){ | ||
| 44 | |||
| 45 | |||
| 46 | } | ||
| 47 | |||
| 48 | function read($sFileName){ | ||
| 49 | |||
| 50 | // check if file exist and is readable (Darko Miljanovic) | ||
| 51 | if(!is_readable($sFileName)) { | ||
| 52 | $this->error = 1; | ||
| 53 | return false; | ||
| 54 | } | ||
| 55 | |||
| 56 | $this->data = @file_get_contents($sFileName); | ||
| 57 | if (!$this->data) { | ||
| 58 | $this->error = 1; | ||
| 59 | return false; | ||
| 60 | } | ||
| 61 | //echo IDENTIFIER_OLE; | ||
| 62 | //echo 'start'; | ||
| 63 | if (substr($this->data, 0, 8) != IDENTIFIER_OLE) { | ||
| 64 | $this->error = 1; | ||
| 65 | return false; | ||
| 66 | } | ||
| 67 | $this->numBigBlockDepotBlocks = GetInt4d($this->data, NUM_BIG_BLOCK_DEPOT_BLOCKS_POS); | ||
| 68 | $this->sbdStartBlock = GetInt4d($this->data, SMALL_BLOCK_DEPOT_BLOCK_POS); | ||
| 69 | $this->rootStartBlock = GetInt4d($this->data, ROOT_START_BLOCK_POS); | ||
| 70 | $this->extensionBlock = GetInt4d($this->data, EXTENSION_BLOCK_POS); | ||
| 71 | $this->numExtensionBlocks = GetInt4d($this->data, NUM_EXTENSION_BLOCK_POS); | ||
| 72 | |||
| 73 | /* | ||
| 74 | echo $this->numBigBlockDepotBlocks." "; | ||
| 75 | echo $this->sbdStartBlock." "; | ||
| 76 | echo $this->rootStartBlock." "; | ||
| 77 | echo $this->extensionBlock." "; | ||
| 78 | echo $this->numExtensionBlocks." "; | ||
| 79 | */ | ||
| 80 | //echo "sbdStartBlock = $this->sbdStartBlock\n"; | ||
| 81 | $bigBlockDepotBlocks = array(); | ||
| 82 | $pos = BIG_BLOCK_DEPOT_BLOCKS_POS; | ||
| 83 | // echo "pos = $pos"; | ||
| 84 | $bbdBlocks = $this->numBigBlockDepotBlocks; | ||
| 85 | |||
| 86 | if ($this->numExtensionBlocks != 0) { | ||
| 87 | $bbdBlocks = (BIG_BLOCK_SIZE - BIG_BLOCK_DEPOT_BLOCKS_POS)/4; | ||
| 88 | } | ||
| 89 | |||
| 90 | for ($i = 0; $i < $bbdBlocks; $i++) { | ||
| 91 | $bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos); | ||
| 92 | $pos += 4; | ||
| 93 | } | ||
| 94 | |||
| 95 | |||
| 96 | for ($j = 0; $j < $this->numExtensionBlocks; $j++) { | ||
| 97 | $pos = ($this->extensionBlock + 1) * BIG_BLOCK_SIZE; | ||
| 98 | $blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, BIG_BLOCK_SIZE / 4 - 1); | ||
| 99 | |||
| 100 | for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; $i++) { | ||
| 101 | $bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos); | ||
| 102 | $pos += 4; | ||
| 103 | } | ||
| 104 | |||
| 105 | $bbdBlocks += $blocksToRead; | ||
| 106 | if ($bbdBlocks < $this->numBigBlockDepotBlocks) { | ||
| 107 | $this->extensionBlock = GetInt4d($this->data, $pos); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | // var_dump($bigBlockDepotBlocks); | ||
| 112 | |||
| 113 | // readBigBlockDepot | ||
| 114 | $pos = 0; | ||
| 115 | $index = 0; | ||
| 116 | $this->bigBlockChain = array(); | ||
| 117 | |||
| 118 | for ($i = 0; $i < $this->numBigBlockDepotBlocks; $i++) { | ||
| 119 | $pos = ($bigBlockDepotBlocks[$i] + 1) * BIG_BLOCK_SIZE; | ||
| 120 | //echo "pos = $pos"; | ||
| 121 | for ($j = 0 ; $j < BIG_BLOCK_SIZE / 4; $j++) { | ||
| 122 | $this->bigBlockChain[$index] = GetInt4d($this->data, $pos); | ||
| 123 | $pos += 4 ; | ||
| 124 | $index++; | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | //var_dump($this->bigBlockChain); | ||
| 129 | //echo '=====2'; | ||
| 130 | // readSmallBlockDepot(); | ||
| 131 | $pos = 0; | ||
| 132 | $index = 0; | ||
| 133 | $sbdBlock = $this->sbdStartBlock; | ||
| 134 | $this->smallBlockChain = array(); | ||
| 135 | |||
| 136 | while ($sbdBlock != -2) { | ||
| 137 | |||
| 138 | $pos = ($sbdBlock + 1) * BIG_BLOCK_SIZE; | ||
| 139 | |||
| 140 | for ($j = 0; $j < BIG_BLOCK_SIZE / 4; $j++) { | ||
| 141 | $this->smallBlockChain[$index] = GetInt4d($this->data, $pos); | ||
| 142 | $pos += 4; | ||
| 143 | $index++; | ||
| 144 | } | ||
| 145 | |||
| 146 | $sbdBlock = $this->bigBlockChain[$sbdBlock]; | ||
| 147 | } | ||
| 148 | |||
| 149 | |||
| 150 | // readData(rootStartBlock) | ||
| 151 | $block = $this->rootStartBlock; | ||
| 152 | $pos = 0; | ||
| 153 | $this->entry = $this->__readData($block); | ||
| 154 | |||
| 155 | /* | ||
| 156 | while ($block != -2) { | ||
| 157 | $pos = ($block + 1) * BIG_BLOCK_SIZE; | ||
| 158 | $this->entry = $this->entry.substr($this->data, $pos, BIG_BLOCK_SIZE); | ||
| 159 | $block = $this->bigBlockChain[$block]; | ||
| 160 | } | ||
| 161 | */ | ||
| 162 | //echo '==='.$this->entry."==="; | ||
| 163 | $this->__readPropertySets(); | ||
| 164 | |||
| 165 | } | ||
| 166 | |||
| 167 | function __readData($bl) { | ||
| 168 | $block = $bl; | ||
| 169 | $pos = 0; | ||
| 170 | $data = ''; | ||
| 171 | |||
| 172 | while ($block != -2) { | ||
| 173 | $pos = ($block + 1) * BIG_BLOCK_SIZE; | ||
| 174 | $data = $data.substr($this->data, $pos, BIG_BLOCK_SIZE); | ||
| 175 | //echo "pos = $pos data=$data\n"; | ||
| 176 | $block = $this->bigBlockChain[$block]; | ||
| 177 | } | ||
| 178 | return $data; | ||
| 179 | } | ||
| 180 | |||
| 181 | function __readPropertySets(){ | ||
| 182 | $offset = 0; | ||
| 183 | //var_dump($this->entry); | ||
| 184 | while ($offset < strlen($this->entry)) { | ||
| 185 | $d = substr($this->entry, $offset, PROPERTY_STORAGE_BLOCK_SIZE); | ||
| 186 | |||
| 187 | $nameSize = ord($d[SIZE_OF_NAME_POS]) | (ord($d[SIZE_OF_NAME_POS+1]) << 8); | ||
| 188 | |||
| 189 | $type = ord($d[TYPE_POS]); | ||
| 190 | //$maxBlock = strlen($d) / BIG_BLOCK_SIZE - 1; | ||
| 191 | |||
| 192 | $startBlock = GetInt4d($d, START_BLOCK_POS); | ||
| 193 | $size = GetInt4d($d, SIZE_POS); | ||
| 194 | |||
| 195 | $name = ''; | ||
| 196 | for ($i = 0; $i < $nameSize ; $i++) { | ||
| 197 | $name .= $d[$i]; | ||
| 198 | } | ||
| 199 | |||
| 200 | $name = str_replace("\x00", "", $name); | ||
| 201 | |||
| 202 | $this->props[] = array ( | ||
| 203 | 'name' => $name, | ||
| 204 | 'type' => $type, | ||
| 205 | 'startBlock' => $startBlock, | ||
| 206 | 'size' => $size); | ||
| 207 | |||
| 208 | if (($name == "Workbook") || ($name == "Book")) { | ||
| 209 | $this->wrkbook = count($this->props) - 1; | ||
| 210 | } | ||
| 211 | |||
| 212 | if ($name == "Root Entry") { | ||
| 213 | $this->rootentry = count($this->props) - 1; | ||
| 214 | } | ||
| 215 | |||
| 216 | //echo "name ==$name=\n"; | ||
| 217 | |||
| 218 | |||
| 219 | $offset += PROPERTY_STORAGE_BLOCK_SIZE; | ||
| 220 | } | ||
| 221 | |||
| 222 | } | ||
| 223 | |||
| 224 | |||
| 225 | function getWorkBook(){ | ||
| 226 | if ($this->props[$this->wrkbook]['size'] < SMALL_BLOCK_THRESHOLD){ | ||
| 227 | // getSmallBlockStream(PropertyStorage ps) | ||
| 228 | |||
| 229 | $rootdata = $this->__readData($this->props[$this->rootentry]['startBlock']); | ||
| 230 | |||
| 231 | $streamData = ''; | ||
| 232 | $block = $this->props[$this->wrkbook]['startBlock']; | ||
| 233 | //$count = 0; | ||
| 234 | $pos = 0; | ||
| 235 | while ($block != -2) { | ||
| 236 | $pos = $block * SMALL_BLOCK_SIZE; | ||
| 237 | $streamData .= substr($rootdata, $pos, SMALL_BLOCK_SIZE); | ||
| 238 | |||
| 239 | $block = $this->smallBlockChain[$block]; | ||
| 240 | } | ||
| 241 | |||
| 242 | return $streamData; | ||
| 243 | |||
| 244 | |||
| 245 | }else{ | ||
| 246 | |||
| 247 | $numBlocks = $this->props[$this->wrkbook]['size'] / BIG_BLOCK_SIZE; | ||
| 248 | if ($this->props[$this->wrkbook]['size'] % BIG_BLOCK_SIZE != 0) { | ||
| 249 | $numBlocks++; | ||
| 250 | } | ||
| 251 | |||
| 252 | if ($numBlocks == 0) return ''; | ||
| 253 | |||
| 254 | //echo "numBlocks = $numBlocks\n"; | ||
| 255 | //byte[] streamData = new byte[numBlocks * BIG_BLOCK_SIZE]; | ||
| 256 | //print_r($this->wrkbook); | ||
| 257 | $streamData = ''; | ||
| 258 | $block = $this->props[$this->wrkbook]['startBlock']; | ||
| 259 | //$count = 0; | ||
| 260 | $pos = 0; | ||
| 261 | //echo "block = $block"; | ||
| 262 | while ($block != -2) { | ||
| 263 | $pos = ($block + 1) * BIG_BLOCK_SIZE; | ||
| 264 | $streamData .= substr($this->data, $pos, BIG_BLOCK_SIZE); | ||
| 265 | $block = $this->bigBlockChain[$block]; | ||
| 266 | } | ||
| 267 | //echo 'stream'.$streamData; | ||
| 268 | return $streamData; | ||
| 269 | } | ||
| 270 | } | ||
| 271 | |||
| 272 | } | ||
| 273 | ?> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
com/ExcelReader/reader.php
0 → 100755
This diff is collapsed.
Click to expand it.
-
Please register or sign in to post a comment