Source for file reader.php

Documentation is available at reader.php

  1. <?php
  2.  
  3. //require_once 'PEAR.php';
  4. require_once 'oleread.inc';
  5.  
  6. define('Spreadsheet_Excel_Reader_HAVE_ICONV'function_exists('iconv'));
  7.  
  8. define('Spreadsheet_Excel_Reader_BIFF8'0x600);
  9. define('Spreadsheet_Excel_Reader_BIFF7'0x500);
  10. define('Spreadsheet_Excel_Reader_WorkbookGlobals'0x5);
  11. define('Spreadsheet_Excel_Reader_Worksheet'0x10);
  12.  
  13. define('Spreadsheet_Excel_Reader_Type_BOF'0x809);
  14. define('Spreadsheet_Excel_Reader_Type_EOF'0x0a);
  15. define('Spreadsheet_Excel_Reader_Type_BOUNDSHEET'0x85);
  16. define('Spreadsheet_Excel_Reader_Type_DIMENSION'0x200);
  17. define('Spreadsheet_Excel_Reader_Type_ROW'0x208);
  18. define('Spreadsheet_Excel_Reader_Type_DBCELL'0xd7);
  19. define('Spreadsheet_Excel_Reader_Type_FILEPASS'0x2f);
  20. define('Spreadsheet_Excel_Reader_Type_NOTE'0x1c);
  21. define('Spreadsheet_Excel_Reader_Type_TXO'0x1b6);
  22. define('Spreadsheet_Excel_Reader_Type_RK'0x7e);
  23. define('Spreadsheet_Excel_Reader_Type_RK2'0x27e);
  24. define('Spreadsheet_Excel_Reader_Type_MULRK'0xbd);
  25. define('Spreadsheet_Excel_Reader_Type_MULBLANK'0xbe);
  26. define('Spreadsheet_Excel_Reader_Type_INDEX'0x20b);
  27. define('Spreadsheet_Excel_Reader_Type_SST'0xfc);
  28. define('Spreadsheet_Excel_Reader_Type_EXTSST'0xff);
  29. define('Spreadsheet_Excel_Reader_Type_CONTINUE'0x3c);
  30. define('Spreadsheet_Excel_Reader_Type_LABEL'0x204);
  31. define('Spreadsheet_Excel_Reader_Type_LABELSST'0xfd);
  32. define('Spreadsheet_Excel_Reader_Type_NUMBER'0x203);
  33. define('Spreadsheet_Excel_Reader_Type_NAME'0x18);
  34. define('Spreadsheet_Excel_Reader_Type_ARRAY'0x221);
  35. define('Spreadsheet_Excel_Reader_Type_STRING'0x207);
  36. define('Spreadsheet_Excel_Reader_Type_FORMULA'0x406);
  37. define('Spreadsheet_Excel_Reader_Type_FORMULA2'0x6);
  38. define('Spreadsheet_Excel_Reader_Type_FORMAT'0x41e);
  39. define('Spreadsheet_Excel_Reader_Type_XF'0xe0);
  40. define('Spreadsheet_Excel_Reader_Type_BOOLERR'0x205);
  41. define('Spreadsheet_Excel_Reader_Type_UNKNOWN'0xffff);
  42. define('Spreadsheet_Excel_Reader_Type_NINETEENFOUR'0x22);
  43. define('Spreadsheet_Excel_Reader_Type_MERGEDCELLS'0xE5);
  44.  
  45. define('Spreadsheet_Excel_Reader_utcOffsetDays' 25569);
  46. define('Spreadsheet_Excel_Reader_utcOffsetDays1904'24107);
  47. define('Spreadsheet_Excel_Reader_msInADay'24 60 60);
  48.  
  49. //define('Spreadsheet_Excel_Reader_DEF_NUM_FORMAT', "%.2f");
  50. define('Spreadsheet_Excel_Reader_DEF_NUM_FORMAT'"%s");
  51.  
  52. // function file_get_contents for PHP < 4.3.0
  53. // Thanks Marian Steinbach for this function
  54. if (!function_exists('file_get_contents')) {
  55.     function file_get_contents($filename$use_include_path 0{
  56.         $data '';
  57.         $file @fopen($filename"rb"$use_include_path);
  58.         if ($file{
  59.             while (!feof($file)) $data .= fread($file1024);
  60.             fclose($file);
  61.         else {
  62.             // There was a problem opening the file
  63.             $data FALSE;
  64.         }
  65.         return $data;
  66.     }
  67. }
  68.  
  69.  
  70. //class Spreadsheet_Excel_Reader extends PEAR {
  71.  
  72.     var $boundsheets = array();
  73.     var $formatRecords = array();
  74.     var $sst = array();
  75.     var $sheets = array();
  76.     var $data;
  77.     var $pos;
  78.     var $_ole;
  79.     var $_defaultEncoding;
  80.     var $_defaultFormat = Spreadsheet_Excel_Reader_DEF_NUM_FORMAT;
  81.     var $_columnsFormat = array();
  82.  
  83.     var $dateFormats = array (
  84.         0xe => "d/m/Y",
  85.         0xf => "d-M-Y",
  86.         0x10 => "d-M",
  87.         0x11 => "M-Y",
  88.         0x12 => "h:i a",
  89.         0x13 => "h:i:s a",
  90.         0x14 => "H:i",
  91.         0x15 => "H:i:s",
  92.         0x16 => "d/m/Y H:i",
  93.         0x2d => "i:s",
  94.         0x2e => "H:i:s",
  95.         0x2f => "i:s.S");
  96.  
  97.     var $numberFormats = array(
  98.         0x1 => "%1.0f"// "0"
  99.         0x2 => "%1.2f"// "0.00",
  100.         0x3 => "%1.0f"//"#,##0",
  101.         0x4 => "%1.2f"//"#,##0.00",
  102.         0x5 => "%1.0f"/*"$#,##0;($#,##0)",*/
  103.         0x6 => '$%1.0f'/*"$#,##0;($#,##0)",*/
  104.         0x7 => '$%1.2f'//"$#,##0.00;($#,##0.00)",
  105.         0x8 => '$%1.2f'//"$#,##0.00;($#,##0.00)",
  106.         0x9 => '%1.0f%%'// "0%"
  107.         0xa => '%1.2f%%'// "0.00%"
  108.         0xb => '%1.2f'// 0.00E00",
  109.         0x25 => '%1.0f'// "#,##0;(#,##0)",
  110.         0x26 => '%1.0f'//"#,##0;(#,##0)",
  111.         0x27 => '%1.2f'//"#,##0.00;(#,##0.00)",
  112.         0x28 => '%1.2f'//"#,##0.00;(#,##0.00)",
  113.         0x29 => '%1.0f'//"#,##0;(#,##0)",
  114.         0x2a => '$%1.0f'//"$#,##0;($#,##0)",
  115.         0x2b => '%1.2f'//"#,##0.00;(#,##0.00)",
  116.         0x2c => '$%1.2f'//"$#,##0.00;($#,##0.00)",
  117.         0x30 => '%1.0f')//"##0.0E0";
  118.  
  119.     function Spreadsheet_Excel_Reader(){
  120.         $this->_ole =new OLERead();
  121.  
  122.     }
  123.  
  124.     function setOutputEncoding($Encoding){
  125.         $this->_defaultEncoding = $Encoding;
  126.     }
  127.  
  128.     function setDefaultFormat($sFormat){
  129.         $this->_defaultFormat = $sFormat;
  130.     }
  131.  
  132.     function setColumnFormat($column$sFormat){
  133.         $this->_columnsFormat[$column$sFormat;
  134.     }
  135.  
  136.  
  137.     function read($sFileName{
  138.         $errlevel error_reporting();
  139.         error_reporting($errlevel E_NOTICE);
  140.  
  141.         $res $this->_ole->read($sFileName);
  142.         
  143.         // oops, something goes wrong (Darko Miljanovic)
  144.         if($res === false{
  145.             // check error code
  146.             if($this->_ole->error == 1{
  147.             // bad file
  148.                 die('The filename ' $sFileName ' is not readable');    
  149.             }
  150.             // check other error codes here (eg bad fileformat, etc...)
  151.         }
  152.  
  153.         $this->data = $this->_ole->getWorkBook();
  154.  
  155.         
  156.         /*
  157.         $res = $this->_ole->read($sFileName);
  158.  
  159.         if ($this->isError($res)) {
  160. //        var_dump($res);        
  161.             return $this->raiseError($res);
  162.         }
  163.  
  164.         $total = $this->_ole->ppsTotal();
  165.         for ($i = 0; $i < $total; $i++) {
  166.             if ($this->_ole->isFile($i)) {
  167.                 $type = unpack("v", $this->_ole->getData($i, 0, 2));
  168.                 if ($type[''] == 0x0809)  { // check if it's a BIFF stream
  169.                     $this->_index = $i;
  170.                     $this->data = $this->_ole->getData($i, 0, $this->_ole->getDataLength($i));
  171.                     break;
  172.                 }
  173.             }
  174.         }
  175.  
  176.         if ($this->_index === null) {
  177.             return $this->raiseError("$file doesn't seem to be an Excel file");
  178.         }
  179.         
  180.         */
  181.         
  182.         //var_dump($this->data);
  183.     //echo "data =".$this->data;    
  184.         $this->pos = 0;
  185.         //$this->readRecords();
  186.         $this->_parse();
  187.         error_reporting($errlevel);
  188.  
  189.     }
  190.  
  191.     function _parse(){
  192.         $pos 0;
  193.  
  194.         $code ord($this->data[$pos]ord($this->data[$pos+1])<<8;
  195.         $length ord($this->data[$pos+2]ord($this->data[$pos+3])<<8;
  196.  
  197.         $version ord($this->data[$pos 4]ord($this->data[$pos 5])<<8;
  198.         $substreamType ord($this->data[$pos 6]ord($this->data[$pos 7])<<8;
  199.         //echo "Start parse code=".base_convert($code,10,16)." version=".base_convert($version,10,16)." substreamType=".base_convert($substreamType,10,16).""."\n";
  200.  
  201.         if (($version != Spreadsheet_Excel_Reader_BIFF8&& ($version != Spreadsheet_Excel_Reader_BIFF7)) {
  202.             return false;
  203.         }
  204.  
  205.         if ($substreamType != Spreadsheet_Excel_Reader_WorkbookGlobals){
  206.             return false;
  207.         }
  208.  
  209.         //print_r($rec);
  210.         $pos += $length 4;
  211.  
  212.         $code ord($this->data[$pos]ord($this->data[$pos+1])<<8;
  213.         $length ord($this->data[$pos+2]ord($this->data[$pos+3])<<8;
  214.  
  215.         while ($code != Spreadsheet_Excel_Reader_Type_EOF){
  216.             switch ($code{
  217.                 case Spreadsheet_Excel_Reader_Type_SST:
  218.                     //echo "Type_SST\n";
  219.                      $spos $pos 4;
  220.                      $limitpos $spos $length;
  221.                      $uniqueStrings $this->_GetInt4d($this->data$spos+4);
  222.                                                 $spos += 8;
  223.                                        for ($i 0$i $uniqueStrings$i++{
  224.         // Read in the number of characters
  225.                                                 if ($spos == $limitpos{
  226.                                                 $opcode ord($this->data[$spos]ord($this->data[$spos+1])<<8;
  227.                                                 $conlength ord($this->data[$spos+2]ord($this->data[$spos+3])<<8;
  228.                                                         if ($opcode != 0x3c{
  229.                                                                 return -1;
  230.                                                         }
  231.                                                 $spos += 4;
  232.                                                 $limitpos $spos $conlength;
  233.                                                 }
  234.                                                 $numChars ord($this->data[$spos](ord($this->data[$spos+1]<< 8);
  235.                                                 //echo "i = $i pos = $pos numChars = $numChars ";
  236.                                                 $spos += 2;
  237.                                                 $optionFlags ord($this->data[$spos]);
  238.                                                 $spos++;
  239.                                         $asciiEncoding (($optionFlags 0x01== 0;
  240.                                                 $extendedString ( ($optionFlags 0x04!= 0);
  241.  
  242.                                                 // See if string contains formatting information
  243.                                                 $richString ( ($optionFlags 0x08!= 0);
  244.  
  245.                                                 if ($richString{
  246.                                         // Read in the crun
  247.                                                         $formattingRuns ord($this->data[$spos](ord($this->data[$spos+1]<< 8);
  248.                                                         $spos += 2;
  249.                                                 }
  250.  
  251.                                                 if ($extendedString{
  252.                                                   // Read in cchExtRst
  253.                                                   $extendedRunLength $this->_GetInt4d($this->data$spos);
  254.                                                   $spos += 4;
  255.                                                 }
  256.  
  257.                                                 $len ($asciiEncoding)$numChars $numChars*2;
  258.                                                 if ($spos $len $limitpos{
  259.                                                                 $retstr substr($this->data$spos$len);
  260.                                                                 $spos += $len;
  261.                                                 }else{
  262.                                                         // found countinue
  263.                                                         $retstr substr($this->data$spos$limitpos $spos);
  264.                                                         $bytesRead $limitpos $spos;
  265.                                                         $charsLeft $numChars (($asciiEncoding$bytesRead ($bytesRead 2));
  266.                                                         $spos $limitpos;
  267.  
  268.                                                          while ($charsLeft 0){
  269.                                                                 $opcode ord($this->data[$spos]ord($this->data[$spos+1])<<8;
  270.                                                                 $conlength ord($this->data[$spos+2]ord($this->data[$spos+3])<<8;
  271.                                                                         if ($opcode != 0x3c{
  272.                                                                                 return -1;
  273.                                                                         }
  274.                                                                 $spos += 4;
  275.                                                                 $limitpos $spos $conlength;
  276.                                                                 $option ord($this->data[$spos]);
  277.                                                                 $spos += 1;
  278.                                                                   if ($asciiEncoding && ($option == 0)) {
  279.                                                                                 $len min($charsLeft$limitpos $spos)// min($charsLeft, $conlength);
  280.                                                                     $retstr .= substr($this->data$spos$len);
  281.                                                                     $charsLeft -= $len;
  282.                                                                     $asciiEncoding true;
  283.                                                                   }elseif (!$asciiEncoding && ($option != 0)){
  284.                                                                                 $len min($charsLeft 2$limitpos $spos)// min($charsLeft, $conlength);
  285.                                                                     $retstr .= substr($this->data$spos$len);
  286.                                                                     $charsLeft -= $len/2;
  287.                                                                     $asciiEncoding false;
  288.                                                                   }elseif (!$asciiEncoding && ($option == 0)) {
  289.                                                                 // Bummer - the string starts off as Unicode, but after the
  290.                                                                 // continuation it is in straightforward ASCII encoding
  291.                                                                                 $len min($charsLeft$limitpos $spos)// min($charsLeft, $conlength);
  292.                                                                         for ($j 0$j $len$j++{
  293.                                                                  $retstr .= $this->data[$spos $j].chr(0);
  294.                                                                 }
  295.                                                             $charsLeft -= $len;
  296.                                                                 $asciiEncoding false;
  297.                                                                   }else{
  298.                                                             $newstr '';
  299.                                                                     for ($j 0$j strlen($retstr)$j++{
  300.                                                                       $newstr $retstr[$j].chr(0);
  301.                                                                     }
  302.                                                                     $retstr $newstr;
  303.                                                                                 $len min($charsLeft 2$limitpos $spos)// min($charsLeft, $conlength);
  304.                                                                     $retstr .= substr($this->data$spos$len);
  305.                                                                     $charsLeft -= $len/2;
  306.                                                                     $asciiEncoding false;
  307.                                                                         //echo "Izavrat\n";
  308.                                                                   }
  309.                                                           $spos += $len;
  310.  
  311.                                                          }
  312.                                                 }
  313.                                                 $retstr ($asciiEncoding$retstr $this->_encodeUTF16($retstr);
  314. //                                              echo "Str $i = $retstr\n";
  315.                                         if ($richString){
  316.                                                   $spos += $formattingRuns;
  317.                                                 }
  318.  
  319.                                                 // For extended strings, skip over the extended string data
  320.                                                 if ($extendedString{
  321.                                                   $spos += $extendedRunLength;
  322.                                                 }
  323.                                                         //if ($retstr == 'Derby'){
  324.                                                         //      echo "bb\n";
  325.                                                         //}
  326.                                                 $this->sst[]=$retstr;
  327.                                        }
  328.                     /*$continueRecords = array();
  329.                     while ($this->getNextCode() == Type_CONTINUE) {
  330.                         $continueRecords[] = &$this->nextRecord();
  331.                     }
  332.                     //echo " 1 Type_SST\n";
  333.                     $this->shareStrings = new SSTRecord($r, $continueRecords);
  334.                     //print_r($this->shareStrings->strings);
  335.                      */
  336.                      // echo 'SST read: '.($time_end-$time_start)."\n";
  337.                     break;
  338.  
  339.                 case Spreadsheet_Excel_Reader_Type_FILEPASS:
  340.                     return false;
  341.                     break;
  342.                 case Spreadsheet_Excel_Reader_Type_NAME:
  343.                     //echo "Type_NAME\n";
  344.                     break;
  345.                 case Spreadsheet_Excel_Reader_Type_FORMAT:
  346.                         $indexCode ord($this->data[$pos+4]ord($this->data[$pos+5]<< 8;
  347.  
  348.                         if ($version == Spreadsheet_Excel_Reader_BIFF8{
  349.                             $numchars ord($this->data[$pos+6]ord($this->data[$pos+7]<< 8;
  350.                             if (ord($this->data[$pos+8]== 0){
  351.                                 $formatString substr($this->data$pos+9$numchars);
  352.                             else {
  353.                                 $formatString substr($this->data$pos+9$numchars*2);
  354.                             }
  355.                         else {
  356.                             $numchars ord($this->data[$pos+6]);
  357.                             $formatString substr($this->data$pos+7$numchars*2);
  358.                         }
  359.  
  360.                     $this->formatRecords[$indexCode$formatString;
  361.                    // echo "Type.FORMAT\n";
  362.                     break;
  363.                 case Spreadsheet_Excel_Reader_Type_XF:
  364.                         //global $dateFormats, $numberFormats;
  365.                         $indexCode ord($this->data[$pos+6]ord($this->data[$pos+7]<< 8;
  366.                         //echo "\nType.XF ".count($this->formatRecords['xfrecords'])." $indexCode ";
  367.                         if (array_key_exists($indexCode$this->dateFormats)) {
  368.                             //echo "isdate ".$dateFormats[$indexCode];
  369.                             $this->formatRecords['xfrecords'][array(
  370.                                     'type' => 'date',
  371.                                     'format' => $this->dateFormats[$indexCode]
  372.                                     );
  373.                         }elseif (array_key_exists($indexCode$this->numberFormats)) {
  374.                         //echo "isnumber ".$this->numberFormats[$indexCode];
  375.                             $this->formatRecords['xfrecords'][array(
  376.                                     'type' => 'number',
  377.                                     'format' => $this->numberFormats[$indexCode]
  378.                                     );
  379.                         }else{
  380.                             $isdate FALSE;
  381.                             if ($indexCode 0){
  382.                                 if (isset($this->formatRecords[$indexCode]))
  383.                                     $formatstr $this->formatRecords[$indexCode];
  384.                                 //echo '.other.';
  385.                                 //echo "\ndate-time=$formatstr=\n";
  386.                                 if ($formatstr)
  387.                                 if (preg_match("/[^hmsday\/\-:\s]/i"$formatstr== 0// found day and time format
  388.                                     $isdate TRUE;
  389.                                     $formatstr str_replace('mm''i'$formatstr);
  390.                                     $formatstr str_replace('h''H'$formatstr);
  391.                                     //echo "\ndate-time $formatstr \n";
  392.                                 }
  393.                             }
  394.  
  395.                             if ($isdate){
  396.                                 $this->formatRecords['xfrecords'][array(
  397.                                         'type' => 'date',
  398.                                         'format' => $formatstr,
  399.                                         );
  400.                             }else{
  401.                                 $this->formatRecords['xfrecords'][array(
  402.                                         'type' => 'other',
  403.                                         'format' => '',
  404.                                         'code' => $indexCode
  405.                                         );
  406.                             }
  407.                         }
  408.                         //echo "\n";
  409.                     break;
  410.                 case Spreadsheet_Excel_Reader_Type_NINETEENFOUR:
  411.                     //echo "Type.NINETEENFOUR\n";
  412.                     $this->nineteenFour (ord($this->data[$pos+4]== 1);
  413.                     break;
  414.                 case Spreadsheet_Excel_Reader_Type_BOUNDSHEET:
  415.                     //echo "Type.BOUNDSHEET\n";
  416.                         $rec_offset $this->_GetInt4d($this->data$pos+4);
  417.                         $rec_typeFlag ord($this->data[$pos+8]);
  418.                         $rec_visibilityFlag ord($this->data[$pos+9]);
  419.                         $rec_length ord($this->data[$pos+10]);
  420.  
  421.                         if ($version == Spreadsheet_Excel_Reader_BIFF8){
  422.                             $chartype =  ord($this->data[$pos+11]);
  423.                             if ($chartype == 0){
  424.                                 $rec_name    substr($this->data$pos+12$rec_length);
  425.                             else {
  426.                                 $rec_name    $this->_encodeUTF16(substr($this->data$pos+12$rec_length*2));
  427.                             }
  428.                         }elseif ($version == Spreadsheet_Excel_Reader_BIFF7){
  429.                                 $rec_name    substr($this->data$pos+11$rec_length);
  430.                         }
  431.                     $this->boundsheets[array('name'=>$rec_name,
  432.                                                  'offset'=>$rec_offset);
  433.  
  434.                     break;
  435.  
  436.             }
  437.  
  438.             //echo "Code = ".base_convert($r['code'],10,16)."\n";
  439.             $pos += $length 4;
  440.             $code ord($this->data[$pos]ord($this->data[$pos+1])<<8;
  441.             $length ord($this->data[$pos+2]ord($this->data[$pos+3])<<8;
  442.  
  443.             //$r = &$this->nextRecord();
  444.             //echo "1 Code = ".base_convert($r['code'],10,16)."\n";
  445.         }
  446.  
  447.         foreach ($this->boundsheets as $key=>$val){
  448.             $this->sn $key;
  449.             $this->_parsesheet($val['offset']);
  450.         }
  451.         return true;
  452.  
  453.     }
  454.  
  455.     function _parsesheet($spos){
  456.         $cont true;
  457.         // read BOF
  458.         $code ord($this->data[$spos]ord($this->data[$spos+1])<<8;
  459.         $length ord($this->data[$spos+2]ord($this->data[$spos+3])<<8;
  460.  
  461.         $version ord($this->data[$spos 4]ord($this->data[$spos 5])<<8;
  462.         $substreamType ord($this->data[$spos 6]ord($this->data[$spos 7])<<8;
  463.  
  464.         if (($version != Spreadsheet_Excel_Reader_BIFF8&& ($version != Spreadsheet_Excel_Reader_BIFF7)) {
  465.             return -1;
  466.         }
  467.  
  468.         if ($substreamType != Spreadsheet_Excel_Reader_Worksheet){
  469.             return -2;
  470.         }
  471.         //echo "Start parse code=".base_convert($code,10,16)." version=".base_convert($version,10,16)." substreamType=".base_convert($substreamType,10,16).""."\n";
  472.         $spos += $length 4;
  473.         //var_dump($this->formatRecords);
  474.     //echo "code $code $length";
  475.         while($cont{
  476.             //echo "mem= ".memory_get_usage()."\n";
  477. //            $r = &$this->file->nextRecord();
  478.             $lowcode ord($this->data[$spos]);
  479.             if ($lowcode == Spreadsheet_Excel_Reader_Type_EOFbreak;
  480.             $code $lowcode ord($this->data[$spos+1])<<8;
  481.             $length ord($this->data[$spos+2]ord($this->data[$spos+3])<<8;
  482.             $spos += 4;
  483.             //echo "Code=".base_convert($code,10,16)." $code\n";
  484.             unset($this->rectype);
  485.             $this->multiplier 1// need for format with %
  486.             switch ($code{
  487.                 case Spreadsheet_Excel_Reader_Type_DIMENSION:
  488.                     //echo 'Type_DIMENSION ';
  489.                     if (!isset($this->numRows)) {
  490.                         if (($length == 10||  ($version == Spreadsheet_Excel_Reader_BIFF7)){
  491.                             $this->sheets[$this->sn]['numRows'ord($this->data[$spos+2]ord($this->data[$spos+3]<< 8;
  492.                             $this->sheets[$this->sn]['numCols'ord($this->data[$spos+6]ord($this->data[$spos+7]<< 8;
  493.                         else {
  494.                             $this->sheets[$this->sn]['numRows'ord($this->data[$spos+4]ord($this->data[$spos+5]<< 8;
  495.                             $this->sheets[$this->sn]['numCols'ord($this->data[$spos+10]ord($this->data[$spos+11]<< 8;
  496.                         }
  497.                     }
  498.                     //echo 'numRows '.$this->numRows.' '.$this->numCols."\n";
  499.                     break;
  500.                 case Spreadsheet_Excel_Reader_Type_MERGEDCELLS:
  501.                     $cellRanges ord($this->data[$spos]ord($this->data[$spos+1])<<8;
  502.                     for ($i 0$i $cellRanges$i++{
  503.                         $fr =  ord($this->data[$spos 8*$i 2]ord($this->data[$spos 8*$i 3])<<8;
  504.                         $lr =  ord($this->data[$spos 8*$i 4]ord($this->data[$spos 8*$i 5])<<8;
  505.                         $fc =  ord($this->data[$spos 8*$i 6]ord($this->data[$spos 8*$i 7])<<8;
  506.                         $lc =  ord($this->data[$spos 8*$i 8]ord($this->data[$spos 8*$i 9])<<8;
  507.                         //$this->sheets[$this->sn]['mergedCells'][] = array($fr + 1, $fc + 1, $lr + 1, $lc + 1);
  508.                         if ($lr $fr 0{
  509.                             $this->sheets[$this->sn]['cellsInfo'][$fr+1][$fc+1]['rowspan'$lr $fr 1;
  510.                         }
  511.                         if ($lc $fc 0{
  512.                             $this->sheets[$this->sn]['cellsInfo'][$fr+1][$fc+1]['colspan'$lc $fc 1;
  513.                         }
  514.                     }
  515.                     //echo "Merged Cells $cellRanges $lr $fr $lc $fc\n";
  516.                     break;
  517.                 case Spreadsheet_Excel_Reader_Type_RK:
  518.                 case Spreadsheet_Excel_Reader_Type_RK2:
  519.                     //echo 'Spreadsheet_Excel_Reader_Type_RK'."\n";
  520.                     $row ord($this->data[$spos]ord($this->data[$spos+1])<<8;
  521.                     $column ord($this->data[$spos+2]ord($this->data[$spos+3])<<8;
  522.                     $rknum $this->_GetInt4d($this->data$spos 6);
  523.                     $numValue $this->_GetIEEE754($rknum);
  524.                     //echo $numValue." ";
  525.                     if ($this->isDate($spos)) {
  526.                         list($string$raw$this->createDate($numValue);
  527.                     }else{
  528.                         $raw $numValue;
  529.                         if (isset($this->_columnsFormat[$column 1])){
  530.                                 $this->curformat $this->_columnsFormat[$column 1];
  531.                         }
  532.                         $string sprintf($this->curformat$numValue $this->multiplier);
  533.                         //$this->addcell(RKRecord($r));
  534.                     }
  535.                     $this->addcell($row$column$string$raw);
  536.                     //echo "Type_RK $row $column $string $raw {$this->curformat}\n";
  537.                     break;
  538.                 case Spreadsheet_Excel_Reader_Type_LABELSST:
  539.                         $row        ord($this->data[$spos]ord($this->data[$spos+1])<<8;
  540.                         $column     ord($this->data[$spos+2]ord($this->data[$spos+3])<<8;
  541.                         $xfindex    ord($this->data[$spos+4]ord($this->data[$spos+5])<<8;
  542.                         $index  $this->_GetInt4d($this->data$spos 6);
  543.             //var_dump($this->sst);
  544.                         $this->addcell($row$column$this->sst[$index]);
  545.                         //echo "LabelSST $row $column $string\n";
  546.                     break;
  547.                 case Spreadsheet_Excel_Reader_Type_MULRK:
  548.                     $row        ord($this->data[$spos]ord($this->data[$spos+1])<<8;
  549.                     $colFirst   ord($this->data[$spos+2]ord($this->data[$spos+3])<<8;
  550.                     $colLast    ord($this->data[$spos $length 2]ord($this->data[$spos $length 1])<<8;
  551.                     $columns    $colLast $colFirst 1;
  552.                     $tmppos $spos+4;
  553.                     for ($i 0$i $columns$i++{
  554.                         $numValue $this->_GetIEEE754($this->_GetInt4d($this->data$tmppos 2));
  555.                         if ($this->isDate($tmppos-4)) {
  556.                             list($string$raw$this->createDate($numValue);
  557.                         }else{
  558.                             $raw $numValue;
  559.                             if (isset($this->_columnsFormat[$colFirst $i 1])){
  560.                                         $this->curformat $this->_columnsFormat[$colFirst $i 1];
  561.                                 }
  562.                             $string sprintf($this->curformat$numValue $this->multiplier);
  563.                         }
  564.                       //$rec['rknumbers'][$i]['xfindex'] = ord($rec['data'][$pos]) | ord($rec['data'][$pos+1]) << 8;
  565.                       $tmppos += 6;
  566.                       $this->addcell($row$colFirst $i$string$raw);
  567.                       //echo "MULRK $row ".($colFirst + $i)." $string\n";
  568.                     }
  569.                      //MulRKRecord($r);
  570.                     // Get the individual cell records from the multiple record
  571.                      //$num = ;
  572.  
  573.                     break;
  574.                 case Spreadsheet_Excel_Reader_Type_NUMBER:
  575.                     $row    ord($this->data[$spos]ord($this->data[$spos+1])<<8;
  576.                     $column ord($this->data[$spos+2]ord($this->data[$spos+3])<<8;
  577.                     $tmp unpack("d"substr($this->data$spos 68))// It machine machine dependent
  578.                     if ($this->isDate($spos)) {
  579.                         list($string$raw$this->createDate($tmp['']);
  580.                      //   $this->addcell(DateRecord($r, 1));
  581.                     }else{
  582.                         //$raw = $tmp[''];
  583.                         if (isset($this->_columnsFormat[$column 1])){
  584.                                 $this->curformat $this->_columnsFormat[$column 1];
  585.                         }
  586.                         $raw $this->createNumber($spos);
  587.                         $string sprintf($this->curformat$raw $this->multiplier);
  588.  
  589.                      //   $this->addcell(NumberRecord($r));
  590.                     }
  591.                     $this->addcell($row$column$string$raw);
  592.                     //echo "Number $row $column $string\n";
  593.                     break;
  594.                 case Spreadsheet_Excel_Reader_Type_FORMULA:
  595.                 case Spreadsheet_Excel_Reader_Type_FORMULA2:
  596.                     $row    ord($this->data[$spos]ord($this->data[$spos+1])<<8;
  597.                     $column ord($this->data[$spos+2]ord($this->data[$spos+3])<<8;
  598.                     if ((ord($this->data[$spos+6])==0&& (ord($this->data[$spos+12])==255&& (ord($this->data[$spos+13])==255)) {
  599.                         //String formula. Result follows in a STRING record
  600.                         //echo "FORMULA $row $column Formula with a string<br>\n";
  601.                     elseif ((ord($this->data[$spos+6])==1&& (ord($this->data[$spos+12])==255&& (ord($this->data[$spos+13])==255)) {
  602.                         //Boolean formula. Result is in +2; 0=false,1=true
  603.                     elseif ((ord($this->data[$spos+6])==2&& (ord($this->data[$spos+12])==255&& (ord($this->data[$spos+13])==255)) {
  604.                         //Error formula. Error code is in +2;
  605.                     elseif ((ord($this->data[$spos+6])==3&& (ord($this->data[$spos+12])==255&& (ord($this->data[$spos+13])==255)) {
  606.                         //Formula result is a null string.
  607.                     else {
  608.                         // result is a number, so first 14 bytes are just like a _NUMBER record
  609.                         $tmp unpack("d"substr($this->data$spos 68))// It machine machine dependent
  610.                         if ($this->isDate($spos)) {
  611.                             list($string$raw$this->createDate($tmp['']);
  612.                          //   $this->addcell(DateRecord($r, 1));
  613.                         }else{
  614.                             $raw $tmp[''];
  615.                             if (isset($this->_columnsFormat[$column 1])){
  616.                                     $this->curformat $this->_columnsFormat[$column 1];
  617.                             }
  618.                             
  619.                             $string sprintf($this->curformat$tmp[''$this->multiplier);
  620.     
  621.                          //   $this->addcell(NumberRecord($r));
  622.                         }
  623.                         $this->addcell($row$column$string$raw);
  624.                         //echo "Number $row $column $string\n";
  625.                     }
  626.                     break;                    
  627.                 case Spreadsheet_Excel_Reader_Type_BOOLERR:
  628.                     $row    ord($this->data[$spos]ord($this->data[$spos+1])<<8;
  629.                     $column ord($this->data[$spos+2]ord($this->data[$spos+3])<<8;
  630.                     $string ord($this->data[$spos+6]);
  631.                     $this->addcell($row$column$string);
  632.                     //echo 'Type_BOOLERR '."\n";
  633.                     break;
  634.                 case Spreadsheet_Excel_Reader_Type_ROW:
  635.                 case Spreadsheet_Excel_Reader_Type_DBCELL:
  636.                 case Spreadsheet_Excel_Reader_Type_MULBLANK:
  637.                     break;
  638.                 case Spreadsheet_Excel_Reader_Type_LABEL:
  639.                     $row    ord($this->data[$spos]ord($this->data[$spos+1])<<8;
  640.                     $column ord($this->data[$spos+2]ord($this->data[$spos+3])<<8;
  641.                     $this->addcell($row$columnsubstr($this->data$spos 8ord($this->data[$spos 6]ord($this->data[$spos 7])<<8));
  642.  
  643.                    // $this->addcell(LabelRecord($r));
  644.                     break;
  645.  
  646.                 case Spreadsheet_Excel_Reader_Type_EOF:
  647.                     $cont false;
  648.                     break;
  649.                 default:
  650.                     //echo ' unknown :'.base_convert($r['code'],10,16)."\n";
  651.                     break;
  652.  
  653.             }
  654.             $spos += $length;
  655.         }
  656.  
  657.         if (!isset($this->sheets[$this->sn]['numRows']))
  658.              $this->sheets[$this->sn]['numRows'$this->sheets[$this->sn]['maxrow'];
  659.         if (!isset($this->sheets[$this->sn]['numCols']))
  660.              $this->sheets[$this->sn]['numCols'$this->sheets[$this->sn]['maxcol'];
  661.  
  662.     }
  663.  
  664.     function isDate($spos){
  665.         //$xfindex = GetInt2d(, 4);
  666.         $xfindex ord($this->data[$spos+4]ord($this->data[$spos+5]<< 8;
  667.         //echo 'check is date '.$xfindex.' '.$this->formatRecords['xfrecords'][$xfindex]['type']."\n";
  668.         //var_dump($this->formatRecords['xfrecords'][$xfindex]);
  669.         if ($this->formatRecords['xfrecords'][$xfindex]['type'== 'date'{
  670.             $this->curformat $this->formatRecords['xfrecords'][$xfindex]['format'];
  671.             $this->rectype 'date';
  672.             return true;
  673.         else {
  674.             if ($this->formatRecords['xfrecords'][$xfindex]['type'== 'number'{
  675.                 $this->curformat $this->formatRecords['xfrecords'][$xfindex]['format'];
  676.                 $this->rectype 'number';
  677.                 if (($xfindex == 0x9|| ($xfindex == 0xa)){
  678.                     $this->multiplier 100;
  679.                 }
  680.             }else{
  681.                 $this->curformat $this->_defaultFormat;
  682.                 $this->rectype 'unknown';
  683.             }
  684.             return false;
  685.         }
  686.     }
  687.  
  688.     function createDate($numValue){
  689.         if ($numValue 1){
  690.             $utcDays $numValue ($this->nineteenFour Spreadsheet_Excel_Reader_utcOffsetDays1904 Spreadsheet_Excel_Reader_utcOffsetDays);
  691.             $utcValue round($utcDays Spreadsheet_Excel_Reader_msInADay);
  692.             $string date ($this->curformat$utcValue);
  693.             $raw $utcValue;
  694.         }else{
  695.             $raw $numValue;
  696.             $hours floor($numValue 24);
  697.             $mins floor($numValue 24 60$hours 60;
  698.             $secs floor($numValue Spreadsheet_Excel_Reader_msInADay$hours 60 60 $mins 60;
  699.             $string date ($this->curformatmktime($hours$mins$secs));
  700.         }
  701.         return array($string$raw);
  702.     }
  703.  
  704.     function createNumber($spos){
  705.         $rknumhigh $this->_GetInt4d($this->data$spos 10);
  706.         $rknumlow $this->_GetInt4d($this->data$spos 6);
  707.         //for ($i=0; $i<8; $i++) { echo ord($this->data[$i+$spos+6]) . " "; } echo "<br>";
  708.         $sign ($rknumhigh 0x80000000>> 31;
  709.         $exp =  ($rknumhigh 0x7ff00000>> 20;
  710.         $mantissa (0x100000 ($rknumhigh 0x000fffff));
  711.         $mantissalow1 ($rknumlow 0x80000000>> 31;
  712.         $mantissalow2 ($rknumlow 0x7fffffff);
  713.         $value $mantissa pow(20($exp 1023)));
  714.         if ($mantissalow1 != 0$value += pow ((21 ($exp 1023)));
  715.         $value += $mantissalow2 pow ((52 ($exp 1023)));
  716.         //echo "Sign = $sign, Exp = $exp, mantissahighx = $mantissa, mantissalow1 = $mantissalow1, mantissalow2 = $mantissalow2<br>\n";
  717.         if ($sign{$value = -$value;}
  718.         return  $value;
  719.     }
  720.  
  721.     function addcell($row$col$string$raw ''){
  722.         //echo "ADD cel $row-$col $string\n";
  723.         $this->sheets[$this->sn]['maxrow'max($this->sheets[$this->sn]['maxrow']$row+1);
  724.         $this->sheets[$this->sn]['maxcol'max($this->sheets[$this->sn]['maxcol']$col+1);
  725.         $this->sheets[$this->sn]['cells'][$row+1][$col+1$string;
  726.         if ($raw)
  727.             $this->sheets[$this->sn]['cellsInfo'][$row+1][$col+1]['raw'$raw;
  728.         if (isset($this->rectype))
  729.             $this->sheets[$this->sn]['cellsInfo'][$row+1][$col+1]['type'$this->rectype;
  730.  
  731.     }
  732.  
  733.  
  734.     function _GetIEEE754($rknum){
  735.         if (($rknum 0x02!= 0{
  736.                 $value $rknum >> 2;
  737.         else {
  738. //mmp
  739. // first comment out the previously existing 7 lines of code here
  740. //                $tmp = unpack("d", pack("VV", 0, ($rknum & 0xfffffffc)));
  741. //                //$value = $tmp[''];
  742. //                if (array_key_exists(1, $tmp)) {
  743. //                    $value = $tmp[1];
  744. //                } else {
  745. //                    $value = $tmp[''];
  746. //                }
  747. // I got my info on IEEE754 encoding from 
  748. // http://research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html
  749. // The RK format calls for using only the most significant 30 bits of the
  750. // 64 bit floating point value. The other 34 bits are assumed to be 0
  751. // So, we use the upper 30 bits of $rknum as follows...
  752.          $sign ($rknum 0x80000000>> 31;
  753.         $exp ($rknum 0x7ff00000>> 20;
  754.         $mantissa (0x100000 ($rknum 0x000ffffc));
  755.         $value $mantissa pow(20($exp 1023)));
  756.         if ($sign{$value = -$value;}
  757. //end of changes by mmp        
  758.  
  759.         }
  760.  
  761.         if (($rknum 0x01!= 0{
  762.             $value /= 100;
  763.         }
  764.         return $value;
  765.     }
  766.  
  767.     function _encodeUTF16($string){
  768.         if ($this->_defaultEncoding){
  769.             return (Spreadsheet_Excel_Reader_HAVE_ICONViconv('UTF-16LE'$this->_defaultEncoding$string)$string;
  770.         }else{
  771.             return $string;
  772.         }
  773.     }
  774.  
  775.     function _GetInt4d($data$pos{
  776.         return ord($data[$pos](ord($data[$pos+1]<< 8(ord($data[$pos+2]<< 16(ord($data[$pos+3]<< 24);
  777.     }
  778.  
  779.  
  780. }
  781.  
  782.  
  783. ?>

Documentation generated on Thu, 08 Jan 2009 17:48:27 +0100 by phpDocumentor 1.4.0a2