ホームページ  >  記事  >  バックエンド開発  >  PHP が Excel コンテンツを読み取る_PHP チュートリアル

PHP が Excel コンテンツを読み取る_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-20 11:05:42876ブラウズ

define('ABC_CRITICAL', 0);
define('ABC_ERROR', 1);
define('ABC_ALERT', 2);
define('ABC_WARNING', 3);
define('ABC_お知らせ」 , 4);
define('ABC_INFO', 5);
define('ABC_DEBUG', 6);
define('ABC_TRACE', 7);
define('ABC_VAR_DUMP', 8);
定義('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 "n";<br />$cs = debug_backtrace();<br />for( $i = 1; $i < count($cs) ; $i++ )<br />{<br />$item = $cs[ $i ];<br />for( $j = 0; $j < count($item['args']); $j++ )<br />if( is_string($item['args'][$j] ) )<br />$item['args'][$j] = """ . $item['args'][$j] . """;<br />$args = join(",", $item['args '] );<br />if( isset( $item['class'] ) )<br />$str = sprintf("%s(%d): %s%s%s(%s)",<br />$item['file '],<br />$item['line'],<br />$item['class'],<br />$item['type'],<br />$item['function'],<br />$args );<br />else<br />$str = sprintf("%s(%d): %s(%s)",<br />$item['file'],<br />$item['line'],<br />$item['function'],<br />$args ); <br />エコー $str 。 "<br>n";<br>}print "n";
}function _die( $str )
{
print "スクリプトが理由で終了しました: $str
n";
print_bt() ;
exit();
}class DebugOut
{
var $priorities = array(ABC_CRITICAL => 'クリティカル',
ABC_ERROR => 'エラー',
ABC_ALERT => 'アラート',
ABC_WARNING => '警告',
ABC_NOTICE => '通知',
ABC_INFO => ABC_DEBUG => 'デバッグ',
ABC_TRACE => トレース,
ABC_VAR_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();
}
register_shutdown_function(array($this,"close"));
} function log($message, $priority = ABC_INFO) {
if ($priority > $this->_currentPriority) {
            return false;
}
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:%M:%S');
$message = var_export($variable,true);
return fwrite($this->_fp,
sprintf("%s %s [%s] 変数 %s = %s rn",
$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 track($message) {
return $this->log($message, ABC_TRACE);
} function error($message) {
return $this->log($message, ABC_ERROR);
}
function _writeLine($message, $priority, $time) {
if( fwrite($this->gt;_fp, sprintf("%s %s [%s] %srn", $time, $this->logger_name, $this->gt;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("ロガーが停止しました");
return fclose($ this->_fp);
} }
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[$署名];
} functionattach(&$logObserver) {
    if (!is_object($logObserver)) {
return false;
} $logObserver->_listenerID = uniqid(rand());
$this->_listeners[$logObserver->_listenerID] = &$logObserver;
}}define ('ABC_BAD_DATE', -1);
class ExcelDateUtil{
function xls2tstamp($date) {
$date=$date>25568?$date:25569;
$ofs=(70 * 365 + 17+ 2) * 86400;
return ($date * 86400) - $ofs;
}function getDateArray($xls_date){
$ret = array();
if ($xls_date == 60) {
$ret['day '] = 29;
$ret['month'] = 2;
$ret['year'] = 1900;
return $ret;
} else if ($xls_date < 60) {
$xls_date++;
}
$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['月'] = $j + 2 - ( 12 * $l );
$ret['年'] = 100 * ( $n - 49 ) + $i + $l;
return $ret;
}function isInternalDateFormat($format) {
$retval =false;
switch(format) {
case 0x0e:
case 0x0f:
case 0x10:
case 0x11:
ケース 0x12:
ケース 0x13:
ケース 0x14:
ケース 0x15:
ケース 0x16:
ケース 0x2d:
ケース 0x2e:
ケース 0x2f:
ケース 0 xa4:
ケース 0xa5:
ケース 0xa6:
ケース 0xa7:
ケース 0xa8:
ケース 0xa9:
ケース0xaa:
case 0xab:
case 0xac:
case 0xad:
$retval = true; Break;
デフォルト: $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_DOUB) LE_ACCOUNTING',0x4);
define('XF_STYLE_ITALIC', 0x2);
define('XF_STYLE_STRIKEOUT', 0x8);
define('XF_BOLDNESS_REGULAR',0x190);
define('XF_BOLDNESS_BOLD',0x2BC);
class ExcelFont {
関数 BasicFontRecord() {
return array('size' => 10,
'script' => XF_SCRIPT_NONE,
'undeline' => XF_UNDERLINE_NONE,
'斜体' => false,
'三振'=> false,
'太字' =>                    '大胆さ' => XF_BOLDNESS_REGULAR,
'パレット' => 0,
'名前' => 'Arial');
} function getFontRecord(&$wb,$ptr) {
$retval = array('size' => 0,
'script' => XF_SCRIPT_NONE,
'下線' => XF_UNDERLINE_NONE,
'斜体' => false,
'三振'=> false,
'太字' => false,
'大胆さ' => XF_BOLDNESS_REGULAR,
'パレット' =>
= > '');
$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) {
$retval['name'] = substr($wb,$ptr+16,$length);
} else {
$retval['name'] = ExcelFont::getUnicodeString($wb,$ ptr+15,$length);
} } return $retval;
} function toString(&$record,$index) {
$retval = sprintf("フォント インデックス = %d nフォント サイズ =%dnItalic = %snStrikeoout=% snPalete=%snBoldness = %s Bold=%sn Script = %dn Underline = %dn FontName=%s


",
$index,
$record['size'],
$レコード['斜体'] = = true?"true":"false",
$record['三振'] == true?"true":"false",
$record['パレット'],
$record['大胆さ'],
$record['bold'] == true?"true":"false",
$record['script'],
$record['underline'],
$record['name']
                );
return $retval;
} function getUnicodeString(&$string,$offset,$length) {
$bstring = "";
$index = $offset + 1;
for ($k = 0; $k < ; $length; $k++)
{
$bstring = $bstring.$string[$index];
$index += 2;
} return substr($bstring,0,$length);
} CSS($ 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("ファイル サイズの決定に失敗しました。");
break;
case DP_STRING_SOURCE:
$this->_data = $data;
$this->_size = strlen( $data );
break;
default:
_die("無効なデータ型が指定されました。");
}$this->_type = $dataType;
register_shutdown_function( array( $this, "close") );
}function get( $offset, $length )
{
if( !$this->isValid() )
_die("データプロバイダーが空です。");
if( $this->_baseOfs + $offset + $length > $this->_size )
_die("無効なオフセット/長さです。");
switch( $this->_type )
{
case DP_FILE_SOURCE:
{
if( @fseek( $this->_data, $this->_baseOfs + $offset, SEEK_SET ) == -1 )
_die("offest で指定されたファイル位置のシークに失敗しました。");
return @fread( $this->_data, $length );
}case DP_STRING_SOURCE:
{
$rc = substr( $this->_data, $this->_baseOfs + $offset, $length );
return $rc;
}default:
_die("無効なデータ型またはクラスは初期化されていませんでした。");
}}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("データプロバイダーが空です。");
return $this->_size;
}function getBlocks()
{
if ( !$this->isValid() )
_die("データプロバイダーが空です。");
return (int)(($this->_size - 1) / 0x200) - 1;
}function ReadFromFat( $chain, $gran = 0x200 )
{
$rc = '';
for( $i = 0; $i $rc .= $this->get( $chain[$i] * $gran, $gran );
return $rc;
}function close()
{
switch($this-> _タイプ)
{
case DP_FILE_SOURCE:
@fclose( $this->_data );
case DP_STRING_SOURCE:
$this->_data = null;
default:
$_type = DP_EMPTY;
break;
}}関数 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;
var $fat;
var $sfat;
var $formats;
var $xf;
var $fonts;
var $dbglog;

function ExcelFileParser($logfile="",$level=ABC_NO_LOG) {
$this->dbglog = &DebugOut::getWriterSingleton($logfile,"",$level);
$this->dbglog->info ("ロガーが開始されました");
}function PopulateFormat() {
$this->dbglog->trace(" PopulateFormat() 関数呼び出し");
$ret = array (
0=> "全般",
1=> "0"、
2=> "#,##0"、
4=> "#,##0.00"、
5=> ; " ($#,##0_);($#,##0)",
6=> "($#,##0_);[赤]($#,##0)",
7= > "($#,##0.00);($#,##0.00)",
8=> "($#,##0.00_);[赤]($#,##0.00)" ,
9=> "0%",
0xa=> "0.00E+00",
0xc=> 0xd=> "# ??/??",
0xe=> "m/d/yy",
0xf=> "d-mmm-yy",
0x11=> ; "mmm-yy",
0x12=> "h:mm AM/PM",
0x13=> "h:mm:ss AM/PM",
0x15 => "h:mm:ss",
0x16=> "m/d/yy h:mm",
"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",
0x25=> "(#,##0_);(#,##0)",
0x26=> "(#,##0_);[赤](#,##0)",
0x27=> "(#,##0.00_);(#,##0.00)",
0x28=> "(#,##0.00_);[赤](#,##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- >ダンプ($ret,"$ret");
            $this->dbglog->trace("populateFormat() function return");
return $ret;
}function xls2tstamp($date) {
$date=$date>25568?$date:25569;
$ ofs=(70 * 365 + 17+2) * 86400;
return ($date * 86400) - $ofs;
}関数 getDateArray($date) {
return ExcelDateUtil::getDateArray($date);
}関数 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+) ([^]]*])/","1'.''.'3'",$this->format[$f_i]);
if(preg_match("/[m|d|y] /i",$tmp)!=0)
return TRUE;
else
return FALSE;
} else {
return TRUE;
}} else
return FALSE;
}function getUnicodeString($str,$ofs){
$size=0;
$i_ofs=0;
return substr($str,$ofs+$i_ofs+1,$size);
}function getByteString($str,$ofs){
$size=0;
$i_ofs =0;
$size=ord($str[$ofs]);
$i_ofs=1;
}
function get_blocks_chain($start,$small_fat=false) {
$this->dbglog->trace( "get_blocks_chain(".var_export($start,true).",".var_export($small_fat,true).") 関数呼び出し ");
$chain = array();
$next_block = $start;
if( !$small_fat ) {
while( ($next_block!=0xfffffffe) &&
($next_block <= $this->max_blocks) &&
($next_block < count($this->fat)) )
{
$chain[] = $next_block;
$next_block = $this->fat[$next_block];
}} else {
while( ($next_block!= 0xfffffffe) &&
($next_block <= $this->max_sblocks) &&
($next_block < count($this->sfat)) )
{
$chain[] = $next_block;
$next_block = $this->sfat[$next_block];
}}if( $next_block != 0xfffffffe )
return false;
$this->dbglog->dump($chain,"$chain");
$this ->dbglog->trace("get_blocks_chain() function return");
return $chain;
}
function find_stream( $dir, $item_name,$item_num=0) {
$this->dbglog-> ;trace("find_stream(".var_export($dir,true).",".var_export($item_name,true).",".var_export($item_num,true).") 関数呼び出し ");
$dt = $dir->getOrd( $item_num * 0x80 + 0x42 );
$prev = $dir->getLong( $item_num * 0x80 + 0x44 );
$next = $dir->getLong( $item_num * 0x80 + 0x48 );
$dir_ = $dir->getLong( $item_num * 0x80 + 0x4c );
$curr_name = '';
if( ($dt==2) || ($dt==5) )
for( $i=0;
$i < ( $dir->getOrd( $item_num * 0x80 + 0x40 ) +
256 * $dir->getOrd( $item_num * 0x80 + 0x41 ) )/2- 1;
$i++ )
$curr_name .= $dir->getByte( $item_num * 0x80 + $i * 2 );
if( (($dt==2) || ($dt==5)) && (strcmp($curr_name,$item_name)==0) ){
$this->dbglog->trace("find_stream() 関数は ".var_export($item_num, true));
return $item_num;
}if( $prev != 0xffffffff ) {
$i = $this->find_stream( $dir, $item_name, $prev);
if( $i>=0 ) {
$this->dbglog->trace("find_stream() function return with ".var_export($i,true));
return $i;
}}if( $next != 0xffffffff ) {
$ i = $this->find_stream( $dir, $item_name, $next);
if( $i>=0 ){
$this->dbglog->trace("find_stream() function return with ". var_export($i,true));
return $i;
}}if( $dir_ != 0xffffffff ) {
$i = $this->find_stream( $dir, $item_name, $dir_ );
if( $i>=0 ) {
$this->dbglog->trace("find_stream() function return with ".var_export($i,true));
return $i;
}} $this-> dbglog->trace("find_stream() function return with -1");
return -1;
}function rk_decode($rk) {
$this->dbglog->trace("rk_decode(".var_export) ($rk,true).") 関数呼び出し");
$res = array();
if( $rk & 2 ) {
$val = ($rk & 0xfffffffc) >> 2;
if( $rk & 1 ) $val = $val / 100;
if (((float)$val) == Floor((float)$val)){
$res['val'] = ( int)$val;
$res['type'] = 1;
} else {
$res['val'] = (float)$val;
$res['type'] = 2;
}} else {
$res['type'] = 2;
$frk = $rk;
$fexp = (($frk & 0x7ff00000) >> 20) - 1023;
$val = 1+(($frk & 0x000fffff) >> 2)/262144;
if( $fexp > 0 ) {
for( $i=0; $i$val *= 2;
} else {
if( $fexp==-1023 ) {
$val=0;
} else {
for( $i=0; $i$val /= 2;
}} if( $rk & 1 ) $val = $val / 100;
if( $rk & 0x80000000 ) $val = -$val;
$res['val'] = (float)$val;
}$this- >dbglog->trace("rk_decode() 関数の戻り値");
return $res;
}
function parse_worksheet($ws) {
$this->dbglog->debug("parse_worksheet(DATA) function ");
if( strlen($ws) <= 0 ){
$this->dbglog->trace("parse_worksheet() 関数は 7 を返します (データが見つかりません)");
return 7;
} if( strlen($ws) < 4 ){
$this->dbglog->trace("parse_worksheet() 関数は 6 (ファイル破損) を返します");
return 6;
}
if( strlen($ ws)< 256*ord($ws[3])+ord($ws[2]) ) return 6;
if( ord($ws[0]) != 0x09 ) return 6;
$vers = ord($ws[ 1]);
if( ($vers!=0) && ($vers!=2) && ($vers!=4) && ($vers!=8) )
return 8;
if( $vers!= 8 ) {
$biff_ver = ($ver+4)/2;
} else {
if( strlen($ws) switch( ord($ws[4])+256*ord ($ws[5]) ) {
case 0x0500:
if( ord($ws[0x0a])+256*ord($ws[0x0b]) < 1994 ) {
$biff_ver = 5;
} else {
switch(ord( $ws[8])+256*ord($ws[9]) ) {
case 2412:
case 3218:
case 3321:
$this->dbglog->debug("Parsed BIFF バージョンは 5");
$biff_ver = 5;
break;
default:
$this->dbglog->debug("解析された BIFF バージョンは 7");
$biff_ver = 7;
break;
}}break;
case 0x0600:
$this->dbglog->debug("解析された BIFF バージョンは 8");
$biff_ver = 8;
break;
default:
return 8;
}}if( $biff_ver < 5 ) {
$this->dbglog->debug("parse_worksheet() 関数が見つかりました ($biff_ver return 8;
}$ptr = 0;
$ data = array('biff_version' => $biff_ver );
while( (ord($ws[$ptr])!=0x0a) && ($ptr switch (ord($ ws[$ptr])+256*ord($ws[$ptr+1])) {
case 0x0203:
$this->dbglog->trace("found NUMBER");
if( ($biff_ver) $this->dbglog->trace("$biff_ver < 3 Break;");
Break;
}if( (ord($ws[$ptr+2])+256*ord ($ws[$ptr+3])) < 14 ){
$this->dbglog->debug("parse_worksheet() return 6");
return 6;
}$row = ord($ws) [$ptr+4])+256*ord($ws[$ptr+5]);
$col = ord($ws[$ptr+6])+256*ord($ws[$ptr+7] );
$num_lo = ExcelParserUtil::str2long(substr($ws,$ptr+10,4));
$num_hi = ExcelParserUtil::str2long(substr($ws,$ptr+14,4));
$ xf_i = ord($ws[$ptr+8])+256*ord($ws[$ptr+9]);
if($this->isDateFormat($xf_i)){
$data['cell' ][$row][$col]['type'] = 3;
} else {
$data['cell'][$row][$col]['type'] = 2;
}$fonti = $this->xf['font'][$xf_i];
$data['cell'][$row][$fc+$i]['f​​ont'] = $fonti;
$fexp = (($ num_hi & 0x7ff00000) >> 20) - 1023;
$val = 1+(($num_hi & 0x000fffff)+$num_lo/4294967296)/1048576;
if( $fexp > 0 ) {
for( $i =0; $i$val *= 2;
} else {
for( $i=0; $i$val /= 2;
}if( $num_hi & 0x80000000 ) $val = -$val;
$data['cell'][$row][$col]['data'] = (float)$val;
if( !isset( $data['max_row']) ||
($data['max_row'] < $row) )
$data['max_row'] = $row;
if( !isset($data['max_col']) ||
($data['max_col'] < $col) )
$data ['max_col'] = $col;
break;
case 0x027e:
  $this->dbglog->trace("RK が見つかりました");
if( ($biff_ver <3) ) Break;
if( (ord($ws[$ptr+2])+256*ord( $ws[$ptr+3])) < 0x0a )
return 6;
$row = ord($ws[$ptr+4])+256*ord($ws[$ptr+5]);
$ Col = ord($ws[$ptr+6])+256*ord($ws[$ptr+7]);
$xf_i = ord($ws[$ptr+8])+256*ord($ws [$ptr+9]);
$val = $this->rk_decode(
ExcelParserUtil::str2long(substr($ws,$ptr+10,4))
);
if($this->isDateFormat ($xf_i)==TRUE){
$data['cell'][$row][$col]['type'] = 3;
} else {
$data['cell'][$row][ $col]['type'] = $val['type'];
}$fonti = $this->xf['font'][$xf_i];
$data['cell'][$row] [$col]['font'] = $fonti;
$data['cell'][$row][$col]['data'] = $val['val'];
if( !isset($ data['max_row']) ||
($data['max_row'] < $row) )
$data['max_row'] = $row;
if( !isset($data['max_col']) ||
($data['max_col'] < $col) )
$data['max_col'] = $col;
break;
case 0x00bd:
$this->dbglog->trace("found MULL RK");
if( ($biff_ver $sz = ord($ws[$ptr+2])+256*ord($ws[$ptr+3]);
if ( $sz $row = ord($ws[$ptr+4])+256*ord($ws[$ptr+5]);
$fc = ord($ws[$ ptr+6])+256*ord($ws[$ptr+7]);
$lc = ord($ws[$ptr+$sz+2])+256*ord($ws[$ptr+$sz+ 3]);
for( $i=0; $i $val = $this->rk_decode(
ExcelParserUtil::str2long(substr($ws,$ptr+10+$i*6,4))
);
$xf_i=ord($ws [$ptr+8+$i*6])+256*ord($ws[($ptr+9+$i*6)]);
if($this->isDateFormat($xf_i)==TRUE ) {
$data['cell'][$row][$fc+$i]['type'] = 3;
} else {
$data['cell'][$row][$fc+$i] ['type'] = $val['type'];
} $fonti = $this->xf['font'][$xf_i];
$data['cell'][$row][$fc+ $i]['f​​ont'] = $fonti;
$data['cell'][$row][$fc+$i]['data'] = $val['val'];
}if( !isset ($data['max_row']) ||
($data['max_row'] < $row) )
$data['max_row'] = $row;
if( !isset($data['max_col' ]) ||
($data['max_col'] < $lc) )
$data['max_col'] = $lc;
break;
case 0x0204:
$this->dbglog->trace( "ラベルが見つかりました");
if( ($biff_ver < 3) ){
Break;
}if( (ord($ws[$ptr+2])+256*ord($ws[$ptr+3] )) < 8 ){
return 6;
}$row = ord($ws[$ptr+4])+256*ord($ws[$ptr+5]);
$col = ord($ws) [$ptr+6])+256*ord($ws[$ptr+7]);
$xf = ord($ws[$ptr+8])+256*ord($ws[$ptr+9] );
$fonti = $this->xf['font'][$xf];
$font = $this->fonts[$fonti];
$str_len = ord($ws[$ptr+10 ])+256*ord($ws[$ptr+11]);
if( $ptr+12+$str_len > strlen($ws) )
return 6;
$this->sst['unicode'][] = false;
$this->sst['data'][] = substr($ws,$ptr+ 12,$str_len);
$data['cell'][$row][$col]['type'] = 0;
$sst_ind = count($this->sst['data'])-1 ;
$data['cell'][$row][$col]['data'] = $sst_ind;
$data['cell'][$row][$col]['font'] = $fonti ;
if( !isset($data['max_row']) ||
($data['max_row'] < $row) )
$data['max_row'] = $row;
if( !isset( $data['max_col']) ||
($data['max_col'] < $col) )
$data['max_col'] = $col;
break;
case 0x00fd:
if( $biff_ver < ; 8 ) ブレーク;
if( (ord($ws[$ptr+2])+256*ord($ws[$ptr+3])) < 0x0a )
return 6;
$row = ord($ ws[$ptr+4])+256*ord($ws[$ptr+5]);
$col = ord($ws[$ptr+6])+256*ord($ws[$ptr+7] ]);
$xf = ord($ws[$ptr+8])+256*ord($ws[$ptr+9]);
$fonti = $this->xf['font'][$ xf];
$font = &$this->fonts[$fonti];
$data['cell'][$row][$col]['type'] = 0;
$sst_ind = ExcelParserUtil:: str2long(substr($ws,$ptr+10,4));
$data['cell'][$row][$col]['data'] = $sst_ind;
$data['cell'][ $row][$col]['font'] = $fonti;
if( !isset($data['max_row']) ||
($data['max_row'] < $row) )
$data['max_row'] = $row;
if( !isset($data['max_col']) ||
($data['max_col'] < $col) )
$data ['max_col'] = $col;
break;
default:
break;
} $ptr += 4+256*ord($ws[$ptr+3])+ord($ws[$ptr+2] );
} $this->dbglog->debug("parse_worksheet() 関数は ".var_export($data,true) を返します); /*DEBUG*/
return $data;
}
function parse_workbook( $f_header, $dp ) {
$this->dbglog->debug("parse_workbook() function");
$root_entry_block = $f_header- >getLong(0x30);
$num_fat_blocks = $f_header->getLong(0x2c);
 $this->dbglog->trace("ヘッダー解析済み");
$this->fat = array();
for( $i = 0; $i $ this->dbglog->trace("FOR LOOP iteration i =".$i);
$fat_block = $f_header->getLong( 0x4c + 4 * $i );
$fatbuf = $dp->> get( $fat_block * 0x200, 0x200 );
$fat = new DataProvider( $fatbuf, DP_STRING_SOURCE );
if( $fat->getSize() $this->dbglog->debug ("parse_workbook() 関数が見つかりました (strlen($fat) return 6;
}for( $j=0; $j$this->fat [] = $fat->getLong( $j * 4 );
$fat->close();
unset( $fat_block, $fatbuf, $fat );
} $this->dbglog-> dump( $this->fat, "$fat" );
if( count($this->fat) < $num_fat_blocks ) {
$this->dbglog->debug("parse_workbook() 関数found (count($this->fat) < $num_fat_blocks) returns 6");
return 6;
}$chain = $this->get_blocks_chain($root_entry_block);
$dir = new DataProvider( $dp ->ReadFromFat( $chain ), DP_STRING_SOURCE );
unset( $chain );
$this->sfat = array();
$small_block = $f_header->getLong( 0x3c );
if( $small_block != 0xfeffffff ) {
$root_entry_index = $this->find_stream( $dir, 'ルート エントリ');
if( $root_entry_index < 0 ) {
$this->dbglog->debug("parse_workbook() 関数が見つからないルート エントリが 6 を返します");
return 6;
}
$sdc_start_block = $dir->getLong( $root_entry_index * 0x80 + 0x74 );
$small_data_chain = $this->get_blocks_chain($sdc_start_block);
$this->gt;max_sblocks = count($small_data_chain) * 8;

$schain = $this->get_blocks_chain($small_block) ;
for( $i = 0; $i < count( $schain ); $i++ ) {

$sfatbuf = $dp->get( $schain[$i] * 0x200, 0x200 );
$sfat = new DataProvider( $sfatbuf, DP_STRING_SOURCE );
if( $sfat->getSize() < 0x200 ) {
$this->dbglog->debug("parse_workbook() 関数が見つかりました (strlen($sfat) <) ; 0x200) returns 6");
return 6;
}
for( $j=0; $j $this->sfat[] = $sfat->getLong( $j * 4 );

$sfat->close();
unset( $sfatbuf, $sfat );
} unset( $schain );
$sfcbuf = $dp->ReadFromFat( $small_data_chain );
$sdp = new DataProvider( $sfcbuf, DP_STRING_SOURCE );
unset( $sfcbuf, $small_data_chain );
}$workbook_index = $this->find_stream( $dir, 'Workbook' );
if( $workbook_index<0 ) {
$workbook_index = $this->find_stream( $dir, 'Book' );
if( $workbook_index<0 ){
$this->dbglog->debug("parse_workbook() 関数のワークブック インデックスが見つかりませんでした。7 を返します");
return 7;
}}$workbook_start_block = $dir->getLong( $workbook_index * 0x80 + 0x74 );
$workbook_length = $dir->getLong( $workbook_index * 0x80 + 0x78 );
$wb = '';
if( $workbook_length > 0 ) {
if( $workbook_length >= 0x1000 ) {
$chain = $this->gt;get_blocks_chain($workbook_start_block);
$wb = $dp->ReadFromFat( $chain );
} else {
$ chain = $this->get_blocks_chain($workbook_start_block,true);
$wb = $sdp->ReadFromFat( $chain, 0x40 );
unset( $sdp );
}$wb = substr($wb,0 ,$workbook_length);
if( strlen($wb) != $workbook_length )
return 6;
unset( $chain );
}
unset( $this->fat, $this->sfat );
if( strlen($wb) <= 0 ) {
$this->dbglog->debug("parse_workbook() function workbook found (strlen($wb) return 7;
}if( strlen($wb) < 4 ) {
$this->dbglog->debug("parse_workbook() 関数ワークブックが見つかりました (strlen($wb) return 6;
}
if( strlen($wb) < 256*ord($wb[3])+ord($wb[2]) ){
$this->dbglog->debug(" parse_workbook() 関数ワークブックが見つかりました (strlen($wb) return 6;
}if ( ord($wb[0]) != 0x09 ){
 $this->dbglog->debug("parse_workbook() 関数ワークブックが見つかりました (ord($wb[0]) != 0x09) returns 6");
return 6;
}$vers = ord($wb[ 1]);
if( ($vers!=0) && ($vers!=2) && ($vers!=4) && ($vers!=8) ){
return 8;
}if( $vers! !=8 )
$biff_ver = ($ver+4)/2;
else {
if( strlen($wb) switch( ord($wb[4])+256*ord ($wb[5]) )
{
case 0x0500:
if( ord($wb[0x0a])+256*ord($wb[0x0b]) $biff_ver = 5;
else {
switch(ord( $wb[8])+256*ord($wb[9]) ) {
case 2412:
case 3218:
case 3321:
$biff_ver = 5;
break;
default:
$biff_ver = 7;
break;
}}break;
case 0x0600:
$biff_ver = 8;
break;
default:
return 8;
}}if( $biff_ver < 5 ) return 8;
$ptr = 0 ;
$this->worksheet['offset'] = array();
$this->worksheet['options'] = array();
$this->worksheet['unicode'] = array( );
$this->worksheet['name'] = array();
$this->worksheet['data'] = array();
$this->format = $this->populateFormat ();
$this->fonts = array();
$this->fonts[0] = ExcelFont::basicFontRecord();
$this->xf = array();
$this-> ;xf['format'] = array();
$this->xf['font'] = array();
$this->xf['type_prot'] = array();
$this- >xf['alignment'] = array();
$this->xf['decoration'] = array();
$xf_cnt=0;
$this->sst['unicode'] = 配列();
$this->sst['data'] = array();
$opcode = 0;
$sst_define = false;
$wblen = strlen($wb);
while( (ord($wb) [$ptr])!=0x0a) && ($ptr{
$oc = ord($wb[$ptr])+256*ord($wb[$ptr+1]);
if ( $oc != 0x3c )
$opcode = $oc;
switch ($opcode)
{
case 0x0085:
$ofs = ExcelParserUtil::str2long(substr($wb,$ptr+4,4));
$this->worksheet['offset'][] = $ofs;
$this->worksheet['options'][] = ord($wb[$ptr+8])+256*ord($wb) [$ptr+9]);
if( $biff_ver==8 ) {
$len = ord($wb[$ptr+10]);
if( (ord($wb[$ptr+11]) & 1) > 0 ) {
$this->worksheet['unicode'][] = true;
$len = $len*2;
} else {
$this->worksheet['unicode'][] = false;
} $this->worksheet['name'][] = substr($wb,$ptr+12,$len);
} else {
$this->worksheet['unicode'][] = false ;
$len = ord($wb[$ptr+10]);
$this->worksheet['name'][] = substr($wb,$ptr+11,$len);
}$pws = $this->parse_worksheet(substr($wb,$ofs));
if( is_array($pws) )
$this->worksheet['data'][] = $pws;
else
return $ pws;
break;
case 0x041e:
$fidx = ord($wb[$ptr+4])+256*ord($wb[$ptr+5]);
if($fidx<0x31 ||$fidx ==0x31 )
break;
elseif($biff_ver>7)
$this->format[$fidx] = $this->getUnicodeString($wb,$ptr+6);
break;
case EXCEL_FONT_RID:
$rec = ExcelFont::getFontRecord($wb,$ptr+4);
$this->fonts[count($this->fonts)] = $rec;
Break;
case 0x00e0:
$this ->xf['font'][$xf_cnt] = ord($wb[$ptr+4])+256*ord($wb[$ptr+5]);
$this->xf['format '][$xf_cnt] = ord($wb[$ptr+6])+256*ord($wb[$ptr+7]);
$this->xf['type'][$xf_cnt] = "1";
$this->xf['bitmask'][$xf_cnt] = "1";
$xf_cnt++;
Break;
case 0x00fc:
if( $biff_ver < 8 ) ブレーク;
$sbuflen = ord($wb[$ptr+2]) + 256*ord($wb[$ptr+3]);
if( $oc != 0x3c ) {
if( $sst_define ) return 6;
$snum = ExcelParserUtil::str2long(substr($wb,$ptr+8,4));
$sptr = $ptr+12;
$sst_define = true;
} else {
if( $rslen > $slen ) {
$sptr = $ptr+4;
$rslen -= $slen;
$slen = $rslen;
if( (ord($wb[$sptr]) > 0 ) {
if( $char_bytes == 1 ) {
$sstr = '';
for( $i=0; $i$sstr .= $str[$i]。 chr(0);
$str = $sstr;
$char_bytes=2;
} $schar_bytes = 2;
} else {
$schar_bytes = 1;
}if( $sptr+$slen*$schar_bytes > $ptr +4+$sbuflen )
$slen = ($ptr+$sbuflen-$sptr+3)/$schar_bytes;
$sstr = substr($wb,$sptr+1,$slen*$schar_bytes);
if( ( $char_bytes == 2) && ($schar_bytes == 1) )
{
$sstr2 = '';
for( $i=0; $i$sstr2 .= $sstr[$i].chr(0);
$sstr = $sstr2;
}$str .= $sstr;
$sptr += $slen*$schar_bytes+1+4*$rt+$fesz;
if( $slen < $rslen ) {
if( ($sptr >= strlen) ($wb)) ||
($sptr < $ptr+4+$sbuflen) ||
(ord($wb[$sptr]) != 0x3c) )
{
return 6;
}break;
} else {
if( $char_bytes == 2 ) {
$this->sst['unicode'][] = true;
} else {
$this->sst['unicode'][] = false ;
}$this->sst['data'][] = $str;
$snum--;
} } else {
$sptr = $ptr+4;
if( $sptr > $ptr ) $sptr += 4*$rt+$fesz;
}}while( ($sptr < $ptr+4+$sbuflen) &&
($sptr < strlen($wb)) &&
($snum > 0 ) )
{
$rslen = ord($wb[$sptr])+256*ord($wb[$sptr+1]);
$slen = $rslen;
if( (ord($wb[$sptr]) +2]) & 1) > 0 ) {
$char_bytes = 2;
} else {
$char_bytes = 1;
} $rt = 0;
$fesz = 0;
switch (ord($wb[$ sptr+2]) & 0x0c) {
case 0x0c:
$rt = ord($wb[$sptr+3])+256*(ord($wb[$sptr+4]));
$fesz = ExcelParserUtil ::str2long(substr($wb,$sptr+5,4));
if( $sptr+9+$slen*$char_bytes > $ptr+4+$sbuflen )
$slen = ($ptr+$sbuflen -$sptr-5)/$char_bytes;
$str = substr($wb,$sptr+9,$slen*$char_bytes);
$sptr += $slen*$char_bytes+9;
break;
ケース 8 :
$rt = ord($wb[$sptr+3])+256*(ord($wb[$sptr+4]));
if( $sptr+5+$slen*$char_bytes > $ptr+4+$sbuflen )
$slen = ($ptr+$sbuflen-$sptr-1)/$char_bytes;
$str = substr($wb,$sptr+5,$slen*$char_bytes);
$ sptr += $slen*$char_bytes+5;
break;
case 4:
$fesz = ExcelParserUtil::str2long(substr($wb,$sptr+3,4));
if( $sptr+7+$ slen*$char_bytes > $ptr+4+$sbuflen )
$slen = ($ptr+$sbuflen-$sptr-3)/$char_bytes;
$str = substr($wb,$sptr+7,$slen* $char_bytes);
$sptr += $slen*$char_bytes+7;
break;
case 0:
if( $sptr+3+$slen*$char_bytes > $ptr+4+$sbuflen )
$slen = ($ptr+$sbuflen-$sptr+1)/$char_bytes;
$str = substr($wb,$sptr+3,$slen*$char_bytes);
$sptr += $slen*$char_bytes+3;
break;
} if( $slen < $rslen ) {
if( ($sptr >= strlen($wb)) ||
($sptr < $ptr+4+$sbuflen) ||
( ord($wb[$sptr]) != 0x3c) ) return 6;
} else {
if( $char_bytes == 2 ) {
$this->sst['unicode'][] = true;
} else {
$this->sst['unicode'][] = false;
}$sptr += 4*$rt+$fesz;
$this->sst['data'][] = $str;
$snum--;
}}
break;
}
$ptr += 4+256*ord($wb[$ptr+3])+ord($wb[$ptr+2]);
}
$this->biff_version = $biff_ver;
$this->dbglog->debug("parse_workbook() 関数は 0 を返します");
return 0;
}
function ParseFromString( $contents )
{
$this ->dbglog->gt;info("ParseFromString() enter.");
$this->dp = new DataProvider( $contents, DP_STRING_SOURCE );
return $this->InitParser();
}関数 ParseFromFile ( $filename )
{
$this->dbglog->info("ParseFromFile() enter.");
$this->dp = new DataProvider( $filename, DP_FILE_SOURCE );
return $this-> ;InitParser();
}function InitParser()
{
$this->dbglog->info("InitParser() enter.");
if( !$this->dp->isValid() )
{
$this->dbglog->error("InitParser() ファイルを開けませんでした。");
$this->dbglog->error("InitParser() 関数は 1 を返します");
return 1;
}if( $this->dp->getSize() <= 0x200 )
{
$this->dbglog->error("InitParser() ファイルが小さすぎて Excel ファイルになりません.");
$this->dbglog->error("InitParser() 関数が 2 を返します");
return 2;
}$this->max_blocks = $this->dp->getBlocks( );
$hdrbuf = $this->dp->get( 0, 0x200 );
if( strlen( $hdrbuf ) < 0x200 )
{
$this->dbglog->error("InitParser() ヘッダー読み取りエラー。");
$this->dbglog->error("InitParser() 関数は 3 を返します");
return 3;
}
$header_sig = array(0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1);
for( $i = 0; $i < count($header_sig); $i++ )
if( $header_sig[$i] != ord( $hdrbuf[$i] ) ){
$this->dbglog->error("InitParser() 関数が無効なヘッダーを見つけました");
$this-> dbglog->error("InitParser() 関数が 5 を返します");
return 5;
}$f_header = new DataProvider( $hdrbuf, DP_STRING_SOURCE );
unset( $hdrbuf, $header_sig, $i );
$this->dp->_baseOfs = 0x200;
$rc = $this ->parse_workbook( $f_header, $this->dp );
unset( $f_header );
unset( $this->dp, $this->max_blocks, $this->max_sblocks );
return $rc;
}}
function unescape($str) {
$str = rawurldecode($str);
preg_match_all("/(?:%u.{4})|.{4};|& #d+;|.+/U",$str,$r);
$ar = $r[0];
foreach($ar as $k=>$v) {
if(substr($v, 0,2) == "%u")
$ar[$k] = iconv("UCS-2","GB2312",pack("H4",substr($v,-4)));
elseif (substr($v,0,3) == "")
$ar[$k] = iconv("UCS-2","GB2312",pack("H4",substr($v,3) ,-1)));
elseif(substr($v,0,2) == "") {
$ar[$k] = iconv("UCS-2","GB2312",pack(" n",substr($v,2,-1)));
}
}
return join("",$ar);
}
function uc2html($str) {
$ret = '';
for ( $i=0; $i$charcode = ord($str[$i*2])+256*ord($str[$i*2+1] ]);
$ret .= ''.$charcode.';';
}return $ret;
}
function Read_Excel_File($ExcelFile,&$result) {
$exc = new ExcelFileParser("", ABC_NO_LOG );
$res=$exc->ParseFromFile($ExcelFile);$result=null;
switch ($res) {
case 0: Break;
case 1: $err="無法打开文件";休憩;
ケース 2: $err="文件太小,可能性無し Excel 文件";休憩;
ケース 3: $err="文件头读取错误";休憩;
ケース 4: $err="读取文件時出错"; Break;
ケース 5: $err="これは Excel 文書または Excel5.0 以前のバージョンの本文";休憩;
ケース 6: $err="文件损坏"; Break;
ケース 7: $err="在文件中没有発行现Excelデータベース";休憩;
ケース 8: $err="不サポートな文書バージョン"; Break;
デフォルト:
$err="不明错误"; Break;
}
for( $ws_num=0; $ws_numworksheet['name']); $ws_num++ )
{
$Sheetname=$exc->worksheet['name'] [$ws_num]; 
$ws = $exc->worksheet['data'][$ws_num]; 
for( $j=0; $j for( $i=0; $i $データ = $ws['セル'][$j][$i]; 
switch ($data['type']) {
case 0:
$ind = $data['data'];
if( $exc->sst['unicode'][$ind] ) {
$ s = unescape(uc2html($exc->sst['data'][$ind]));
} else
$s = $exc->sst['data'][$ind];
if( strlen(trim($s))==0 )
$V="";
else
$V=$s;
break;
case 1:
$V=(int)($data['data'] );
break;
ケース 2:
$V=(float)($data['data']);
break;
ケース 3:
$ret = $exc->getDateArray($data['data' ]);
$V=$ret['年']."-".$ret['月']."-".$ret['日']." ".$ret['時間'];
break;
default:
break;
}
$result[$Sheetname][$j][$i]=$V;
}
}
}
if ($err=='') {return 0; } else {return $err;}
}
?>


www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/445084.html技術記事 ?定義('ABC_CRITICAL', 0);定義('ABC_ERROR', 1);定義('ABC_ALERT', 2);定義('ABC_WARNING', 3);定義('ABC_NOTICE', 4);定義('ABC_INFO', 5);定義('ABC_DEBUG', 6);定義します...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。