readFilter = new PHPExcel_Reader_DefaultReadFilter();
    }
    /**
     * Can the current PHPExcel_Reader_IReader read the file?
     *
     * @param     string         $pFilename
     * @return     boolean
     * @throws PHPExcel_Reader_Exception
     */
    public function canRead($pFilename)
    {
        //    Office                    xmlns:o="urn:schemas-microsoft-com:office:office"
        //    Excel                    xmlns:x="urn:schemas-microsoft-com:office:excel"
        //    XML Spreadsheet            xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
        //    Spreadsheet component    xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet"
        //    XML schema                 xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
        //    XML data type            xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
        //    MS-persist recordset    xmlns:rs="urn:schemas-microsoft-com:rowset"
        //    Rowset                    xmlns:z="#RowsetSchema"
        //
        $signature = array(
                ''
            );
        // Open file
        $this->openFile($pFilename);
        $fileHandle = $this->fileHandle;
        
        // Read sample data (first 2 KB will do)
        $data = fread($fileHandle, 2048);
        fclose($fileHandle);
        $valid = true;
        foreach ($signature as $match) {
            // every part of the signature must be present
            if (strpos($data, $match) === false) {
                $valid = false;
                break;
            }
        }
        //    Retrieve charset encoding
        if (preg_match('//um', $data, $matches)) {
            $this->charSet = strtoupper($matches[1]);
        }
//        echo 'Character Set is ', $this->charSet,'
';
        return $valid;
    }
    /**
     * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object
     *
     * @param     string         $pFilename
     * @throws     PHPExcel_Reader_Exception
     */
    public function listWorksheetNames($pFilename)
    {
        // Check if file exists
        if (!file_exists($pFilename)) {
            throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
        }
        if (!$this->canRead($pFilename)) {
            throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file.");
        }
        $worksheetNames = array();
        $xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());
        $namespaces = $xml->getNamespaces(true);
        $xml_ss = $xml->children($namespaces['ss']);
        foreach ($xml_ss->Worksheet as $worksheet) {
            $worksheet_ss = $worksheet->attributes($namespaces['ss']);
            $worksheetNames[] = self::convertStringEncoding((string) $worksheet_ss['Name'], $this->charSet);
        }
        return $worksheetNames;
    }
    /**
     * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)
     *
     * @param   string     $pFilename
     * @throws   PHPExcel_Reader_Exception
     */
    public function listWorksheetInfo($pFilename)
    {
        // Check if file exists
        if (!file_exists($pFilename)) {
            throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
        }
        $worksheetInfo = array();
        $xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());
        $namespaces = $xml->getNamespaces(true);
        $worksheetID = 1;
        $xml_ss = $xml->children($namespaces['ss']);
        foreach ($xml_ss->Worksheet as $worksheet) {
            $worksheet_ss = $worksheet->attributes($namespaces['ss']);
            $tmpInfo = array();
            $tmpInfo['worksheetName'] = '';
            $tmpInfo['lastColumnLetter'] = 'A';
            $tmpInfo['lastColumnIndex'] = 0;
            $tmpInfo['totalRows'] = 0;
            $tmpInfo['totalColumns'] = 0;
            if (isset($worksheet_ss['Name'])) {
                $tmpInfo['worksheetName'] = (string) $worksheet_ss['Name'];
            } else {
                $tmpInfo['worksheetName'] = "Worksheet_{$worksheetID}";
            }
            if (isset($worksheet->Table->Row)) {
                $rowIndex = 0;
                foreach ($worksheet->Table->Row as $rowData) {
                    $columnIndex = 0;
                    $rowHasData = false;
                    foreach ($rowData->Cell as $cell) {
                        if (isset($cell->Data)) {
                            $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex);
                            $rowHasData = true;
                        }
                        ++$columnIndex;
                    }
                    ++$rowIndex;
                    if ($rowHasData) {
                        $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex);
                    }
                }
            }
            $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
            $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;
            $worksheetInfo[] = $tmpInfo;
            ++$worksheetID;
        }
        return $worksheetInfo;
    }
    /**
     * Loads PHPExcel from file
     *
     * @param     string         $pFilename
     * @return     PHPExcel
     * @throws     PHPExcel_Reader_Exception
     */
    public function load($pFilename)
    {
        // Create new PHPExcel
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->removeSheetByIndex(0);
        // Load into this instance
        return $this->loadIntoExisting($pFilename, $objPHPExcel);
    }
    protected static function identifyFixedStyleValue($styleList, &$styleAttributeValue)
    {
        $styleAttributeValue = strtolower($styleAttributeValue);
        foreach ($styleList as $style) {
            if ($styleAttributeValue == strtolower($style)) {
                $styleAttributeValue = $style;
                return true;
            }
        }
        return false;
    }
    /**
     * pixel units to excel width units(units of 1/256th of a character width)
     * @param pxs
     * @return
     */
    protected static function pixel2WidthUnits($pxs)
    {
        $UNIT_OFFSET_MAP = array(0, 36, 73, 109, 146, 182, 219);
        $widthUnits = 256 * ($pxs / 7);
        $widthUnits += $UNIT_OFFSET_MAP[($pxs % 7)];
        return $widthUnits;
    }
    /**
     * excel width units(units of 1/256th of a character width) to pixel units
     * @param widthUnits
     * @return
     */
    protected static function widthUnits2Pixel($widthUnits)
    {
        $pixels = ($widthUnits / 256) * 7;
        $offsetWidthUnits = $widthUnits % 256;
        $pixels += round($offsetWidthUnits / (256 / 7));
        return $pixels;
    }
    protected static function hex2str($hex)
    {
        return chr(hexdec($hex[1]));
    }
    /**
     * Loads PHPExcel from file into PHPExcel instance
     *
     * @param     string         $pFilename
     * @param    PHPExcel    $objPHPExcel
     * @return     PHPExcel
     * @throws     PHPExcel_Reader_Exception
     */
    public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
    {
        $fromFormats    = array('\-', '\ ');
        $toFormats      = array('-', ' ');
        $underlineStyles = array (
            PHPExcel_Style_Font::UNDERLINE_NONE,
            PHPExcel_Style_Font::UNDERLINE_DOUBLE,
            PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING,
            PHPExcel_Style_Font::UNDERLINE_SINGLE,
            PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING
        );
        $verticalAlignmentStyles = array (
            PHPExcel_Style_Alignment::VERTICAL_BOTTOM,
            PHPExcel_Style_Alignment::VERTICAL_TOP,
            PHPExcel_Style_Alignment::VERTICAL_CENTER,
            PHPExcel_Style_Alignment::VERTICAL_JUSTIFY
        );
        $horizontalAlignmentStyles = array (
            PHPExcel_Style_Alignment::HORIZONTAL_GENERAL,
            PHPExcel_Style_Alignment::HORIZONTAL_LEFT,
            PHPExcel_Style_Alignment::HORIZONTAL_RIGHT,
            PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
            PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS,
            PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY
        );
        $timezoneObj = new DateTimeZone('Europe/London');
        $GMT = new DateTimeZone('UTC');
        // Check if file exists
        if (!file_exists($pFilename)) {
            throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
        }
        if (!$this->canRead($pFilename)) {
            throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file.");
        }
        $xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());
        $namespaces = $xml->getNamespaces(true);
        $docProps = $objPHPExcel->getProperties();
        if (isset($xml->DocumentProperties[0])) {
            foreach ($xml->DocumentProperties[0] as $propertyName => $propertyValue) {
                switch ($propertyName) {
                    case 'Title':
                        $docProps->setTitle(self::convertStringEncoding($propertyValue, $this->charSet));
                        break;
                    case 'Subject':
                        $docProps->setSubject(self::convertStringEncoding($propertyValue, $this->charSet));
                        break;
                    case 'Author':
                        $docProps->setCreator(self::convertStringEncoding($propertyValue, $this->charSet));
                        break;
                    case 'Created':
                        $creationDate = strtotime($propertyValue);
                        $docProps->setCreated($creationDate);
                        break;
                    case 'LastAuthor':
                        $docProps->setLastModifiedBy(self::convertStringEncoding($propertyValue, $this->charSet));
                        break;
                    case 'LastSaved':
                        $lastSaveDate = strtotime($propertyValue);
                        $docProps->setModified($lastSaveDate);
                        break;
                    case 'Company':
                        $docProps->setCompany(self::convertStringEncoding($propertyValue, $this->charSet));
                        break;
                    case 'Category':
                        $docProps->setCategory(self::convertStringEncoding($propertyValue, $this->charSet));
                        break;
                    case 'Manager':
                        $docProps->setManager(self::convertStringEncoding($propertyValue, $this->charSet));
                        break;
                    case 'Keywords':
                        $docProps->setKeywords(self::convertStringEncoding($propertyValue, $this->charSet));
                        break;
                    case 'Description':
                        $docProps->setDescription(self::convertStringEncoding($propertyValue, $this->charSet));
                        break;
                }
            }
        }
        if (isset($xml->CustomDocumentProperties)) {
            foreach ($xml->CustomDocumentProperties[0] as $propertyName => $propertyValue) {
                $propertyAttributes = $propertyValue->attributes($namespaces['dt']);
                $propertyName = preg_replace_callback('/_x([0-9a-z]{4})_/', 'PHPExcel_Reader_Excel2003XML::hex2str', $propertyName);
                $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_UNKNOWN;
                switch ((string) $propertyAttributes) {
                    case 'string':
                        $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING;
                        $propertyValue = trim($propertyValue);
                        break;
                    case 'boolean':
                        $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN;
                        $propertyValue = (bool) $propertyValue;
                        break;
                    case 'integer':
                        $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_INTEGER;
                        $propertyValue = intval($propertyValue);
                        break;
                    case 'float':
                        $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT;
                        $propertyValue = floatval($propertyValue);
                        break;
                    case 'dateTime.tz':
                        $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE;
                        $propertyValue = strtotime(trim($propertyValue));
                        break;
                }
                $docProps->setCustomProperty($propertyName, $propertyValue, $propertyType);
            }
        }
        foreach ($xml->Styles[0] as $style) {
            $style_ss = $style->attributes($namespaces['ss']);
            $styleID = (string) $style_ss['ID'];
//            echo 'Style ID = '.$styleID.'
';
            if ($styleID == 'Default') {
                $this->styles['Default'] = array();
            } else {
                $this->styles[$styleID] = $this->styles['Default'];
            }
            foreach ($style as $styleType => $styleData) {
                $styleAttributes = $styleData->attributes($namespaces['ss']);
//                echo $styleType.'
';
                switch ($styleType) {
                    case 'Alignment':
                        foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) {
//                                echo $styleAttributeKey.' = '.$styleAttributeValue.'
';
                            $styleAttributeValue = (string) $styleAttributeValue;
                            switch ($styleAttributeKey) {
                                case 'Vertical':
                                    if (self::identifyFixedStyleValue($verticalAlignmentStyles, $styleAttributeValue)) {
                                        $this->styles[$styleID]['alignment']['vertical'] = $styleAttributeValue;
                                    }
                                    break;
                                case 'Horizontal':
                                    if (self::identifyFixedStyleValue($horizontalAlignmentStyles, $styleAttributeValue)) {
                                        $this->styles[$styleID]['alignment']['horizontal'] = $styleAttributeValue;
                                    }
                                    break;
                                case 'WrapText':
                                    $this->styles[$styleID]['alignment']['wrap'] = true;
                                    break;
                            }
                        }
                        break;
                    case 'Borders':
                        foreach ($styleData->Border as $borderStyle) {
                            $borderAttributes = $borderStyle->attributes($namespaces['ss']);
                            $thisBorder = array();
                            foreach ($borderAttributes as $borderStyleKey => $borderStyleValue) {
//                                    echo $borderStyleKey.' = '.$borderStyleValue.'
';
                                switch ($borderStyleKey) {
                                    case 'LineStyle':
                                        $thisBorder['style'] = PHPExcel_Style_Border::BORDER_MEDIUM;
//                                                $thisBorder['style'] = $borderStyleValue;
                                        break;
                                    case 'Weight':
//                                                $thisBorder['style'] = $borderStyleValue;
                                        break;
                                    case 'Position':
                                        $borderPosition = strtolower($borderStyleValue);
                                        break;
                                    case 'Color':
                                        $borderColour = substr($borderStyleValue, 1);
                                        $thisBorder['color']['rgb'] = $borderColour;
                                        break;
                                }
                            }
                            if (!empty($thisBorder)) {
                                if (($borderPosition == 'left') || ($borderPosition == 'right') || ($borderPosition == 'top') || ($borderPosition == 'bottom')) {
                                    $this->styles[$styleID]['borders'][$borderPosition] = $thisBorder;
                                }
                            }
                        }
                        break;
                    case 'Font':
                        foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) {
//                                echo $styleAttributeKey.' = '.$styleAttributeValue.'
';
                            $styleAttributeValue = (string) $styleAttributeValue;
                            switch ($styleAttributeKey) {
                                case 'FontName':
                                    $this->styles[$styleID]['font']['name'] = $styleAttributeValue;
                                    break;
                                case 'Size':
                                    $this->styles[$styleID]['font']['size'] = $styleAttributeValue;
                                    break;
                                case 'Color':
                                    $this->styles[$styleID]['font']['color']['rgb'] = substr($styleAttributeValue, 1);
                                    break;
                                case 'Bold':
                                    $this->styles[$styleID]['font']['bold'] = true;
                                    break;
                                case 'Italic':
                                    $this->styles[$styleID]['font']['italic'] = true;
                                    break;
                                case 'Underline':
                                    if (self::identifyFixedStyleValue($underlineStyles, $styleAttributeValue)) {
                                        $this->styles[$styleID]['font']['underline'] = $styleAttributeValue;
                                    }
                                    break;
                            }
                        }
                        break;
                    case 'Interior':
                        foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) {
//                                echo $styleAttributeKey.' = '.$styleAttributeValue.'
';
                            switch ($styleAttributeKey) {
                                case 'Color':
                                    $this->styles[$styleID]['fill']['color']['rgb'] = substr($styleAttributeValue, 1);
                                    break;
                            }
                        }
                        break;
                    case 'NumberFormat':
                        foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) {
//                                echo $styleAttributeKey.' = '.$styleAttributeValue.'
';
                            $styleAttributeValue = str_replace($fromFormats, $toFormats, $styleAttributeValue);
                            switch ($styleAttributeValue) {
                                case 'Short Date':
                                    $styleAttributeValue = 'dd/mm/yyyy';
                                    break;
                            }
                            if ($styleAttributeValue > '') {
                                $this->styles[$styleID]['numberformat']['code'] = $styleAttributeValue;
                            }
                        }
                        break;
                    case 'Protection':
                        foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) {
//                                echo $styleAttributeKey.' = '.$styleAttributeValue.'
';
                        }
                        break;
                }
            }
//            print_r($this->styles[$styleID]);
//            echo '