Wednesday, May 6, 2015

Import Excel data to database through PHP

As we know excel have two different type of extension first one is "xls" which is supported by office 2003 and now we are using "xlsx" which is highly compressed version of "xls". I found two different php code to get these data to our database through PHP code.

This is just a tutorial for study purpose  no commercial use.

This code for XLS file

    <?php
    // include class file
    include 'excel_reader2.php';//make your own file copy from bottom
    // initialize reader object
    $data = new Spreadsheet_Excel_Reader();
    
    // read spreadsheet data
    $data->read('Book1.xls');    
    
    // iterate over spreadsheet cells and print as HTML table
    for($i=0;$i<count($data->sheets);$i++) // Loop to get all sheets in a file.
{
//echo "Sheet $i:<br /><br />Total rows in sheet $i  ".count($data->sheets[$i][cells])."<br />";
for($j=1;$j<=count($data->sheets[$i][cells]);$j++) // loop used to get each row of the sheet

for($k=1;$k<=count($data->sheets[$i][cells][$j]);$k++) // This loop is created to get data in a table format.
{
//echo $data->sheets[$i][cells][$j][$k];
}
$val1=$data->sheets[$i][cells][$j][1];
$val2=$data->sheets[$i][cells][$j][2];
$query="insert into tab(name,email) values('".$val1."','".$val2."')";
mysql_query($query);
}
}
    ?>  

This code is for XLSX  


<?php

include 'simplexlsx.class.php';
//include 'config.php';
$xlsx = new SimpleXLSX('Book1.xlsx');
$excel = array(array());
$excel = $xlsx->rows();

for($i=0;$i<sizeof($excel);$i++){
$name = $excel[$i][0];
echo $name;
//mysql_query("INSERT INTO `ringtones` (`name`,`singer`,`album`,`full_file_link`,`link`,`category`,`popularity`) VALUES ('$name','$artist','$album','$full_link','$link','$cat','$popularity') ");
}
//echo $i." rows inserted";

?>

file name: 
<?php
/**
 * A class for reading Microsoft Excel (97/2003) Spreadsheets.
 *
 * Version 2.2
 *
 * Enhanced and maintained by Matt Kruse < http://mattkruse.com >
 * Maintained at http://code.google.com/p/php-excel-reader/
 *
 * Format parsing and MUCH more contributed by:
 *    Matt Roxburgh < http://www.roxburgh.me.uk >
 *
 * DOCUMENTATION
 * =============
 *   http://code.google.com/p/php-excel-reader/wiki/Documentation
 *
 * CHANGE LOG
 * ==========
 *   http://code.google.com/p/php-excel-reader/wiki/ChangeHistory
 *
 * DISCUSSION/SUPPORT
 * ==================
 *   http://groups.google.com/group/php-excel-reader-discuss/topics
 *
 * --------------------------------------------------------------------------
 *
 * Originally developed by Vadim Tkachenko under the name PHPExcelReader.
 * (http://sourceforge.net/projects/phpexcelreader)
 * Based on the Java version by Andy Khan (http://www.andykhan.com).  Now
 * maintained by David Sanders.  Reads only Biff 7 and Biff 8 formats.
 *
 * PHP versions 4 and 5
 *
 * LICENSE: This source file is subject to version 3.0 of the PHP license
 * that is available through the world-wide-web at the following URI:
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
 * the PHP License and are unable to obtain it through the web, please
 * send a note to license@php.net so we can mail you a copy immediately.
 *
 * @category   Spreadsheet
 * @package Spreadsheet_Excel_Reader
 * @author Vadim Tkachenko <vt@apachephp.com>
 * @license http://www.php.net/license/3_0.txt  PHP License 3.0
 * @version CVS: $Id: reader.php 19 2007-03-13 12:42:41Z shangxiao $
 * @link   http://pear.php.net/package/Spreadsheet_Excel_Reader
 * @see OLE, Spreadsheet_Excel_Writer
 * --------------------------------------------------------------------------
 */

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));


function GetInt4d($data, $pos) {
$value = ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | (ord($data[$pos+3]) << 24);
if ($value>=4294967294) {
$value=-2;
}
return $value;
}

// http://uk.php.net/manual/en/function.getdate.php
function gmgetdate($ts = null){
$k = array('seconds','minutes','hours','mday','wday','mon','year','yday','weekday','month',0);
return(array_combine($k,split(":",gmdate('s:i:G:j:w:n:Y:z:l:F:U',is_null($ts)?time():$ts))));


function v($data,$pos) {
return ord($data[$pos]) | ord($data[$pos+1])<<8;
}

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;
    }
    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);

$bigBlockDepotBlocks = array();
$pos = BIG_BLOCK_DEPOT_BLOCKS_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);
}
}

// 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++;
}
}

// 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);
$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);
$block = $this->bigBlockChain[$block];
}
return $data;
}

function __readPropertySets(){
$offset = 0;
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]);
$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 ((strtolower($name) == "workbook") || ( strtolower($name) == "book")) {
$this->wrkbook = count($this->props) - 1;
}
if ($name == "Root Entry") {
$this->rootentry = count($this->props) - 1;
}
$offset += PROPERTY_STORAGE_BLOCK_SIZE;
}

}


function getWorkBook(){
if ($this->props[$this->wrkbook]['size'] < SMALL_BLOCK_THRESHOLD){
$rootdata = $this->__readData($this->props[$this->rootentry]['startBlock']);
$streamData = '';
$block = $this->props[$this->wrkbook]['startBlock'];
$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 '';
$streamData = '';
$block = $this->props[$this->wrkbook]['startBlock'];
$pos = 0;
while ($block != -2) {
 $pos = ($block + 1) * BIG_BLOCK_SIZE;
 $streamData .= substr($this->data, $pos, BIG_BLOCK_SIZE);
 $block = $this->bigBlockChain[$block];
}
return $streamData;
}
}

}

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_FONT',  0x0031);
define('SPREADSHEET_EXCEL_READER_TYPE_PALETTE',  0x0092);
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',  86400);
define('SPREADSHEET_EXCEL_READER_TYPE_HYPER',     0x01b8);
define('SPREADSHEET_EXCEL_READER_TYPE_COLINFO',     0x7d);
define('SPREADSHEET_EXCEL_READER_TYPE_DEFCOLWIDTH',  0x55);
define('SPREADSHEET_EXCEL_READER_TYPE_STANDARDWIDTH', 0x99);
define('SPREADSHEET_EXCEL_READER_DEF_NUM_FORMAT', "%s");


/*
* Main Class
*/
class Spreadsheet_Excel_Reader {

// MK: Added to make data retrieval easier
var $colnames = array();
var $colindexes = array();
var $standardColWidth = 0;
var $defaultColWidth = 0;

function myHex($d) {
if ($d < 16) return "0" . dechex($d);
return dechex($d);
}

function dumpHexData($data, $pos, $length) {
$info = "";
for ($i = 0; $i <= $length; $i++) {
$info .= ($i==0?"":" ") . $this->myHex(ord($data[$pos + $i])) . (ord($data[$pos + $i])>31? "[" . $data[$pos + $i] . "]":'');
}
return $info;
}

function getCol($col) {
if (is_string($col)) {
$col = strtolower($col);
if (array_key_exists($col,$this->colnames)) {
$col = $this->colnames[$col];
}
}
return $col;
}

// PUBLIC API FUNCTIONS
// --------------------

function val($row,$col,$sheet=0) {
$col = $this->getCol($col);
if (array_key_exists($row,$this->sheets[$sheet]['cells']) && array_key_exists($col,$this->sheets[$sheet]['cells'][$row])) {
return $this->sheets[$sheet]['cells'][$row][$col];
}
return "";
}
function value($row,$col,$sheet=0) {
return $this->val($row,$col,$sheet);
}
function info($row,$col,$type='',$sheet=0) {
$col = $this->getCol($col);
if (array_key_exists('cellsInfo',$this->sheets[$sheet])
&& array_key_exists($row,$this->sheets[$sheet]['cellsInfo'])
&& array_key_exists($col,$this->sheets[$sheet]['cellsInfo'][$row])
&& array_key_exists($type,$this->sheets[$sheet]['cellsInfo'][$row][$col])) {
return $this->sheets[$sheet]['cellsInfo'][$row][$col][$type];
}
return "";
}
function type($row,$col,$sheet=0) {
return $this->info($row,$col,'type',$sheet);
}
function raw($row,$col,$sheet=0) {
return $this->info($row,$col,'raw',$sheet);
}
function rowspan($row,$col,$sheet=0) {
$val = $this->info($row,$col,'rowspan',$sheet);
if ($val=="") { return 1; }
return $val;
}
function colspan($row,$col,$sheet=0) {
$val = $this->info($row,$col,'colspan',$sheet);
if ($val=="") { return 1; }
return $val;
}
function hyperlink($row,$col,$sheet=0) {
$link = $this->sheets[$sheet]['cellsInfo'][$row][$col]['hyperlink'];
if ($link) {
return $link['link'];
}
return '';
}
function rowcount($sheet=0) {
return $this->sheets[$sheet]['numRows'];
}
function colcount($sheet=0) {
return $this->sheets[$sheet]['numCols'];
}
function colwidth($col,$sheet=0) {
// Col width is actually the width of the number 0. So we have to estimate and come close
return $this->colInfo[$sheet][$col]['width']/9142*200; 
}
function colhidden($col,$sheet=0) {
return !!$this->colInfo[$sheet][$col]['hidden'];
}
function rowheight($row,$sheet=0) {
return $this->rowInfo[$sheet][$row]['height'];
}
function rowhidden($row,$sheet=0) {
return !!$this->rowInfo[$sheet][$row]['hidden'];
}

// GET THE CSS FOR FORMATTING
// ==========================
function style($row,$col,$sheet=0,$properties='') {
$css = "";
$font=$this->font($row,$col,$sheet);
if ($font!="") {
$css .= "font-family:$font;";
}
$align=$this->align($row,$col,$sheet);
if ($align!="") {
$css .= "text-align:$align;";
}
$height=$this->height($row,$col,$sheet);
if ($height!="") {
$css .= "font-size:$height"."px;";
}
$bgcolor=$this->bgColor($row,$col,$sheet);
if ($bgcolor!="") {
$bgcolor = $this->colors[$bgcolor];
$css .= "background-color:$bgcolor;";
}
$color=$this->color($row,$col,$sheet);
if ($color!="") {
$css .= "color:$color;";
}
$bold=$this->bold($row,$col,$sheet);
if ($bold) {
$css .= "font-weight:bold;";
}
$italic=$this->italic($row,$col,$sheet);
if ($italic) {
$css .= "font-style:italic;";
}
$underline=$this->underline($row,$col,$sheet);
if ($underline) {
$css .= "text-decoration:underline;";
}
// Borders
$bLeft = $this->borderLeft($row,$col,$sheet);
$bRight = $this->borderRight($row,$col,$sheet);
$bTop = $this->borderTop($row,$col,$sheet);
$bBottom = $this->borderBottom($row,$col,$sheet);
$bLeftCol = $this->borderLeftColor($row,$col,$sheet);
$bRightCol = $this->borderRightColor($row,$col,$sheet);
$bTopCol = $this->borderTopColor($row,$col,$sheet);
$bBottomCol = $this->borderBottomColor($row,$col,$sheet);
// Try to output the minimal required style
if ($bLeft!="" && $bLeft==$bRight && $bRight==$bTop && $bTop==$bBottom) {
$css .= "border:" . $this->lineStylesCss[$bLeft] .";";
}
else {
if ($bLeft!="") { $css .= "border-left:" . $this->lineStylesCss[$bLeft] .";"; }
if ($bRight!="") { $css .= "border-right:" . $this->lineStylesCss[$bRight] .";"; }
if ($bTop!="") { $css .= "border-top:" . $this->lineStylesCss[$bTop] .";"; }
if ($bBottom!="") { $css .= "border-bottom:" . $this->lineStylesCss[$bBottom] .";"; }
}
// Only output border colors if there is an actual border specified
if ($bLeft!="" && $bLeftCol!="") { $css .= "border-left-color:" . $bLeftCol .";"; }
if ($bRight!="" && $bRightCol!="") { $css .= "border-right-color:" . $bRightCol .";"; }
if ($bTop!="" && $bTopCol!="") { $css .= "border-top-color:" . $bTopCol . ";"; }
if ($bBottom!="" && $bBottomCol!="") { $css .= "border-bottom-color:" . $bBottomCol .";"; }

return $css;
}

// FORMAT PROPERTIES
// =================
function format($row,$col,$sheet=0) {
return $this->info($row,$col,'format',$sheet);
}
function formatIndex($row,$col,$sheet=0) {
return $this->info($row,$col,'formatIndex',$sheet);
}
function formatColor($row,$col,$sheet=0) {
return $this->info($row,$col,'formatColor',$sheet);
}

// CELL (XF) PROPERTIES
// ====================
function xfRecord($row,$col,$sheet=0) {
$xfIndex = $this->info($row,$col,'xfIndex',$sheet);
if ($xfIndex!="") {
return $this->xfRecords[$xfIndex];
}
return null;
}
function xfProperty($row,$col,$sheet,$prop) {
$xfRecord = $this->xfRecord($row,$col,$sheet);
if ($xfRecord!=null) {
return $xfRecord[$prop];
}
return "";
}
function align($row,$col,$sheet=0) {
return $this->xfProperty($row,$col,$sheet,'align');
}
function bgColor($row,$col,$sheet=0) {
return $this->xfProperty($row,$col,$sheet,'bgColor');
}
function borderLeft($row,$col,$sheet=0) {
return $this->xfProperty($row,$col,$sheet,'borderLeft');
}
function borderRight($row,$col,$sheet=0) {
return $this->xfProperty($row,$col,$sheet,'borderRight');
}
function borderTop($row,$col,$sheet=0) {
return $this->xfProperty($row,$col,$sheet,'borderTop');
}
function borderBottom($row,$col,$sheet=0) {
return $this->xfProperty($row,$col,$sheet,'borderBottom');
}
function borderLeftColor($row,$col,$sheet=0) {
return $this->colors[$this->xfProperty($row,$col,$sheet,'borderLeftColor')];
}
function borderRightColor($row,$col,$sheet=0) {
return $this->colors[$this->xfProperty($row,$col,$sheet,'borderRightColor')];
}
function borderTopColor($row,$col,$sheet=0) {
return $this->colors[$this->xfProperty($row,$col,$sheet,'borderTopColor')];
}
function borderBottomColor($row,$col,$sheet=0) {
return $this->colors[$this->xfProperty($row,$col,$sheet,'borderBottomColor')];
}

// FONT PROPERTIES
// ===============
function fontRecord($row,$col,$sheet=0) {
   $xfRecord = $this->xfRecord($row,$col,$sheet);
if ($xfRecord!=null) {
$font = $xfRecord['fontIndex'];
if ($font!=null) {
return $this->fontRecords[$font];
}
}
return null;
}
function fontProperty($row,$col,$sheet=0,$prop) {
$font = $this->fontRecord($row,$col,$sheet);
if ($font!=null) {
return $font[$prop];
}
return false;
}
function fontIndex($row,$col,$sheet=0) {
return $this->xfProperty($row,$col,$sheet,'fontIndex');
}
function color($row,$col,$sheet=0) {
$formatColor = $this->formatColor($row,$col,$sheet);
if ($formatColor!="") {
return $formatColor;
}
$ci = $this->fontProperty($row,$col,$sheet,'color');
                return $this->rawColor($ci);
        }
        function rawColor($ci) {
if (($ci <> 0x7FFF) && ($ci <> '')) {
return $this->colors[$ci];
}
return "";
}
function bold($row,$col,$sheet=0) {
return $this->fontProperty($row,$col,$sheet,'bold');
}
function italic($row,$col,$sheet=0) {
return $this->fontProperty($row,$col,$sheet,'italic');
}
function underline($row,$col,$sheet=0) {
return $this->fontProperty($row,$col,$sheet,'under');
}
function height($row,$col,$sheet=0) {
return $this->fontProperty($row,$col,$sheet,'height');
}
function font($row,$col,$sheet=0) {
return $this->fontProperty($row,$col,$sheet,'font');
}

// DUMP AN HTML TABLE OF THE ENTIRE XLS DATA
// =========================================
function dump($row_numbers=false,$col_letters=false,$sheet=0,$table_class='excel') {
$out = "<table class=\"$table_class\" cellspacing=0>";
if ($col_letters) {
$out .= "<thead>\n\t<tr>";
if ($row_numbers) {
$out .= "\n\t\t<th>&nbsp</th>";
}
for($i=1;$i<=$this->colcount($sheet);$i++) {
$style = "width:" . ($this->colwidth($i,$sheet)*1) . "px;";
if ($this->colhidden($i,$sheet)) {
$style .= "display:none;";
}
$out .= "\n\t\t<th style=\"$style\">" . strtoupper($this->colindexes[$i]) . "</th>";
}
$out .= "</tr></thead>\n";
}

$out .= "<tbody>\n";
for($row=1;$row<=$this->rowcount($sheet);$row++) {
$rowheight = $this->rowheight($row,$sheet);
$style = "height:" . ($rowheight*(4/3)) . "px;";
if ($this->rowhidden($row,$sheet)) {
$style .= "display:none;";
}
$out .= "\n\t<tr style=\"$style\">";
if ($row_numbers) {
$out .= "\n\t\t<th>$row</th>";
}
for($col=1;$col<=$this->colcount($sheet);$col++) {
// Account for Rowspans/Colspans
$rowspan = $this->rowspan($row,$col,$sheet);
$colspan = $this->colspan($row,$col,$sheet);
for($i=0;$i<$rowspan;$i++) {
for($j=0;$j<$colspan;$j++) {
if ($i>0 || $j>0) {
$this->sheets[$sheet]['cellsInfo'][$row+$i][$col+$j]['dontprint']=1;
}
}
}
if(!$this->sheets[$sheet]['cellsInfo'][$row][$col]['dontprint']) {
$style = $this->style($row,$col,$sheet);
if ($this->colhidden($col,$sheet)) {
$style .= "display:none;";
}
$out .= "\n\t\t<td style=\"$style\"" . ($colspan > 1?" colspan=$colspan":"") . ($rowspan > 1?" rowspan=$rowspan":"") . ">";
$val = $this->val($row,$col,$sheet);
if ($val=='') { $val="&nbsp;"; }
else { 
$val = htmlentities($val); 
$link = $this->hyperlink($row,$col,$sheet);
if ($link!='') {
$val = "<a href=\"$link\">$val</a>";
}
}
$out .= "<nobr>".nl2br($val)."</nobr>";
$out .= "</td>";
}
}
$out .= "</tr>\n";
}
$out .= "</tbody></table>";
return $out;
}

// --------------
// END PUBLIC API


var $boundsheets = array();
var $formatRecords = array();
var $fontRecords = array();
var $xfRecords = array();
var $colInfo = array();
    var $rowInfo = array();

var $sst = array();
var $sheets = array();

var $data;
var $_ole;
var $_defaultEncoding = "UTF-8";
var $_defaultFormat = SPREADSHEET_EXCEL_READER_DEF_NUM_FORMAT;
var $_columnsFormat = array();
var $_rowoffset = 1;
var $_coloffset = 1;

/**
* List of default date formats used by Excel
*/
var $dateFormats = array (
0xe => "m/d/Y",
0xf => "M-d-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"
);

/**
* Default number formats used by Excel
*/
var $numberFormats = array(
0x1 => "0",
0x2 => "0.00",
0x3 => "#,##0",
0x4 => "#,##0.00",
0x5 => "\$#,##0;(\$#,##0)",
0x6 => "\$#,##0;[Red](\$#,##0)",
0x7 => "\$#,##0.00;(\$#,##0.00)",
0x8 => "\$#,##0.00;[Red](\$#,##0.00)",
0x9 => "0%",
0xa => "0.00%",
0xb => "0.00E+00",
0x25 => "#,##0;(#,##0)",
0x26 => "#,##0;[Red](#,##0)",
0x27 => "#,##0.00;(#,##0.00)",
0x28 => "#,##0.00;[Red](#,##0.00)",
0x29 => "#,##0;(#,##0)",  // Not exactly
0x2a => "\$#,##0;(\$#,##0)",  // Not exactly
0x2b => "#,##0.00;(#,##0.00)",  // Not exactly
0x2c => "\$#,##0.00;(\$#,##0.00)",  // Not exactly
0x30 => "##0.0E+0"
);

    var $colors = Array(
        0x00 => "#000000",
        0x01 => "#FFFFFF",
        0x02 => "#FF0000",
        0x03 => "#00FF00",
        0x04 => "#0000FF",
        0x05 => "#FFFF00",
        0x06 => "#FF00FF",
        0x07 => "#00FFFF",
        0x08 => "#000000",
        0x09 => "#FFFFFF",
        0x0A => "#FF0000",
        0x0B => "#00FF00",
        0x0C => "#0000FF",
        0x0D => "#FFFF00",
        0x0E => "#FF00FF",
        0x0F => "#00FFFF",
        0x10 => "#800000",
        0x11 => "#008000",
        0x12 => "#000080",
        0x13 => "#808000",
        0x14 => "#800080",
        0x15 => "#008080",
        0x16 => "#C0C0C0",
        0x17 => "#808080",
        0x18 => "#9999FF",
        0x19 => "#993366",
        0x1A => "#FFFFCC",
        0x1B => "#CCFFFF",
        0x1C => "#660066",
        0x1D => "#FF8080",
        0x1E => "#0066CC",
        0x1F => "#CCCCFF",
        0x20 => "#000080",
        0x21 => "#FF00FF",
        0x22 => "#FFFF00",
        0x23 => "#00FFFF",
        0x24 => "#800080",
        0x25 => "#800000",
        0x26 => "#008080",
        0x27 => "#0000FF",
        0x28 => "#00CCFF",
        0x29 => "#CCFFFF",
        0x2A => "#CCFFCC",
        0x2B => "#FFFF99",
        0x2C => "#99CCFF",
        0x2D => "#FF99CC",
        0x2E => "#CC99FF",
        0x2F => "#FFCC99",
        0x30 => "#3366FF",
        0x31 => "#33CCCC",
        0x32 => "#99CC00",
        0x33 => "#FFCC00",
        0x34 => "#FF9900",
        0x35 => "#FF6600",
        0x36 => "#666699",
        0x37 => "#969696",
        0x38 => "#003366",
        0x39 => "#339966",
        0x3A => "#003300",
        0x3B => "#333300",
        0x3C => "#993300",
        0x3D => "#993366",
        0x3E => "#333399",
        0x3F => "#333333",
        0x40 => "#000000",
        0x41 => "#FFFFFF",

        0x43 => "#000000",
        0x4D => "#000000",
        0x4E => "#FFFFFF",
        0x4F => "#000000",
        0x50 => "#FFFFFF",
        0x51 => "#000000",

        0x7FFF => "#000000"
    );

var $lineStyles = array(
0x00 => "",
0x01 => "Thin",
0x02 => "Medium",
0x03 => "Dashed",
0x04 => "Dotted",
0x05 => "Thick",
0x06 => "Double",
0x07 => "Hair",
0x08 => "Medium dashed",
0x09 => "Thin dash-dotted",
0x0A => "Medium dash-dotted",
0x0B => "Thin dash-dot-dotted",
0x0C => "Medium dash-dot-dotted",
0x0D => "Slanted medium dash-dotted"
);

var $lineStylesCss = array(
"Thin" => "1px solid", 
"Medium" => "2px solid", 
"Dashed" => "1px dashed", 
"Dotted" => "1px dotted", 
"Thick" => "3px solid", 
"Double" => "double", 
"Hair" => "1px solid", 
"Medium dashed" => "2px dashed", 
"Thin dash-dotted" => "1px dashed", 
"Medium dash-dotted" => "2px dashed", 
"Thin dash-dot-dotted" => "1px dashed", 
"Medium dash-dot-dotted" => "2px dashed", 
"Slanted medium dash-dotte" => "2px dashed" 
);

function read16bitstring($data, $start) {
$len = 0;
while (ord($data[$start + $len]) + ord($data[$start + $len + 1]) > 0) $len++;
return substr($data, $start, $len);
}

// ADDED by Matt Kruse for better formatting
function _format_value($format,$num,$f) {
// 49==TEXT format
// http://code.google.com/p/php-excel-reader/issues/detail?id=7
if ( (!$f && $format=="%s") || ($f==49) || ($format=="GENERAL") ) { return array('string'=>$num); }

// Custom pattern can be POSITIVE;NEGATIVE;ZERO
// The "text" option as 4th parameter is not handled
$parts = split(";",$format);
$pattern = $parts[0];
// Negative pattern
if (count($parts)>2 && $num==0) {
$pattern = $parts[2];
}
// Zero pattern
if (count($parts)>1 && $num<0) {
$pattern = $parts[1];
$num = abs($num);
}

$color = "";
$color_regex = "/^\[(BLACK|BLUE|CYAN|GREEN|MAGENTA|RED|WHITE|YELLOW)\]/i";
if (preg_match($color_regex,$pattern,$matches)) {
$color = strtolower($matches[1]);
$pattern = preg_replace($color_regex,"",$pattern);
}

// In Excel formats, "_" is used to add spacing, which we can't do in HTML
$pattern = preg_replace("/_./","",$pattern);

// Some non-number characters are escaped with \, which we don't need
$pattern = preg_replace("/\\\/","",$pattern);

// Some non-number strings are quoted, so we'll get rid of the quotes
$pattern = preg_replace("/\"/","",$pattern);

// TEMPORARY - Convert # to 0
$pattern = preg_replace("/\#/","0",$pattern);

// Find out if we need comma formatting
$has_commas = preg_match("/,/",$pattern);
if ($has_commas) {
$pattern = preg_replace("/,/","",$pattern);
}

// Handle Percentages
if (preg_match("/\d(\%)([^\%]|$)/",$pattern,$matches)) {
$num = $num * 100;
$pattern = preg_replace("/(\d)(\%)([^\%]|$)/","$1%$3",$pattern);
}

// Handle the number itself
$number_regex = "/(\d+)(\.?)(\d*)/";
if (preg_match($number_regex,$pattern,$matches)) {
$left = $matches[1];
$dec = $matches[2];
$right = $matches[3];
if ($has_commas) {
$formatted = number_format($num,strlen($right));
}
else {
$sprintf_pattern = "%1.".strlen($right)."f";
$formatted = sprintf($sprintf_pattern, $num);
}
$pattern = preg_replace($number_regex, $formatted, $pattern);
}

return array(
'string'=>$pattern,
'formatColor'=>$color
);
}

/**
* Constructor
*
* Some basic initialisation
*/
function Spreadsheet_Excel_Reader($file='',$store_extended_info=true,$outputEncoding='') {
$this->_ole = new OLERead();
$this->setUTFEncoder('iconv');
if ($outputEncoding != '') { 
$this->setOutputEncoding($outputEncoding);
}
for ($i=1; $i<245; $i++) {
$name = strtolower(( (($i-1)/26>=1)?chr(($i-1)/26+64):'') . chr(($i-1)%26+65));
$this->colnames[$name] = $i;
$this->colindexes[$i] = $name;
}
$this->store_extended_info = $store_extended_info;
if ($file!="") {
$this->read($file);
}
}

/**
* Set the encoding method
*/
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;
}

/**
* Set the default number format
*/
function setDefaultFormat($sFormat) {
$this->_defaultFormat = $sFormat;
}

/**
* Force a column to use a certain format
*/
function setColumnFormat($column, $sFormat) {
$this->_columnsFormat[$column] = $sFormat;
}

/**
* Read the spreadsheet file using OLE, then parse
*/
function read($sFileName) {
$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();
$this->_parse();
}

/**
* Parse a workbook
*
* @access private
* @return bool
*/
function _parse() {
$pos = 0;
$data = $this->data;

$code = v($data,$pos);
$length = v($data,$pos+2);
$version = v($data,$pos+4);
$substreamType = v($data,$pos+6);

$this->version = $version;

if (($version != SPREADSHEET_EXCEL_READER_BIFF8) &&
($version != SPREADSHEET_EXCEL_READER_BIFF7)) {
return false;
}

if ($substreamType != SPREADSHEET_EXCEL_READER_WORKBOOKGLOBALS){
return false;
}

$pos += $length + 4;

$code = v($data,$pos);
$length = v($data,$pos+2);

while ($code != SPREADSHEET_EXCEL_READER_TYPE_EOF) {
switch ($code) {
case SPREADSHEET_EXCEL_READER_TYPE_SST:
$spos = $pos + 4;
$limitpos = $spos + $length;
$uniqueStrings = $this->_GetInt4d($data, $spos+4);
$spos += 8;
for ($i = 0; $i < $uniqueStrings; $i++) {
// Read in the number of characters
if ($spos == $limitpos) {
$opcode = v($data,$spos);
$conlength = v($data,$spos+2);
if ($opcode != 0x3c) {
return -1;
}
$spos += 4;
$limitpos = $spos + $conlength;
}
$numChars = ord($data[$spos]) | (ord($data[$spos+1]) << 8);
$spos += 2;
$optionFlags = ord($data[$spos]);
$spos++;
$asciiEncoding = (($optionFlags & 0x01) == 0) ;
$extendedString = ( ($optionFlags & 0x04) != 0);

// See if string contains formatting information
$richString = ( ($optionFlags & 0x08) != 0);

if ($richString) {
// Read in the crun
$formattingRuns = v($data,$spos);
$spos += 2;
}

if ($extendedString) {
// Read in cchExtRst
$extendedRunLength = $this->_GetInt4d($data, $spos);
$spos += 4;
}

$len = ($asciiEncoding)? $numChars : $numChars*2;
if ($spos + $len < $limitpos) {
$retstr = substr($data, $spos, $len);
$spos += $len;
}
else{
// found countinue
$retstr = substr($data, $spos, $limitpos - $spos);
$bytesRead = $limitpos - $spos;
$charsLeft = $numChars - (($asciiEncoding) ? $bytesRead : ($bytesRead / 2));
$spos = $limitpos;

while ($charsLeft > 0){
$opcode = v($data,$spos);
$conlength = v($data,$spos+2);
if ($opcode != 0x3c) {
return -1;
}
$spos += 4;
$limitpos = $spos + $conlength;
$option = ord($data[$spos]);
$spos += 1;
if ($asciiEncoding && ($option == 0)) {
$len = min($charsLeft, $limitpos - $spos); // min($charsLeft, $conlength);
$retstr .= substr($data, $spos, $len);
$charsLeft -= $len;
$asciiEncoding = true;
}
elseif (!$asciiEncoding && ($option != 0)) {
$len = min($charsLeft * 2, $limitpos - $spos); // min($charsLeft, $conlength);
$retstr .= substr($data, $spos, $len);
$charsLeft -= $len/2;
$asciiEncoding = false;
}
elseif (!$asciiEncoding && ($option == 0)) {
// Bummer - the string starts off as Unicode, but after the
// continuation it is in straightforward ASCII encoding
$len = min($charsLeft, $limitpos - $spos); // min($charsLeft, $conlength);
for ($j = 0; $j < $len; $j++) {
$retstr .= $data[$spos + $j].chr(0);
}
$charsLeft -= $len;
$asciiEncoding = false;
}
else{
$newstr = '';
for ($j = 0; $j < strlen($retstr); $j++) {
$newstr = $retstr[$j].chr(0);
}
$retstr = $newstr;
$len = min($charsLeft * 2, $limitpos - $spos); // min($charsLeft, $conlength);
$retstr .= substr($data, $spos, $len);
$charsLeft -= $len/2;
$asciiEncoding = false;
}
$spos += $len;
}
}
$retstr = ($asciiEncoding) ? $retstr : $this->_encodeUTF16($retstr);

if ($richString){
$spos += 4 * $formattingRuns;
}

// For extended strings, skip over the extended string data
if ($extendedString) {
$spos += $extendedRunLength;
}
$this->sst[]=$retstr;
}
break;
case SPREADSHEET_EXCEL_READER_TYPE_FILEPASS:
return false;
break;
case SPREADSHEET_EXCEL_READER_TYPE_NAME:
break;
case SPREADSHEET_EXCEL_READER_TYPE_FORMAT:
$indexCode = v($data,$pos+4);
if ($version == SPREADSHEET_EXCEL_READER_BIFF8) {
$numchars = v($data,$pos+6);
if (ord($data[$pos+8]) == 0){
$formatString = substr($data, $pos+9, $numchars);
} else {
$formatString = substr($data, $pos+9, $numchars*2);
}
} else {
$numchars = ord($data[$pos+6]);
$formatString = substr($data, $pos+7, $numchars*2);
}
$this->formatRecords[$indexCode] = $formatString;
break;
case SPREADSHEET_EXCEL_READER_TYPE_FONT:
$height = v($data,$pos+4);
$option = v($data,$pos+6);
$color = v($data,$pos+8);
$weight = v($data,$pos+10);
$under  = ord($data[$pos+14]);
$font = "";
// Font name
$numchars = ord($data[$pos+18]);
if ((ord($data[$pos+19]) & 1) == 0){
   $font = substr($data, $pos+20, $numchars);
} else {
   $font = substr($data, $pos+20, $numchars*2);
   $font =  $this->_encodeUTF16($font); 
}
$this->fontRecords[] = array(
'height' => $height / 20,
'italic' => !!($option & 2),
'color' => $color,
'under' => !($under==0),
'bold' => ($weight==700),
'font' => $font,
'raw' => $this->dumpHexData($data, $pos+3, $length)
);
   break;

case SPREADSHEET_EXCEL_READER_TYPE_PALETTE:
$colors = ord($data[$pos+4]) | ord($data[$pos+5]) << 8;
for ($coli = 0; $coli < $colors; $coli++) {
   $colOff = $pos + 2 + ($coli * 4);
     $colr = ord($data[$colOff]);
     $colg = ord($data[$colOff+1]);
     $colb = ord($data[$colOff+2]);
$this->colors[0x07 + $coli] = '#' . $this->myhex($colr) . $this->myhex($colg) . $this->myhex($colb);
}
   break;

case SPREADSHEET_EXCEL_READER_TYPE_XF:
$fontIndexCode = (ord($data[$pos+4]) | ord($data[$pos+5]) << 8) - 1;
$fontIndexCode = max(0,$fontIndexCode);
$indexCode = ord($data[$pos+6]) | ord($data[$pos+7]) << 8;
$alignbit = ord($data[$pos+10]) & 3;
$bgi = (ord($data[$pos+22]) | ord($data[$pos+23]) << 8) & 0x3FFF;
$bgcolor = ($bgi & 0x7F);
// $bgcolor = ($bgi & 0x3f80) >> 7;
$align = "";
if ($alignbit==3) { $align="right"; }
if ($alignbit==2) { $align="center"; }

$fillPattern = (ord($data[$pos+21]) & 0xFC) >> 2;
if ($fillPattern == 0) {
$bgcolor = "";
}

$xf = array();
$xf['formatIndex'] = $indexCode;
$xf['align'] = $align;
$xf['fontIndex'] = $fontIndexCode;
$xf['bgColor'] = $bgcolor;
$xf['fillPattern'] = $fillPattern;

$border = ord($data[$pos+14]) | (ord($data[$pos+15]) << 8) | (ord($data[$pos+16]) << 16) | (ord($data[$pos+17]) << 24);
$xf['borderLeft'] = $this->lineStyles[($border & 0xF)];
$xf['borderRight'] = $this->lineStyles[($border & 0xF0) >> 4];
$xf['borderTop'] = $this->lineStyles[($border & 0xF00) >> 8];
$xf['borderBottom'] = $this->lineStyles[($border & 0xF000) >> 12];

$xf['borderLeftColor'] = ($border & 0x7F0000) >> 16;
$xf['borderRightColor'] = ($border & 0x3F800000) >> 23;
$border = (ord($data[$pos+18]) | ord($data[$pos+19]) << 8);

$xf['borderTopColor'] = ($border & 0x7F);
$xf['borderBottomColor'] = ($border & 0x3F80) >> 7;

if (array_key_exists($indexCode, $this->dateFormats)) {
$xf['type'] = 'date';
$xf['format'] = $this->dateFormats[$indexCode];
if ($align=='') { $xf['align'] = 'right'; }
}elseif (array_key_exists($indexCode, $this->numberFormats)) {
$xf['type'] = 'number';
$xf['format'] = $this->numberFormats[$indexCode];
if ($align=='') { $xf['align'] = 'right'; }
}else{
$isdate = FALSE;
$formatstr = '';
if ($indexCode > 0){
if (isset($this->formatRecords[$indexCode]))
$formatstr = $this->formatRecords[$indexCode];
if ($formatstr!="") {
$tmp = preg_replace("/\;.*/","",$formatstr);
$tmp = preg_replace("/^\[[^\]]*\]/","",$tmp);
if (preg_match("/[^hmsday\/\-:\s\\\,AMP]/i", $tmp) == 0) { // found day and time format
$isdate = TRUE;
$formatstr = $tmp;
$formatstr = str_replace(array('AM/PM','mmmm','mmm'), array('a','F','M'), $formatstr);
// m/mm are used for both minutes and months - oh SNAP!
// This mess tries to fix for that.
// 'm' == minutes only if following h/hh or preceding s/ss
$formatstr = preg_replace("/(h:?)mm?/","$1i", $formatstr);
$formatstr = preg_replace("/mm?(:?s)/","i$1", $formatstr);
// A single 'm' = n in PHP
$formatstr = preg_replace("/(^|[^m])m([^m]|$)/", '$1n$2', $formatstr);
$formatstr = preg_replace("/(^|[^m])m([^m]|$)/", '$1n$2', $formatstr);
// else it's months
$formatstr = str_replace('mm', 'm', $formatstr);
// Convert single 'd' to 'j'
$formatstr = preg_replace("/(^|[^d])d([^d]|$)/", '$1j$2', $formatstr);
$formatstr = str_replace(array('dddd','ddd','dd','yyyy','yy','hh','h'), array('l','D','d','Y','y','H','g'), $formatstr);
$formatstr = preg_replace("/ss?/", 's', $formatstr);
}
}
}
if ($isdate){
$xf['type'] = 'date';
$xf['format'] = $formatstr;
if ($align=='') { $xf['align'] = 'right'; }
}else{
// If the format string has a 0 or # in it, we'll assume it's a number
if (preg_match("/[0#]/", $formatstr)) {
$xf['type'] = 'number';
if ($align=='') { $xf['align']='right'; }
}
else {
$xf['type'] = 'other';
}
$xf['format'] = $formatstr;
$xf['code'] = $indexCode;
}
}
$this->xfRecords[] = $xf;
break;
case SPREADSHEET_EXCEL_READER_TYPE_NINETEENFOUR:
$this->nineteenFour = (ord($data[$pos+4]) == 1);
break;
case SPREADSHEET_EXCEL_READER_TYPE_BOUNDSHEET:
$rec_offset = $this->_GetInt4d($data, $pos+4);
$rec_typeFlag = ord($data[$pos+8]);
$rec_visibilityFlag = ord($data[$pos+9]);
$rec_length = ord($data[$pos+10]);

if ($version == SPREADSHEET_EXCEL_READER_BIFF8){
$chartype =  ord($data[$pos+11]);
if ($chartype == 0){
$rec_name = substr($data, $pos+12, $rec_length);
} else {
$rec_name = $this->_encodeUTF16(substr($data, $pos+12, $rec_length*2));
}
}elseif ($version == SPREADSHEET_EXCEL_READER_BIFF7){
$rec_name = substr($data, $pos+11, $rec_length);
}
$this->boundsheets[] = array('name'=>$rec_name,'offset'=>$rec_offset);
break;

}

$pos += $length + 4;
$code = ord($data[$pos]) | ord($data[$pos+1])<<8;
$length = ord($data[$pos+2]) | ord($data[$pos+3])<<8;
}

foreach ($this->boundsheets as $key=>$val){
$this->sn = $key;
$this->_parsesheet($val['offset']);
}
return true;
}

/**
* Parse a worksheet
*/
function _parsesheet($spos) {
$cont = true;
$data = $this->data;
// read BOF
$code = ord($data[$spos]) | ord($data[$spos+1])<<8;
$length = ord($data[$spos+2]) | ord($data[$spos+3])<<8;

$version = ord($data[$spos + 4]) | ord($data[$spos + 5])<<8;
$substreamType = ord($data[$spos + 6]) | ord($data[$spos + 7])<<8;

if (($version != SPREADSHEET_EXCEL_READER_BIFF8) && ($version != SPREADSHEET_EXCEL_READER_BIFF7)) {
return -1;
}

if ($substreamType != SPREADSHEET_EXCEL_READER_WORKSHEET){
return -2;
}
$spos += $length + 4;
while($cont) {
$lowcode = ord($data[$spos]);
if ($lowcode == SPREADSHEET_EXCEL_READER_TYPE_EOF) break;
$code = $lowcode | ord($data[$spos+1])<<8;
$length = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
$spos += 4;
$this->sheets[$this->sn]['maxrow'] = $this->_rowoffset - 1;
$this->sheets[$this->sn]['maxcol'] = $this->_coloffset - 1;
unset($this->rectype);
switch ($code) {
case SPREADSHEET_EXCEL_READER_TYPE_DIMENSION:
if (!isset($this->numRows)) {
if (($length == 10) ||  ($version == SPREADSHEET_EXCEL_READER_BIFF7)){
$this->sheets[$this->sn]['numRows'] = ord($data[$spos+2]) | ord($data[$spos+3]) << 8;
$this->sheets[$this->sn]['numCols'] = ord($data[$spos+6]) | ord($data[$spos+7]) << 8;
} else {
$this->sheets[$this->sn]['numRows'] = ord($data[$spos+4]) | ord($data[$spos+5]) << 8;
$this->sheets[$this->sn]['numCols'] = ord($data[$spos+10]) | ord($data[$spos+11]) << 8;
}
}
break;
case SPREADSHEET_EXCEL_READER_TYPE_MERGEDCELLS:
$cellRanges = ord($data[$spos]) | ord($data[$spos+1])<<8;
for ($i = 0; $i < $cellRanges; $i++) {
$fr =  ord($data[$spos + 8*$i + 2]) | ord($data[$spos + 8*$i + 3])<<8;
$lr =  ord($data[$spos + 8*$i + 4]) | ord($data[$spos + 8*$i + 5])<<8;
$fc =  ord($data[$spos + 8*$i + 6]) | ord($data[$spos + 8*$i + 7])<<8;
$lc =  ord($data[$spos + 8*$i + 8]) | ord($data[$spos + 8*$i + 9])<<8;
if ($lr - $fr > 0) {
$this->sheets[$this->sn]['cellsInfo'][$fr+1][$fc+1]['rowspan'] = $lr - $fr + 1;
}
if ($lc - $fc > 0) {
$this->sheets[$this->sn]['cellsInfo'][$fr+1][$fc+1]['colspan'] = $lc - $fc + 1;
}
}
break;
case SPREADSHEET_EXCEL_READER_TYPE_RK:
case SPREADSHEET_EXCEL_READER_TYPE_RK2:
$row = ord($data[$spos]) | ord($data[$spos+1])<<8;
$column = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
$rknum = $this->_GetInt4d($data, $spos + 6);
$numValue = $this->_GetIEEE754($rknum);
$info = $this->_getCellDetails($spos,$numValue,$column);
$this->addcell($row, $column, $info['string'],$info);
break;
case SPREADSHEET_EXCEL_READER_TYPE_LABELSST:
$row = ord($data[$spos]) | ord($data[$spos+1])<<8;
$column = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
$xfindex = ord($data[$spos+4]) | ord($data[$spos+5])<<8;
$index  = $this->_GetInt4d($data, $spos + 6);
$this->addcell($row, $column, $this->sst[$index], array('xfIndex'=>$xfindex) );
break;
case SPREADSHEET_EXCEL_READER_TYPE_MULRK:
$row = ord($data[$spos]) | ord($data[$spos+1])<<8;
$colFirst   = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
$colLast = ord($data[$spos + $length - 2]) | ord($data[$spos + $length - 1])<<8;
$columns = $colLast - $colFirst + 1;
$tmppos = $spos+4;
for ($i = 0; $i < $columns; $i++) {
$numValue = $this->_GetIEEE754($this->_GetInt4d($data, $tmppos + 2));
$info = $this->_getCellDetails($tmppos-4,$numValue,$colFirst + $i + 1);
$tmppos += 6;
$this->addcell($row, $colFirst + $i, $info['string'], $info);
}
break;
case SPREADSHEET_EXCEL_READER_TYPE_NUMBER:
$row = ord($data[$spos]) | ord($data[$spos+1])<<8;
$column = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
$tmp = unpack("ddouble", substr($data, $spos + 6, 8)); // It machine machine dependent
if ($this->isDate($spos)) {
$numValue = $tmp['double'];
}
else {
$numValue = $this->createNumber($spos);
}
$info = $this->_getCellDetails($spos,$numValue,$column);
$this->addcell($row, $column, $info['string'], $info);
break;

case SPREADSHEET_EXCEL_READER_TYPE_FORMULA:
case SPREADSHEET_EXCEL_READER_TYPE_FORMULA2:
$row = ord($data[$spos]) | ord($data[$spos+1])<<8;
$column = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
if ((ord($data[$spos+6])==0) && (ord($data[$spos+12])==255) && (ord($data[$spos+13])==255)) {
//String formula. Result follows in a STRING record
// This row/col are stored to be referenced in that record
// http://code.google.com/p/php-excel-reader/issues/detail?id=4
$previousRow = $row;
$previousCol = $column;
} elseif ((ord($data[$spos+6])==1) && (ord($data[$spos+12])==255) && (ord($data[$spos+13])==255)) {
//Boolean formula. Result is in +2; 0=false,1=true
// http://code.google.com/p/php-excel-reader/issues/detail?id=4
                        if (ord($this->data[$spos+8])==1) {
                            $this->addcell($row, $column, "TRUE");
                        } else {
                            $this->addcell($row, $column, "FALSE");
                        }
} elseif ((ord($data[$spos+6])==2) && (ord($data[$spos+12])==255) && (ord($data[$spos+13])==255)) {
//Error formula. Error code is in +2;
} elseif ((ord($data[$spos+6])==3) && (ord($data[$spos+12])==255) && (ord($data[$spos+13])==255)) {
//Formula result is a null string.
$this->addcell($row, $column, '');
} else {
// result is a number, so first 14 bytes are just like a _NUMBER record
$tmp = unpack("ddouble", substr($data, $spos + 6, 8)); // It machine machine dependent
 if ($this->isDate($spos)) {
$numValue = $tmp['double'];
 }
 else {
$numValue = $this->createNumber($spos);
 }
$info = $this->_getCellDetails($spos,$numValue,$column);
$this->addcell($row, $column, $info['string'], $info);
}
break;
case SPREADSHEET_EXCEL_READER_TYPE_BOOLERR:
$row = ord($data[$spos]) | ord($data[$spos+1])<<8;
$column = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
$string = ord($data[$spos+6]);
$this->addcell($row, $column, $string);
break;
                case SPREADSHEET_EXCEL_READER_TYPE_STRING:
// http://code.google.com/p/php-excel-reader/issues/detail?id=4
if ($version == SPREADSHEET_EXCEL_READER_BIFF8){
// Unicode 16 string, like an SST record
$xpos = $spos;
$numChars =ord($data[$xpos]) | (ord($data[$xpos+1]) << 8);
$xpos += 2;
$optionFlags =ord($data[$xpos]);
$xpos++;
$asciiEncoding = (($optionFlags &0x01) == 0) ;
$extendedString = (($optionFlags & 0x04) != 0);
                        // See if string contains formatting information
$richString = (($optionFlags & 0x08) != 0);
if ($richString) {
// Read in the crun
$formattingRuns =ord($data[$xpos]) | (ord($data[$xpos+1]) << 8);
$xpos += 2;
}
if ($extendedString) {
// Read in cchExtRst
$extendedRunLength =$this->_GetInt4d($this->data, $xpos);
$xpos += 4;
}
$len = ($asciiEncoding)?$numChars : $numChars*2;
$retstr =substr($data, $xpos, $len);
$xpos += $len;
$retstr = ($asciiEncoding)? $retstr : $this->_encodeUTF16($retstr);
}
elseif ($version == SPREADSHEET_EXCEL_READER_BIFF7){
// Simple byte string
$xpos = $spos;
$numChars =ord($data[$xpos]) | (ord($data[$xpos+1]) << 8);
$xpos += 2;
$retstr =substr($data, $xpos, $numChars);
}
$this->addcell($previousRow, $previousCol, $retstr);
break;
case SPREADSHEET_EXCEL_READER_TYPE_ROW:
$row = ord($data[$spos]) | ord($data[$spos+1])<<8;
$rowInfo = ord($data[$spos + 6]) | ((ord($data[$spos+7]) << 8) & 0x7FFF);
if (($rowInfo & 0x8000) > 0) {
$rowHeight = -1;
} else {
$rowHeight = $rowInfo & 0x7FFF;
}
$rowHidden = (ord($data[$spos + 12]) & 0x20) >> 5;
$this->rowInfo[$this->sn][$row+1] = Array('height' => $rowHeight / 20, 'hidden'=>$rowHidden );
break;
case SPREADSHEET_EXCEL_READER_TYPE_DBCELL:
break;
case SPREADSHEET_EXCEL_READER_TYPE_MULBLANK:
$row = ord($data[$spos]) | ord($data[$spos+1])<<8;
$column = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
$cols = ($length / 2) - 3;
for ($c = 0; $c < $cols; $c++) {
$xfindex = ord($data[$spos + 4 + ($c * 2)]) | ord($data[$spos + 5 + ($c * 2)])<<8;
$this->addcell($row, $column + $c, "", array('xfIndex'=>$xfindex));
}
break;
case SPREADSHEET_EXCEL_READER_TYPE_LABEL:
$row = ord($data[$spos]) | ord($data[$spos+1])<<8;
$column = ord($data[$spos+2]) | ord($data[$spos+3])<<8;
$this->addcell($row, $column, substr($data, $spos + 8, ord($data[$spos + 6]) | ord($data[$spos + 7])<<8));
break;
case SPREADSHEET_EXCEL_READER_TYPE_EOF:
$cont = false;
break;
case SPREADSHEET_EXCEL_READER_TYPE_HYPER:
//  Only handle hyperlinks to a URL
$row = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8;
$row2   = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8;
$column = ord($this->data[$spos+4]) | ord($this->data[$spos+5])<<8;
$column2 = ord($this->data[$spos+6]) | ord($this->data[$spos+7])<<8;
$linkdata = Array();
$flags = ord($this->data[$spos + 28]);
$udesc = "";
$ulink = "";
$uloc = 32;
$linkdata['flags'] = $flags;
if (($flags & 1) > 0 ) {   // is a type we understand
//  is there a description ?
if (($flags & 0x14) == 0x14 ) {   // has a description
$uloc += 4;
$descLen = ord($this->data[$spos + 32]) | ord($this->data[$spos + 33]) << 8;
$udesc = substr($this->data, $spos + $uloc, $descLen * 2);
$uloc += 2 * $descLen;
}
$ulink = $this->read16bitstring($this->data, $spos + $uloc + 20);
if ($udesc == "") {
$udesc = $ulink;
}
}
$linkdata['desc'] = $udesc;
$linkdata['link'] = $this->_encodeUTF16($ulink);
for ($r=$row; $r<=$row2; $r++) { 
for ($c=$column; $c<=$column2; $c++) {
$this->sheets[$this->sn]['cellsInfo'][$r+1][$c+1]['hyperlink'] = $linkdata;
}
}
break;
case SPREADSHEET_EXCEL_READER_TYPE_DEFCOLWIDTH:
$this->defaultColWidth  = ord($data[$spos+4]) | ord($data[$spos+5]) << 8; 
break;
case SPREADSHEET_EXCEL_READER_TYPE_STANDARDWIDTH:
$this->standardColWidth  = ord($data[$spos+4]) | ord($data[$spos+5]) << 8; 
break;
case SPREADSHEET_EXCEL_READER_TYPE_COLINFO:
$colfrom = ord($data[$spos+0]) | ord($data[$spos+1]) << 8;
$colto = ord($data[$spos+2]) | ord($data[$spos+3]) << 8;
$cw = ord($data[$spos+4]) | ord($data[$spos+5]) << 8; 
$cxf = ord($data[$spos+6]) | ord($data[$spos+7]) << 8; 
$co = ord($data[$spos+8]); 
for ($coli = $colfrom; $coli <= $colto; $coli++) {
$this->colInfo[$this->sn][$coli+1] = Array('width' => $cw, 'xf' => $cxf, 'hidden' => ($co & 0x01), 'collapsed' => ($co & 0x1000) >> 12);
}
break;

default:
break;
}
$spos += $length;
}

if (!isset($this->sheets[$this->sn]['numRows']))
$this->sheets[$this->sn]['numRows'] = $this->sheets[$this->sn]['maxrow'];
if (!isset($this->sheets[$this->sn]['numCols']))
$this->sheets[$this->sn]['numCols'] = $this->sheets[$this->sn]['maxcol'];
}

function isDate($spos) {
$xfindex = ord($this->data[$spos+4]) | ord($this->data[$spos+5]) << 8;
return ($this->xfRecords[$xfindex]['type'] == 'date');
}

// Get the details for a particular cell
function _getCellDetails($spos,$numValue,$column) {
$xfindex = ord($this->data[$spos+4]) | ord($this->data[$spos+5]) << 8;
$xfrecord = $this->xfRecords[$xfindex];
$type = $xfrecord['type'];

$format = $xfrecord['format'];
$formatIndex = $xfrecord['formatIndex'];
$formatColor = "";
$rectype = '';
$string = '';
$raw = '';

if (isset($this->_columnsFormat[$column + 1])){
$format = $this->_columnsFormat[$column + 1];
}

if ($type == 'date') {
// See http://groups.google.com/group/php-excel-reader-discuss/browse_frm/thread/9c3f9790d12d8e10/f2045c2369ac79de
$rectype = 'date';
// Convert numeric value into a date
$utcDays = floor($numValue - ($this->nineteenFour ? SPREADSHEET_EXCEL_READER_UTCOFFSETDAYS1904 : SPREADSHEET_EXCEL_READER_UTCOFFSETDAYS));
$utcValue = ($utcDays) * SPREADSHEET_EXCEL_READER_MSINADAY;
$dateinfo = gmgetdate($utcValue);

$raw = $numValue;
$fractionalDay = $numValue - floor($numValue) + .0000001; // The .0000001 is to fix for php/excel fractional diffs

$totalseconds = floor(SPREADSHEET_EXCEL_READER_MSINADAY * $fractionalDay);
$secs = $totalseconds % 60;
$totalseconds -= $secs;
$hours = floor($totalseconds / (60 * 60));
$mins = floor($totalseconds / 60) % 60;
$string = date ($format, mktime($hours, $mins, $secs, $dateinfo["mon"], $dateinfo["mday"], $dateinfo["year"]));
} else if ($type == 'number') {
$rectype = 'number';
$formatted = $this->_format_value($format, $numValue, $formatIndex);
$string = $formatted['string'];
$formatColor = $formatted['formatColor'];
$raw = $numValue;
} else{
if ($format=="") {
$format = $this->_defaultFormat;
}
$rectype = 'unknown';
$formatted = $this->_format_value($format, $numValue, $formatIndex);
$string = $formatted['string'];
//$formatColor = $formatted['formatColor'];
$raw = $numValue;
}

return array(
'string'=>$string,
'raw'=>$raw,
'rectype'=>$rectype,
'format'=>$format,
'formatIndex'=>$formatIndex,
//'fontIndex'=>$fontIndex,
'formatColor'=>$formatColor,
'xfIndex'=>$xfindex
);

}


function createNumber($spos) {
$rknumhigh = $this->_GetInt4d($this->data, $spos + 10);
$rknumlow = $this->_GetInt4d($this->data, $spos + 6);
$sign = ($rknumhigh & 0x80000000) >> 31;
$exp =  ($rknumhigh & 0x7ff00000) >> 20;
$mantissa = (0x100000 | ($rknumhigh & 0x000fffff));
$mantissalow1 = ($rknumlow & 0x80000000) >> 31;
$mantissalow2 = ($rknumlow & 0x7fffffff);
$value = $mantissa / pow( 2 , (20- ($exp - 1023)));
if ($mantissalow1 != 0) $value += 1 / pow (2 , (21 - ($exp - 1023)));
$value += $mantissalow2 / pow (2 , (52 - ($exp - 1023)));
if ($sign) {$value = -1 * $value;}
return  $value;
}

function addcell($row, $col, $string, $info=null) {
$this->sheets[$this->sn]['maxrow'] = max($this->sheets[$this->sn]['maxrow'], $row + $this->_rowoffset);
$this->sheets[$this->sn]['maxcol'] = max($this->sheets[$this->sn]['maxcol'], $col + $this->_coloffset);
$this->sheets[$this->sn]['cells'][$row + $this->_rowoffset][$col + $this->_coloffset] = $string;
if ($this->store_extended_info && $info) {
foreach ($info as $key=>$val) {
$this->sheets[$this->sn]['cellsInfo'][$row + $this->_rowoffset][$col + $this->_coloffset][$key] = $val;
}
}
}


function _GetIEEE754($rknum) {
if (($rknum & 0x02) != 0) {
$value = $rknum >> 2;
} else {
//mmp
// I got my info on IEEE754 encoding from
// http://research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html
// The RK format calls for using only the most significant 30 bits of the
// 64 bit floating point value. The other 34 bits are assumed to be 0
// So, we use the upper 30 bits of $rknum as follows...
$sign = ($rknum & 0x80000000) >> 31;
$exp = ($rknum & 0x7ff00000) >> 20;
$mantissa = (0x100000 | ($rknum & 0x000ffffc));
$value = $mantissa / pow( 2 , (20- ($exp - 1023)));
if ($sign) {
$value = -1 * $value;
}
//end of changes by mmp
}
if (($rknum & 0x01) != 0) {
$value /= 100;
}
return $value;
}

function _encodeUTF16($string) {
$result = $string;
if ($this->_defaultEncoding){
switch ($this->_encoderFunction){
case 'iconv' : //$result = iconv('UTF-16LE', $this->_defaultEncoding, $string);
break;
case 'mb_convert_encoding' : $result = mb_convert_encoding($string, $this->_defaultEncoding, 'UTF-16LE' );
break;
}
}
return $result;
}

function _GetInt4d($data, $pos) {
$value = ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | (ord($data[$pos+3]) << 24);
if ($value>=4294967294) {
$value=-2;
}
return $value;
}

}


?>

--------------------------------------------------------------------------------------------------------------------------

file name:  simplexlsx.class.php

<?php
/*
SimpleXLSX php class v0.6.8
MS Excel 2007 workbooks reader

Example 1: 
$xlsx = new SimpleXLSX('book.xlsx');
print_r( $xlsx->rows() );

Example 2: 
$xlsx = new SimpleXLSX('book.xlsx');
print_r( $xlsx->rowsEx() );

Example 3: 
$xlsx = new SimpleXLSX('book.xlsx');
print_r( $xlsx->rows(2) ); // second worksheet

Example 4.1:
$xlsx = new SimpleXLSX('book.xlsx');
print_r( $xlsx->sheetNames() ); // array( 1 => 'Sheet 1', 3 => 'Catalog' );

Example 4.2:
$xlsx = new SimpleXLSX('book.xlsx');
echo 'Sheet Name 2 = '.$xlsx->sheetName(2);

Example 5:
$xlsx = new SimpleXLSX('book.xlsx');
if ($xslx->success())
print_r( $xlsx->rows() );
else
echo 'xlsx error: '.$xslx->error();

Example 6:
$xslx = new SimpleXLSX( file_get_contents('http://www.example.com/example.xlsx'), true);
list($num_cols, $num_rows) = $xlsx->dimension(2);
echo $xlsx->sheetName(2).':'.$num_cols.'x'.$num_rows;

v0.6.8 (2013-10-13) fixed dimension() where 1 row only, fixed rowsEx() empty cells indexes (Daniel Stastka)
v0.6.7 (2013-08-10) fixed unzip (mac), added $debug param to _constructor to display errors
v0.6.6 (2013-06-03) +entryExists(),
v0.6.5 (2013-03-18) fixed sheetName()
v0.6.4 (2013-03-13) rowsEx(), _parse(): fixed date column type & format detection
v0.6.3 (2013-03-13) rowsEx(): fixed formulas, added date type 'd', added format 'format'
dimension(): fixed empty sheet dimension
                   + sheetNames() - returns array( sheet_id => sheet_name, sheet_id2 => sheet_name2 ...)
v0.6.2 (2012-10-04) fixed empty cells, rowsEx() returns type and formulas now
v0.6.1 (2012-09-14) removed "raise exception" and fixed _unzip
v0.6 (2012-09-13) success(), error(), __constructor( $filename, $is_data = false )
v0.5.1 (2012-09-13) sheetName() fixed
v0.5 (2012-09-12) sheetName()
v0.4 sheets(), sheetsCount(), unixstamp( $excelDateTime )
v0.3 - fixed empty cells (Gonzo patch)
*/

class SimpleXLSX {
// Don't remove this string! Created by Sergey Schuchkin from http://www.sibvision.ru - professional php developers team 2010-2013
private $workbook;
private $sheets;
private $styles;
private $hyperlinks;
private $package = array(
'filename' => '',
'mtime' => 0,
'size' => 0,
'comment' => '',
'entries' => array()
);
private $sharedstrings;
private $error = false;
private $debug = false;
// scheme
const SCHEMA_REL_OFFICEDOCUMENT  =  'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument';
const SCHEMA_REL_SHAREDSTRINGS =  'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings';
const SCHEMA_REL_WORKSHEET =  'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet';
const SCHEMA_REL_STYLES = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles';

private $workbook_cell_formats = array();
private $built_in_cell_formats = array(
0 => 'General',
1 => '0',
2 => '0.00',
3 => '#,##0',
4 => '#,##0.00',
9 => '0%',
10 => '0.00%',
11 => '0.00E+00',
12 => '# ?/?',
13 => '# ??/??',
14 => 'mm-dd-yy',
15 => 'd-mmm-yy',
16 => 'd-mmm',
17 => 'mmm-yy',
18 => 'h:mm AM/PM',
19 => 'h:mm:ss AM/PM',
20 => 'h:mm',
21 => 'h:mm:ss',
22 => 'm/d/yy h:mm',

37 => '#,##0 ;(#,##0)',
38 => '#,##0 ;[Red](#,##0)',
39 => '#,##0.00;(#,##0.00)',
40 => '#,##0.00;[Red](#,##0.00)',

44 => '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)',
45 => 'mm:ss',
46 => '[h]:mm:ss',
47 => 'mmss.0',
48 => '##0.0E+0',
49 => '@',

27 => '[$-404]e/m/d',
30 => 'm/d/yy',
36 => '[$-404]e/m/d',
50 => '[$-404]e/m/d',
57 => '[$-404]e/m/d',

59 => 't0',
60 => 't0.00',
61 => 't#,##0',
62 => 't#,##0.00',
67 => 't0%',
68 => 't0.00%',
69 => 't# ?/?',
70 => 't# ??/??',
);

function __construct( $filename, $is_data = false, $debug = false ) {
$this->debug = $debug;
$this->_unzip( $filename, $is_data );
$this->_parse();
}
function sheets() {
return $this->sheets;
}
function sheetsCount() {
return count($this->sheets);
}
function sheetName( $worksheet_id) {

foreach( $this->workbook->sheets->sheet as $s ) {

if ( $s->attributes('r',true)->id == 'rId'.$worksheet_id)
return (string) $s['name'];

}
return false;
}
function sheetNames() {

$result = array();

foreach( $this->workbook->sheets->sheet as $s ) {

$result[ substr( $s->attributes('r',true)->id, 3) ] = (string) $s['name'];

}
return $result;
}
function worksheet( $worksheet_id ) {
if ( isset( $this->sheets[ $worksheet_id ] ) ) {
$ws = $this->sheets[ $worksheet_id ];

if (isset($ws->hyperlinks)) {
$this->hyperlinks = array();
foreach( $ws->hyperlinks->hyperlink as $hyperlink ) {
$this->hyperlinks[ (string) $hyperlink['ref'] ] = (string) $hyperlink['display'];
}
}

return $ws;
} else {
$this->error( 'Worksheet '.$worksheet_id.' not found. Try $xlsx->rows('.implode(') or $xlsx->rows(', array_keys($this->sheets)).')' );
return false;
}
}
function dimension( $worksheet_id = 1 ) {

if (($ws = $this->worksheet( $worksheet_id)) === false)
return false;

$ref = (string) $ws->dimension['ref'];

if( strpos( $ref, ':') !== false ) {
$d = explode(':', $ref);
if(!isset($d[1]))
return array(0,0);
$index = $this->_columnIndex( $d[1] );
return array( $index[0]+1, $index[1]+1);
} else if ( strlen( $ref ) ) { // 0.6.8
$index = $this->_columnIndex( $ref );
return array( $index[0]+1, $index[1]+1);
} else
return array(0,0);

}
// sheets numeration: 1,2,3....
function rows( $worksheet_id = 1 ) {

if (($ws = $this->worksheet( $worksheet_id)) === false)
return false;

$rows = array();
$curR = 0;

list($cols,) = $this->dimension( $worksheet_id );

foreach ($ws->sheetData->row as $row) {
// echo 'row<br />';
foreach ($row->c as $c) {
list($curC,) = $this->_columnIndex((string) $c['r']);
$rows[ $curR ][ $curC ] = $this->value($c);
}
for ($i = 0; $i < $cols; $i++)
if (!isset($rows[$curR][$i]))
$rows[ $curR ][ $i ] = '';

ksort( $rows[ $curR ] );

$curR++;
}
return $rows;
}
function rowsEx( $worksheet_id = 1 ) {

if (($ws = $this->worksheet( $worksheet_id)) === false)
return false;

$rows = array();
$curR = 0;
list($cols,) = $this->dimension( $worksheet_id );

foreach ($ws->sheetData->row as $row) {

foreach ($row->c as $c) {
list($curC,) = $this->_columnIndex((string) $c['r']);
$t = (string)$c['t'];
$s = (int)$c['s'];
if ($s > 0 && isset($this->workbook_cell_formats[ $s ])) {
$format = $this->workbook_cell_formats[ $s ]['format'];
if ( strpos($format,'m') !== false )
$t = 'd';
} else
$format = '';

$rows[ $curR ][ $curC ] = array(
'type' => $t,
'name' => (string) $c['r'],
'value' => $this->value($c),
'href' => $this->href( $c ),
'f' => (string) $c->f,
'format' => $format
);
}
for ($i = 0; $i < $cols; $i++) {

if ( !isset($rows[$curR][$i]) ) {

// 0.6.8
for ($c = '', $j = $i; $j >= 0; $j = intval($j / 26) - 1)
$c = chr( $j % 26 + 65 ) . $c;

$rows[ $curR ][$i] = array(
'type' => '',
// 'name' => chr($i + 65).($curR+1),
'name' => $c.($curR+1),
'value' => '',
'href' => '',
'f' => '',
'format' => ''
);
}
}

ksort( $rows[ $curR ] );

$curR++;
}
return $rows;

}
// thx Gonzo
private function _columnIndex( $cell = 'A1' ) {

if (preg_match("/([A-Z]+)(\d+)/", $cell, $matches)) {

$col = $matches[1];
$row = $matches[2];

$colLen = strlen($col);
$index = 0;

for ($i = $colLen-1; $i >= 0; $i--)
$index += (ord($col{$i}) - 64) * pow(26, $colLen-$i-1);

return array($index-1, $row-1);
} else
throw new Exception("Invalid cell index.");
}
function value( $cell ) {
// Determine data type
$dataType = (string) $cell['t'];

switch ($dataType) {
case "s":
// Value is a shared string
if ((string)$cell->v != '') {
$value = $this->sharedstrings[intval($cell->v)];
} else {
$value = '';
}

break;

case "b":
// Value is boolean
$value = (string)$cell->v;
if ($value == '0') {
$value = false;
} else if ($value == '1') {
$value = true;
} else {
$value = (bool)$cell->v;
}

break;

case "inlineStr":
// Value is rich text inline
$value = $this->_parseRichText($cell->is);

break;

case "e":
// Value is an error message
if ((string)$cell->v != '') {
$value = (string)$cell->v;
} else {
$value = '';
}

break;

default:
// Value is a string
$value = (string)$cell->v;

// Check for numeric values
if (is_numeric($value) && $dataType != 's') {
if ($value == (int)$value) $value = (int)$value;
elseif ($value == (float)$value) $value = (float)$value;
}
}
return $value;
}
function href( $cell ) {
return isset( $this->hyperlinks[ (string) $cell['r'] ] ) ? $this->hyperlinks[ (string) $cell['r'] ] : '';
}
function styles() {
return $this->styles;
}
function _unzip( $filename, $is_data = false ) {

// Clear current file
$this->datasec = array();

if ($is_data) {

$this->package['filename'] = 'default.xlsx';
$this->package['mtime'] = time();
$this->package['size'] = strlen( $filename );

$vZ = $filename;
} else {

if (!is_readable($filename)) {
$this->error( 'File not found' );
return false;
}

// Package information
$this->package['filename'] = $filename;
$this->package['mtime'] = filemtime( $filename );
$this->package['size'] = filesize( $filename );

// Read file
$oF = fopen($filename, 'rb');
$vZ = fread($oF, $this->package['size']);
fclose($oF);

}
// Cut end of central directory
/* $aE = explode("\x50\x4b\x05\x06", $vZ);

if (count($aE) == 1) {
$this->error('Unknown format');
return false;
}
*/
if ( ($pcd = strrpos( $vZ, "\x50\x4b\x05\x06" )) === false ) {
$this->error('Unknown format');
return false;
}
$aE = array(
0 => substr( $vZ, 0, $pcd ),
1 => substr( $vZ, $pcd + 3 )
);

// Normal way
$aP = unpack('x16/v1CL', $aE[1]);
$this->package['comment'] = substr($aE[1], 18, $aP['CL']);

// Translates end of line from other operating systems
$this->package['comment'] = strtr($this->package['comment'], array("\r\n" => "\n", "\r" => "\n"));

// Cut the entries from the central directory
$aE = explode("\x50\x4b\x01\x02", $vZ);
// Explode to each part
$aE = explode("\x50\x4b\x03\x04", $aE[0]);
// Shift out spanning signature or empty entry
array_shift($aE);

// Loop through the entries
foreach ($aE as $vZ) {
$aI = array();
$aI['E']  = 0;
$aI['EM'] = '';
// Retrieving local file header information
// $aP = unpack('v1VN/v1GPF/v1CM/v1FT/v1FD/V1CRC/V1CS/V1UCS/v1FNL', $vZ);
$aP = unpack('v1VN/v1GPF/v1CM/v1FT/v1FD/V1CRC/V1CS/V1UCS/v1FNL/v1EFL', $vZ);

// Check if data is encrypted
// $bE = ($aP['GPF'] && 0x0001) ? TRUE : FALSE;
$bE = false;
$nF = $aP['FNL'];
$mF = $aP['EFL'];

// Special case : value block after the compressed data
if ($aP['GPF'] & 0x0008) {
$aP1 = unpack('V1CRC/V1CS/V1UCS', substr($vZ, -12));

$aP['CRC'] = $aP1['CRC'];
$aP['CS']  = $aP1['CS'];
$aP['UCS'] = $aP1['UCS'];
// 2013-08-10
$vZ = substr($vZ, 0, -12);
if (substr($vZ,-4) === "\x50\x4b\x07\x08")
$vZ = substr($vZ, 0, -4);
}

// Getting stored filename
$aI['N'] = substr($vZ, 26, $nF);

if (substr($aI['N'], -1) == '/') {
// is a directory entry - will be skipped
continue;
}

// Truncate full filename in path and filename
$aI['P'] = dirname($aI['N']);
$aI['P'] = $aI['P'] == '.' ? '' : $aI['P'];
$aI['N'] = basename($aI['N']);

$vZ = substr($vZ, 26 + $nF + $mF);

if ( strlen($vZ) != $aP['CS'] ) { // check only if availabled
 $aI['E']  = 1;
 $aI['EM'] = 'Compressed size is not equal with the value in header information.';
} else {
if ($bE) {
$aI['E']  = 5;
$aI['EM'] = 'File is encrypted, which is not supported from this class.';
} else {
switch($aP['CM']) {
case 0: // Stored
// Here is nothing to do, the file ist flat.
break;
case 8: // Deflated
$vZ = gzinflate($vZ);
break;
case 12: // BZIP2
if (! extension_loaded('bz2')) {
if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
 @dl('php_bz2.dll');
} else {
 @dl('bz2.so');
}
}
if (extension_loaded('bz2')) {
$vZ = bzdecompress($vZ);
} else {
$aI['E']  = 7;
$aI['EM'] = "PHP BZIP2 extension not available.";
}
break;
default:
 $aI['E']  = 6;
 $aI['EM'] = "De-/Compression method {$aP['CM']} is not supported.";
}
if (! $aI['E']) {
if ($vZ === FALSE) {
$aI['E']  = 2;
$aI['EM'] = 'Decompression of data failed.';
} else {
if (strlen($vZ) != $aP['UCS']) {
$aI['E']  = 3;
$aI['EM'] = 'Uncompressed size is not equal with the value in header information.';
} else {
if (crc32($vZ) != $aP['CRC']) {
$aI['E']  = 4;
$aI['EM'] = 'CRC32 checksum is not equal with the value in header information.';
}
}
}
}
}
}

$aI['D'] = $vZ;

// DOS to UNIX timestamp
$aI['T'] = mktime(($aP['FT']  & 0xf800) >> 11,
 ($aP['FT']  & 0x07e0) >>  5,
 ($aP['FT']  & 0x001f) <<  1,
 ($aP['FD']  & 0x01e0) >>  5,
 ($aP['FD']  & 0x001f),
 (($aP['FD'] & 0xfe00) >>  9) + 1980);

//$this->Entries[] = &new SimpleUnzipEntry($aI);
$this->package['entries'][] = array(
'data' => $aI['D'],
'error' => $aI['E'],
'error_msg' => $aI['EM'],
'name' => $aI['N'],
'path' => $aI['P'],
'time' => $aI['T']
);

} // end for each entries
}
function getPackage() {
return $this->package;
}
function entryExists( $name ) { // 0.6.6
$dir = dirname( $name );
$name = basename( $name );
foreach( $this->package['entries'] as $entry)
if ( $entry['path'] == $dir && $entry['name'] == $name)
return true;
return false;
}
function getEntryData( $name ) {
$dir = dirname( $name );
$name = basename( $name );
foreach( $this->package['entries'] as $entry)
if ( $entry['path'] == $dir && $entry['name'] == $name)
return $entry['data'];
$this->error('Unknown format');
return false;
}
function getEntryXML( $name ) {
if ( ($entry_xml = $this->getEntryData( $name ))
&&  ($entry_xmlobj = simplexml_load_string( $entry_xml )))
return $entry_xmlobj;


$this->error('Entry not found: '.$name );
return false;
}
function unixstamp( $excelDateTime ) {
$d = floor( $excelDateTime ); // seconds since 1900
$t = $excelDateTime - $d;
return ($d > 0) ? ( $d - 25569 ) * 86400 + $t * 86400 : $t * 86400;
}
function error( $set = false ) {
if ($set) {
$this->error = $set;
if ($this->debug)
trigger_error( __CLASS__.': '.$set, E_USER_WARNING );
} else {
return $this->error;
}
}
function success() {
return !$this->error;
}
function _parse() {
// Document data holders
$this->sharedstrings = array();
$this->sheets = array();
// $this->styles = array();

// Read relations and search for officeDocument
if ( $relations = $this->getEntryXML("_rels/.rels" ) ) {

foreach ($relations->Relationship as $rel) {

if ($rel["Type"] == SimpleXLSX::SCHEMA_REL_OFFICEDOCUMENT) {

// echo 'workbook found<br />';
// Found office document! Read workbook & relations...

// Workbook
if ( $this->workbook = $this->getEntryXML( $rel['Target'] )) {

// echo 'workbook read<br />';

if ( $workbookRelations = $this->getEntryXML( dirname($rel['Target']) . '/_rels/workbook.xml.rels' )) {

// echo 'workbook relations<br />';

// Loop relations for workbook and extract sheets...
foreach ($workbookRelations->Relationship as $workbookRelation) {

$path = dirname($rel['Target']) . '/' . $workbookRelation['Target'];

if ($workbookRelation['Type'] == SimpleXLSX::SCHEMA_REL_WORKSHEET) { // Sheets

// echo 'sheet<br />';

if ( $sheet = $this->getEntryXML( $path ) ) {
$this->sheets[ str_replace( 'rId', '', (string) $workbookRelation['Id']) ] = $sheet;
// echo '<pre>'.htmlspecialchars( print_r( $sheet, true ) ).'</pre>';
}

} else if ($workbookRelation['Type'] == SimpleXLSX::SCHEMA_REL_SHAREDSTRINGS && $this->entryExists( $path )) { // 0.6.6

// echo 'sharedstrings<br />';

if ( $sharedStrings = $this->getEntryXML( $path ) ) {
foreach ($sharedStrings->si as $val) {
if (isset($val->t)) {
$this->sharedstrings[] = (string)$val->t;
} elseif (isset($val->r)) {
$this->sharedstrings[] = $this->_parseRichText($val);
}
}
}
} else if ($workbookRelation['Type'] == SimpleXLSX::SCHEMA_REL_STYLES) {
$this->styles = $this->getEntryXML( $path );

$nf = array();
if ( $this->styles->numFmts->numFmt != NULL )
foreach( $this->styles->numFmts->numFmt as $v )
$nf[ (int) $v['numFmtId'] ] = (string) $v['formatCode'];

if ( $this->styles->cellXfs->xf != NULL )
foreach( $this->styles->cellXfs->xf as $v ) {
$v = (array) $v->attributes();
$v = $v['@attributes'];
if (isset($this->built_in_cell_formats[ $v['numFmtId'] ]) )
$v['format'] = $this->built_in_cell_formats[ $v['numFmtId'] ];
else if (isset($nf[ $v['numFmtId'] ]))
$v['format'] = $nf[ $v['numFmtId'] ];
else
$v['format'] = '';
$this->workbook_cell_formats[] = $v;
}
// print_r( $this->workbook_cell_formats );
}
}

break;
}
}
}
}
}
// Sort sheets
ksort($this->sheets);
}
    private function _parseRichText($is = null) {
        $value = array();

        if (isset($is->t)) {
            $value[] = (string)$is->t;
        } else {
            foreach ($is->r as $run) {
                $value[] = (string)$run->t;
            }
        }

        return implode(' ', $value);
    }
}

?>

No comments:

Post a Comment

Dharamart.blogspot.in