source: sourcecode/application/libraries/PHPExcel/Reader/SYLK.php @ 1

Last change on this file since 1 was 1, checked in by dungnv, 11 years ago
File size: 13.8 KB
Line 
1<?php
2/**
3 * PHPExcel
4 *
5 * Copyright (c) 2006 - 2014 PHPExcel
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20 *
21 * @category   PHPExcel
22 * @package    PHPExcel_Reader
23 * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
24 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
25 * @version    1.8.0, 2014-03-02
26 */
27
28
29/** PHPExcel root directory */
30if (!defined('PHPEXCEL_ROOT')) {
31        /**
32         * @ignore
33         */
34        define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');
35        require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
36}
37
38/**
39 * PHPExcel_Reader_SYLK
40 *
41 * @category   PHPExcel
42 * @package    PHPExcel_Reader
43 * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
44 */
45class PHPExcel_Reader_SYLK extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader
46{
47        /**
48         * Input encoding
49         *
50         * @var string
51         */
52        private $_inputEncoding = 'ANSI';
53
54        /**
55         * Sheet index to read
56         *
57         * @var int
58         */
59        private $_sheetIndex    = 0;
60
61        /**
62         * Formats
63         *
64         * @var array
65         */
66        private $_formats = array();
67
68        /**
69         * Format Count
70         *
71         * @var int
72         */
73        private $_format = 0;
74
75        /**
76         * Create a new PHPExcel_Reader_SYLK
77         */
78        public function __construct() {
79                $this->_readFilter      = new PHPExcel_Reader_DefaultReadFilter();
80        }
81
82        /**
83         * Validate that the current file is a SYLK file
84         *
85         * @return boolean
86         */
87        protected function _isValidFormat()
88        {
89                // Read sample data (first 2 KB will do)
90                $data = fread($this->_fileHandle, 2048);
91
92                // Count delimiters in file
93                $delimiterCount = substr_count($data, ';');
94                if ($delimiterCount < 1) {
95                        return FALSE;
96                }
97
98                // Analyze first line looking for ID; signature
99                $lines = explode("\n", $data);
100                if (substr($lines[0],0,4) != 'ID;P') {
101                        return FALSE;
102                }
103
104                return TRUE;
105        }
106
107        /**
108         * Set input encoding
109         *
110         * @param string $pValue Input encoding
111         */
112        public function setInputEncoding($pValue = 'ANSI')
113        {
114                $this->_inputEncoding = $pValue;
115                return $this;
116        }
117
118        /**
119         * Get input encoding
120         *
121         * @return string
122         */
123        public function getInputEncoding()
124        {
125                return $this->_inputEncoding;
126        }
127
128        /**
129         * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)
130         *
131         * @param   string     $pFilename
132         * @throws   PHPExcel_Reader_Exception
133         */
134        public function listWorksheetInfo($pFilename)
135        {
136                // Open file
137                $this->_openFile($pFilename);
138                if (!$this->_isValidFormat()) {
139                        fclose ($this->_fileHandle);
140                        throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file.");
141                }
142                $fileHandle = $this->_fileHandle;
143                rewind($fileHandle);
144
145                $worksheetInfo = array();
146                $worksheetInfo[0]['worksheetName'] = 'Worksheet';
147                $worksheetInfo[0]['lastColumnLetter'] = 'A';
148                $worksheetInfo[0]['lastColumnIndex'] = 0;
149                $worksheetInfo[0]['totalRows'] = 0;
150                $worksheetInfo[0]['totalColumns'] = 0;
151
152                // Loop through file
153                $rowData = array();
154
155                // loop through one row (line) at a time in the file
156                $rowIndex = 0;
157                while (($rowData = fgets($fileHandle)) !== FALSE) {
158                        $columnIndex = 0;
159
160                        // convert SYLK encoded $rowData to UTF-8
161                        $rowData = PHPExcel_Shared_String::SYLKtoUTF8($rowData);
162
163                        // explode each row at semicolons while taking into account that literal semicolon (;)
164                        // is escaped like this (;;)
165                        $rowData = explode("\t",str_replace('€',';',str_replace(';',"\t",str_replace(';;','€',rtrim($rowData)))));
166
167                        $dataType = array_shift($rowData);
168                        if ($dataType == 'C') {
169                                //  Read cell value data
170                                foreach($rowData as $rowDatum) {
171                                        switch($rowDatum{0}) {
172                                                case 'C' :
173                                                case 'X' :
174                                                        $columnIndex = substr($rowDatum,1) - 1;
175                                                        break;
176                                                case 'R' :
177                                                case 'Y' :
178                                                        $rowIndex = substr($rowDatum,1);
179                                                        break;
180                                        }
181
182                                        $worksheetInfo[0]['totalRows'] = max($worksheetInfo[0]['totalRows'], $rowIndex);
183                                        $worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], $columnIndex);
184                                }
185                        }
186                }
187
188                $worksheetInfo[0]['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']);
189                $worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1;
190
191                // Close file
192                fclose($fileHandle);
193
194                return $worksheetInfo;
195        }
196
197        /**
198         * Loads PHPExcel from file
199         *
200         * @param       string          $pFilename
201         * @return      PHPExcel
202         * @throws      PHPExcel_Reader_Exception
203         */
204        public function load($pFilename)
205        {
206                // Create new PHPExcel
207                $objPHPExcel = new PHPExcel();
208
209                // Load into this instance
210                return $this->loadIntoExisting($pFilename, $objPHPExcel);
211        }
212
213        /**
214         * Loads PHPExcel from file into PHPExcel instance
215         *
216         * @param       string          $pFilename
217         * @param       PHPExcel        $objPHPExcel
218         * @return      PHPExcel
219         * @throws      PHPExcel_Reader_Exception
220         */
221        public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)
222        {
223                // Open file
224                $this->_openFile($pFilename);
225                if (!$this->_isValidFormat()) {
226                        fclose ($this->_fileHandle);
227                        throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file.");
228                }
229                $fileHandle = $this->_fileHandle;
230                rewind($fileHandle);
231
232                // Create new PHPExcel
233                while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) {
234                        $objPHPExcel->createSheet();
235                }
236                $objPHPExcel->setActiveSheetIndex( $this->_sheetIndex );
237
238                $fromFormats    = array('\-',   '\ ');
239                $toFormats              = array('-',    ' ');
240
241                // Loop through file
242                $rowData = array();
243                $column = $row = '';
244
245                // loop through one row (line) at a time in the file
246                while (($rowData = fgets($fileHandle)) !== FALSE) {
247
248                        // convert SYLK encoded $rowData to UTF-8
249                        $rowData = PHPExcel_Shared_String::SYLKtoUTF8($rowData);
250
251                        // explode each row at semicolons while taking into account that literal semicolon (;)
252                        // is escaped like this (;;)
253                        $rowData = explode("\t",str_replace('€',';',str_replace(';',"\t",str_replace(';;','€',rtrim($rowData)))));
254
255                        $dataType = array_shift($rowData);
256                        //      Read shared styles
257                        if ($dataType == 'P') {
258                                $formatArray = array();
259                                foreach($rowData as $rowDatum) {
260                                        switch($rowDatum{0}) {
261                                                case 'P' :      $formatArray['numberformat']['code'] = str_replace($fromFormats,$toFormats,substr($rowDatum,1));
262                                                                        break;
263                                                case 'E' :
264                                                case 'F' :      $formatArray['font']['name'] = substr($rowDatum,1);
265                                                                        break;
266                                                case 'L' :      $formatArray['font']['size'] = substr($rowDatum,1);
267                                                                        break;
268                                                case 'S' :      $styleSettings = substr($rowDatum,1);
269                                                                        for ($i=0;$i<strlen($styleSettings);++$i) {
270                                                                                switch ($styleSettings{$i}) {
271                                                                                        case 'I' :      $formatArray['font']['italic'] = true;
272                                                                                                                break;
273                                                                                        case 'D' :      $formatArray['font']['bold'] = true;
274                                                                                                                break;
275                                                                                        case 'T' :      $formatArray['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN;
276                                                                                                                break;
277                                                                                        case 'B' :      $formatArray['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN;
278                                                                                                                break;
279                                                                                        case 'L' :      $formatArray['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN;
280                                                                                                                break;
281                                                                                        case 'R' :      $formatArray['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN;
282                                                                                                                break;
283                                                                                }
284                                                                        }
285                                                                        break;
286                                        }
287                                }
288                                $this->_formats['P'.$this->_format++] = $formatArray;
289                        //      Read cell value data
290                        } elseif ($dataType == 'C') {
291                                $hasCalculatedValue = false;
292                                $cellData = $cellDataFormula = '';
293                                foreach($rowData as $rowDatum) {
294                                        switch($rowDatum{0}) {
295                                                case 'C' :
296                                                case 'X' :      $column = substr($rowDatum,1);
297                                                                        break;
298                                                case 'R' :
299                                                case 'Y' :      $row = substr($rowDatum,1);
300                                                                        break;
301                                                case 'K' :      $cellData = substr($rowDatum,1);
302                                                                        break;
303                                                case 'E' :      $cellDataFormula = '='.substr($rowDatum,1);
304                                                                        //      Convert R1C1 style references to A1 style references (but only when not quoted)
305                                                                        $temp = explode('"',$cellDataFormula);
306                                                                        $key = false;
307                                                                        foreach($temp as &$value) {
308                                                                                //      Only count/replace in alternate array entries
309                                                                                if ($key = !$key) {
310                                                                                        preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/',$value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE);
311                                                                                        //      Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way
312                                                                                        //              through the formula from left to right. Reversing means that we work right to left.through
313                                                                                        //              the formula
314                                                                                        $cellReferences = array_reverse($cellReferences);
315                                                                                        //      Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent,
316                                                                                        //              then modify the formula to use that new reference
317                                                                                        foreach($cellReferences as $cellReference) {
318                                                                                                $rowReference = $cellReference[2][0];
319                                                                                                //      Empty R reference is the current row
320                                                                                                if ($rowReference == '') $rowReference = $row;
321                                                                                                //      Bracketed R references are relative to the current row
322                                                                                                if ($rowReference{0} == '[') $rowReference = $row + trim($rowReference,'[]');
323                                                                                                $columnReference = $cellReference[4][0];
324                                                                                                //      Empty C reference is the current column
325                                                                                                if ($columnReference == '') $columnReference = $column;
326                                                                                                //      Bracketed C references are relative to the current column
327                                                                                                if ($columnReference{0} == '[') $columnReference = $column + trim($columnReference,'[]');
328                                                                                                $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference;
329
330                                                                                                $value = substr_replace($value,$A1CellReference,$cellReference[0][1],strlen($cellReference[0][0]));
331                                                                                        }
332                                                                                }
333                                                                        }
334                                                                        unset($value);
335                                                                        //      Then rebuild the formula string
336                                                                        $cellDataFormula = implode('"',$temp);
337                                                                        $hasCalculatedValue = true;
338                                                                        break;
339                                        }
340                                }
341                                $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1);
342                                $cellData = PHPExcel_Calculation::_unwrapResult($cellData);
343
344                                // Set cell value
345                                $objPHPExcel->getActiveSheet()->getCell($columnLetter.$row)->setValue(($hasCalculatedValue) ? $cellDataFormula : $cellData);
346                                if ($hasCalculatedValue) {
347                                        $cellData = PHPExcel_Calculation::_unwrapResult($cellData);
348                                        $objPHPExcel->getActiveSheet()->getCell($columnLetter.$row)->setCalculatedValue($cellData);
349                                }
350                        //      Read cell formatting
351                        } elseif ($dataType == 'F') {
352                                $formatStyle = $columnWidth = $styleSettings = '';
353                                $styleData = array();
354                                foreach($rowData as $rowDatum) {
355                                        switch($rowDatum{0}) {
356                                                case 'C' :
357                                                case 'X' :      $column = substr($rowDatum,1);
358                                                                        break;
359                                                case 'R' :
360                                                case 'Y' :      $row = substr($rowDatum,1);
361                                                                        break;
362                                                case 'P' :      $formatStyle = $rowDatum;
363                                                                        break;
364                                                case 'W' :      list($startCol,$endCol,$columnWidth) = explode(' ',substr($rowDatum,1));
365                                                                        break;
366                                                case 'S' :      $styleSettings = substr($rowDatum,1);
367                                                                        for ($i=0;$i<strlen($styleSettings);++$i) {
368                                                                                switch ($styleSettings{$i}) {
369                                                                                        case 'I' :      $styleData['font']['italic'] = true;
370                                                                                                                break;
371                                                                                        case 'D' :      $styleData['font']['bold'] = true;
372                                                                                                                break;
373                                                                                        case 'T' :      $styleData['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN;
374                                                                                                                break;
375                                                                                        case 'B' :      $styleData['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN;
376                                                                                                                break;
377                                                                                        case 'L' :      $styleData['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN;
378                                                                                                                break;
379                                                                                        case 'R' :      $styleData['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN;
380                                                                                                                break;
381                                                                                }
382                                                                        }
383                                                                        break;
384                                        }
385                                }
386                                if (($formatStyle > '') && ($column > '') && ($row > '')) {
387                                        $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1);
388                                        if (isset($this->_formats[$formatStyle])) {
389                                                $objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($this->_formats[$formatStyle]);
390                                        }
391                                }
392                                if ((!empty($styleData)) && ($column > '') && ($row > '')) {
393                                        $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1);
394                                        $objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($styleData);
395                                }
396                                if ($columnWidth > '') {
397                                        if ($startCol == $endCol) {
398                                                $startCol = PHPExcel_Cell::stringFromColumnIndex($startCol-1);
399                                                $objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth);
400                                        } else {
401                                                $startCol = PHPExcel_Cell::stringFromColumnIndex($startCol-1);
402                                                $endCol = PHPExcel_Cell::stringFromColumnIndex($endCol-1);
403                                                $objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth);
404                                                do {
405                                                        $objPHPExcel->getActiveSheet()->getColumnDimension(++$startCol)->setWidth($columnWidth);
406                                                } while ($startCol != $endCol);
407                                        }
408                                }
409                        } else {
410                                foreach($rowData as $rowDatum) {
411                                        switch($rowDatum{0}) {
412                                                case 'C' :
413                                                case 'X' :      $column = substr($rowDatum,1);
414                                                                        break;
415                                                case 'R' :
416                                                case 'Y' :      $row = substr($rowDatum,1);
417                                                                        break;
418                                        }
419                                }
420                        }
421                }
422
423                // Close file
424                fclose($fileHandle);
425
426                // Return
427                return $objPHPExcel;
428        }
429
430        /**
431         * Get sheet index
432         *
433         * @return int
434         */
435        public function getSheetIndex() {
436                return $this->_sheetIndex;
437        }
438
439        /**
440         * Set sheet index
441         *
442         * @param       int             $pValue         Sheet index
443         * @return PHPExcel_Reader_SYLK
444         */
445        public function setSheetIndex($pValue = 0) {
446                $this->_sheetIndex = $pValue;
447                return $this;
448        }
449
450}
Note: See TracBrowser for help on using the repository browser.