php 读取excel
这不是我写的,我志修改了一下,使调用更方便
- <?php
- require_once 'ExcelReader.class.php'; //调用下面的代码
- // ExcelFile($filename, $encoding);
- $data = new Spreadsheet_Excel_Reader();
- $data->setOutputEncoding('GB2312');
- $data->setUTFEncoder('mb'); // iconv or mb
- $data->setRowColOffset(1);
- $data->read('book2.xls');
- $array = $data->outPutData(); //返回2维数组
- print_r($array);
- ?>
- <?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) {
- return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | (ord($data[$pos+3]) << 24);
- }
- 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;
- }
- }
- }
- //define('Spreadsheet_Excel_Reader_HAVE_ICONV', function_exists('iconv'));
- //define('Spreadsheet_Excel_Reader_HAVE_MB', function_exists('mb_convert_encoding'));
- 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', 24 * 60 * 60);
- //define('Spreadsheet_Excel_Reader_DEF_NUM_FORMAT', "%.2f");
- define('Spreadsheet_Excel_Reader_DEF_NUM_FORMAT', "%s");
- // function file_get_contents for PHP < 4.3.0
- // Thanks Marian Steinbach for this function
- if (!function_exists('file_get_contents')) {
- function file_get_contents($filename, $use_include_path = 0) {
- $data = '';
- $file = @fopen($filename, "rb", $use_include_path);
- if ($file) {
- while (!feof($file)) $data .= fread($file, 1024);
- fclose($file);
- } else {
- // There was a problem opening the file
- $data = FALSE;
- }
- return $data;
- }
- }
- //class Spreadsheet_Excel_Reader extends PEAR {
- class Spreadsheet_Excel_Reader {
- var $boundsheets = array();
- var $formatRecords = array();
- var $sst = array();
- var $sheets = array();
- var $data;
- var $pos;
- var $_ole;
- var $_defaultEncoding;
- var $_defaultFormat = Spreadsheet_Excel_Reader_DEF_NUM_FORMAT;
- var $_columnsFormat = array();
- var $_rowoffset = 1;
- var $_coloffset = 1;
- 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");
- 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";
- function Spreadsheet_Excel_Reader(){
- $this->_ole =& new OLERead();
- $this->setUTFEncoder('iconv');
- }
- function setOutputEncoding($Encoding){
- $this->_defaultEncoding = $Encoding;
- }
- /**
- * $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
- */
- 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' : '';
- }
- }
- function setRowColOffset($iOffset){
- $this->_rowoffset = $iOffset;
- $this->_coloffset = $iOffset;
- }
- function setDefaultFormat($sFormat){
- $this->_defaultFormat = $sFormat;
- }
- function setColumnFormat($column, $sFormat){
- $this->_columnsFormat[$column] = $sFormat;
- }
- function read($sFileName) {
- $errlevel = error_reporting();
- error_reporting($errlevel ^ E_NOTICE);
- $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;