1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61: if (!defined('PHPEXCEL_ROOT')) {
62: 63: 64:
65: define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');
66: require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
67: }
68:
69: 70: 71: 72: 73: 74: 75: 76: 77:
78: class PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader
79: {
80:
81: const XLS_BIFF8 = 0x0600;
82: const XLS_BIFF7 = 0x0500;
83: const XLS_WorkbookGlobals = 0x0005;
84: const XLS_Worksheet = 0x0010;
85:
86:
87: const XLS_Type_FORMULA = 0x0006;
88: const XLS_Type_EOF = 0x000a;
89: const XLS_Type_PROTECT = 0x0012;
90: const XLS_Type_OBJECTPROTECT = 0x0063;
91: const XLS_Type_SCENPROTECT = 0x00dd;
92: const XLS_Type_PASSWORD = 0x0013;
93: const XLS_Type_HEADER = 0x0014;
94: const XLS_Type_FOOTER = 0x0015;
95: const XLS_Type_EXTERNSHEET = 0x0017;
96: const XLS_Type_DEFINEDNAME = 0x0018;
97: const XLS_Type_VERTICALPAGEBREAKS = 0x001a;
98: const XLS_Type_HORIZONTALPAGEBREAKS = 0x001b;
99: const XLS_Type_NOTE = 0x001c;
100: const XLS_Type_SELECTION = 0x001d;
101: const XLS_Type_DATEMODE = 0x0022;
102: const XLS_Type_EXTERNNAME = 0x0023;
103: const XLS_Type_LEFTMARGIN = 0x0026;
104: const XLS_Type_RIGHTMARGIN = 0x0027;
105: const XLS_Type_TOPMARGIN = 0x0028;
106: const XLS_Type_BOTTOMMARGIN = 0x0029;
107: const XLS_Type_PRINTGRIDLINES = 0x002b;
108: const XLS_Type_FILEPASS = 0x002f;
109: const XLS_Type_FONT = 0x0031;
110: const XLS_Type_CONTINUE = 0x003c;
111: const XLS_Type_PANE = 0x0041;
112: const XLS_Type_CODEPAGE = 0x0042;
113: const XLS_Type_DEFCOLWIDTH = 0x0055;
114: const XLS_Type_OBJ = 0x005d;
115: const XLS_Type_COLINFO = 0x007d;
116: const XLS_Type_IMDATA = 0x007f;
117: const XLS_Type_SHEETPR = 0x0081;
118: const XLS_Type_HCENTER = 0x0083;
119: const XLS_Type_VCENTER = 0x0084;
120: const XLS_Type_SHEET = 0x0085;
121: const XLS_Type_PALETTE = 0x0092;
122: const XLS_Type_SCL = 0x00a0;
123: const XLS_Type_PAGESETUP = 0x00a1;
124: const XLS_Type_MULRK = 0x00bd;
125: const XLS_Type_MULBLANK = 0x00be;
126: const XLS_Type_DBCELL = 0x00d7;
127: const XLS_Type_XF = 0x00e0;
128: const XLS_Type_MERGEDCELLS = 0x00e5;
129: const XLS_Type_MSODRAWINGGROUP = 0x00eb;
130: const XLS_Type_MSODRAWING = 0x00ec;
131: const XLS_Type_SST = 0x00fc;
132: const XLS_Type_LABELSST = 0x00fd;
133: const XLS_Type_EXTSST = 0x00ff;
134: const XLS_Type_EXTERNALBOOK = 0x01ae;
135: const XLS_Type_DATAVALIDATIONS = 0x01b2;
136: const XLS_Type_TXO = 0x01b6;
137: const XLS_Type_HYPERLINK = 0x01b8;
138: const XLS_Type_DATAVALIDATION = 0x01be;
139: const XLS_Type_DIMENSION = 0x0200;
140: const XLS_Type_BLANK = 0x0201;
141: const XLS_Type_NUMBER = 0x0203;
142: const XLS_Type_LABEL = 0x0204;
143: const XLS_Type_BOOLERR = 0x0205;
144: const XLS_Type_STRING = 0x0207;
145: const XLS_Type_ROW = 0x0208;
146: const XLS_Type_INDEX = 0x020b;
147: const XLS_Type_ARRAY = 0x0221;
148: const XLS_Type_DEFAULTROWHEIGHT = 0x0225;
149: const XLS_Type_WINDOW2 = 0x023e;
150: const XLS_Type_RK = 0x027e;
151: const XLS_Type_STYLE = 0x0293;
152: const XLS_Type_FORMAT = 0x041e;
153: const XLS_Type_SHAREDFMLA = 0x04bc;
154: const XLS_Type_BOF = 0x0809;
155: const XLS_Type_SHEETPROTECTION = 0x0867;
156: const XLS_Type_RANGEPROTECTION = 0x0868;
157: const XLS_Type_SHEETLAYOUT = 0x0862;
158: const XLS_Type_XFEXT = 0x087d;
159: const XLS_Type_PAGELAYOUTVIEW = 0x088b;
160: const XLS_Type_UNKNOWN = 0xffff;
161:
162:
163: const MS_BIFF_CRYPTO_NONE = 0;
164: const MS_BIFF_CRYPTO_XOR = 1;
165: const MS_BIFF_CRYPTO_RC4 = 2;
166:
167:
168: const REKEY_BLOCK = 0x400;
169:
170: 171: 172: 173: 174:
175: private $_summaryInformation;
176:
177: 178: 179: 180: 181:
182: private $_documentSummaryInformation;
183:
184: 185: 186: 187: 188:
189: private $_userDefinedProperties;
190:
191: 192: 193: 194: 195:
196: private $_data;
197:
198: 199: 200: 201: 202:
203: private $_dataSize;
204:
205: 206: 207: 208: 209:
210: private $_pos;
211:
212: 213: 214: 215: 216:
217: private $_phpExcel;
218:
219: 220: 221: 222: 223:
224: private $_phpSheet;
225:
226: 227: 228: 229: 230:
231: private $_version;
232:
233: 234: 235: 236: 237: 238:
239: private $_codepage;
240:
241: 242: 243: 244: 245:
246: private $_formats;
247:
248: 249: 250: 251: 252:
253: private $_objFonts;
254:
255: 256: 257: 258: 259:
260: private $_palette;
261:
262: 263: 264: 265: 266:
267: private $_sheets;
268:
269: 270: 271: 272: 273:
274: private $_externalBooks;
275:
276: 277: 278: 279: 280:
281: private $_ref;
282:
283: 284: 285: 286: 287:
288: private $_externalNames;
289:
290: 291: 292: 293: 294:
295: private $_definedname;
296:
297: 298: 299: 300: 301:
302: private $_sst;
303:
304: 305: 306: 307: 308:
309: private $_frozen;
310:
311: 312: 313: 314: 315:
316: private $_isFitToPages;
317:
318: 319: 320: 321: 322:
323: private $_objs;
324:
325: 326: 327: 328: 329:
330: private $_textObjects;
331:
332: 333: 334: 335: 336:
337: private $_cellNotes;
338:
339: 340: 341: 342: 343:
344: private $_drawingGroupData;
345:
346: 347: 348: 349: 350:
351: private $_drawingData;
352:
353: 354: 355: 356: 357:
358: private $_xfIndex;
359:
360: 361: 362: 363: 364:
365: private $_mapCellXfIndex;
366:
367: 368: 369: 370: 371:
372: private $_mapCellStyleXfIndex;
373:
374: 375: 376: 377: 378:
379: private $_sharedFormulas;
380:
381: 382: 383: 384: 385: 386:
387: private $_sharedFormulaParts;
388:
389: 390: 391: 392: 393:
394: private $_encryption = 0;
395:
396: 397: 398: 399: 400:
401: private $_encryptionStartPos = false;
402:
403: 404: 405: 406: 407:
408: private $_rc4Key = null;
409:
410: 411: 412: 413: 414:
415: private $_rc4Pos = 0;
416:
417: 418: 419: 420: 421:
422: private $_md5Ctxt = null;
423:
424: 425: 426:
427: public function __construct() {
428: $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter();
429: }
430:
431:
432: 433: 434: 435: 436: 437: 438:
439: public function canRead($pFilename)
440: {
441:
442: if (!file_exists($pFilename)) {
443: throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
444: }
445:
446: try {
447:
448: $ole = new PHPExcel_Shared_OLERead();
449:
450:
451: $res = $ole->read($pFilename);
452: return true;
453: } catch (PHPExcel_Exception $e) {
454: return false;
455: }
456: }
457:
458:
459: 460: 461: 462: 463: 464:
465: public function listWorksheetNames($pFilename)
466: {
467:
468: if (!file_exists($pFilename)) {
469: throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
470: }
471:
472: $worksheetNames = array();
473:
474:
475: $this->_loadOLE($pFilename);
476:
477:
478: $this->_dataSize = strlen($this->_data);
479:
480: $this->_pos = 0;
481: $this->_sheets = array();
482:
483:
484: while ($this->_pos < $this->_dataSize) {
485: $code = self::_GetInt2d($this->_data, $this->_pos);
486:
487: switch ($code) {
488: case self::XLS_Type_BOF: $this->_readBof(); break;
489: case self::XLS_Type_SHEET: $this->_readSheet(); break;
490: case self::XLS_Type_EOF: $this->_readDefault(); break 2;
491: default: $this->_readDefault(); break;
492: }
493: }
494:
495: foreach ($this->_sheets as $sheet) {
496: if ($sheet['sheetType'] != 0x00) {
497:
498: continue;
499: }
500:
501: $worksheetNames[] = $sheet['name'];
502: }
503:
504: return $worksheetNames;
505: }
506:
507:
508: 509: 510: 511: 512: 513:
514: public function listWorksheetInfo($pFilename)
515: {
516:
517: if (!file_exists($pFilename)) {
518: throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
519: }
520:
521: $worksheetInfo = array();
522:
523:
524: $this->_loadOLE($pFilename);
525:
526:
527: $this->_dataSize = strlen($this->_data);
528:
529:
530: $this->_pos = 0;
531: $this->_sheets = array();
532:
533:
534: while ($this->_pos < $this->_dataSize) {
535: $code = self::_GetInt2d($this->_data, $this->_pos);
536:
537: switch ($code) {
538: case self::XLS_Type_BOF: $this->_readBof(); break;
539: case self::XLS_Type_SHEET: $this->_readSheet(); break;
540: case self::XLS_Type_EOF: $this->_readDefault(); break 2;
541: default: $this->_readDefault(); break;
542: }
543: }
544:
545:
546: foreach ($this->_sheets as $sheet) {
547:
548: if ($sheet['sheetType'] != 0x00) {
549:
550:
551:
552: continue;
553: }
554:
555: $tmpInfo = array();
556: $tmpInfo['worksheetName'] = $sheet['name'];
557: $tmpInfo['lastColumnLetter'] = 'A';
558: $tmpInfo['lastColumnIndex'] = 0;
559: $tmpInfo['totalRows'] = 0;
560: $tmpInfo['totalColumns'] = 0;
561:
562: $this->_pos = $sheet['offset'];
563:
564: while ($this->_pos <= $this->_dataSize - 4) {
565: $code = self::_GetInt2d($this->_data, $this->_pos);
566:
567: switch ($code) {
568: case self::XLS_Type_RK:
569: case self::XLS_Type_LABELSST:
570: case self::XLS_Type_NUMBER:
571: case self::XLS_Type_FORMULA:
572: case self::XLS_Type_BOOLERR:
573: case self::XLS_Type_LABEL:
574: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
575: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
576:
577:
578: $this->_pos += 4 + $length;
579:
580: $rowIndex = self::_GetInt2d($recordData, 0) + 1;
581: $columnIndex = self::_GetInt2d($recordData, 2);
582:
583: $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex);
584: $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex);
585: break;
586: case self::XLS_Type_BOF: $this->_readBof(); break;
587: case self::XLS_Type_EOF: $this->_readDefault(); break 2;
588: default: $this->_readDefault(); break;
589: }
590: }
591:
592: $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
593: $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;
594:
595: $worksheetInfo[] = $tmpInfo;
596: }
597:
598: return $worksheetInfo;
599: }
600:
601:
602: 603: 604: 605: 606: 607: 608:
609: public function load($pFilename)
610: {
611:
612: $this->_loadOLE($pFilename);
613:
614:
615: $this->_phpExcel = new PHPExcel;
616: $this->_phpExcel->removeSheetByIndex(0);
617: if (!$this->_readDataOnly) {
618: $this->_phpExcel->removeCellStyleXfByIndex(0);
619: $this->_phpExcel->removeCellXfByIndex(0);
620: }
621:
622:
623: $this->_readSummaryInformation();
624:
625:
626: $this->_readDocumentSummaryInformation();
627:
628:
629: $this->_dataSize = strlen($this->_data);
630:
631:
632: $this->_pos = 0;
633: $this->_codepage = 'CP1252';
634: $this->_formats = array();
635: $this->_objFonts = array();
636: $this->_palette = array();
637: $this->_sheets = array();
638: $this->_externalBooks = array();
639: $this->_ref = array();
640: $this->_definedname = array();
641: $this->_sst = array();
642: $this->_drawingGroupData = '';
643: $this->_xfIndex = '';
644: $this->_mapCellXfIndex = array();
645: $this->_mapCellStyleXfIndex = array();
646:
647:
648: while ($this->_pos < $this->_dataSize) {
649: $code = self::_GetInt2d($this->_data, $this->_pos);
650:
651: switch ($code) {
652: case self::XLS_Type_BOF: $this->_readBof(); break;
653: case self::XLS_Type_FILEPASS: $this->_readFilepass(); break;
654: case self::XLS_Type_CODEPAGE: $this->_readCodepage(); break;
655: case self::XLS_Type_DATEMODE: $this->_readDateMode(); break;
656: case self::XLS_Type_FONT: $this->_readFont(); break;
657: case self::XLS_Type_FORMAT: $this->_readFormat(); break;
658: case self::XLS_Type_XF: $this->_readXf(); break;
659: case self::XLS_Type_XFEXT: $this->_readXfExt(); break;
660: case self::XLS_Type_STYLE: $this->_readStyle(); break;
661: case self::XLS_Type_PALETTE: $this->_readPalette(); break;
662: case self::XLS_Type_SHEET: $this->_readSheet(); break;
663: case self::XLS_Type_EXTERNALBOOK: $this->_readExternalBook(); break;
664: case self::XLS_Type_EXTERNNAME: $this->_readExternName(); break;
665: case self::XLS_Type_EXTERNSHEET: $this->_readExternSheet(); break;
666: case self::XLS_Type_DEFINEDNAME: $this->_readDefinedName(); break;
667: case self::XLS_Type_MSODRAWINGGROUP: $this->_readMsoDrawingGroup(); break;
668: case self::XLS_Type_SST: $this->_readSst(); break;
669: case self::XLS_Type_EOF: $this->_readDefault(); break 2;
670: default: $this->_readDefault(); break;
671: }
672: }
673:
674:
675:
676: if (!$this->_readDataOnly) {
677: foreach ($this->_objFonts as $objFont) {
678: if (isset($objFont->colorIndex)) {
679: $color = self::_readColor($objFont->colorIndex,$this->_palette,$this->_version);
680: $objFont->getColor()->setRGB($color['rgb']);
681: }
682: }
683:
684: foreach ($this->_phpExcel->getCellXfCollection() as $objStyle) {
685:
686: $fill = $objStyle->getFill();
687:
688: if (isset($fill->startcolorIndex)) {
689: $startColor = self::_readColor($fill->startcolorIndex,$this->_palette,$this->_version);
690: $fill->getStartColor()->setRGB($startColor['rgb']);
691: }
692:
693: if (isset($fill->endcolorIndex)) {
694: $endColor = self::_readColor($fill->endcolorIndex,$this->_palette,$this->_version);
695: $fill->getEndColor()->setRGB($endColor['rgb']);
696: }
697:
698:
699: $top = $objStyle->getBorders()->getTop();
700: $right = $objStyle->getBorders()->getRight();
701: $bottom = $objStyle->getBorders()->getBottom();
702: $left = $objStyle->getBorders()->getLeft();
703: $diagonal = $objStyle->getBorders()->getDiagonal();
704:
705: if (isset($top->colorIndex)) {
706: $borderTopColor = self::_readColor($top->colorIndex,$this->_palette,$this->_version);
707: $top->getColor()->setRGB($borderTopColor['rgb']);
708: }
709:
710: if (isset($right->colorIndex)) {
711: $borderRightColor = self::_readColor($right->colorIndex,$this->_palette,$this->_version);
712: $right->getColor()->setRGB($borderRightColor['rgb']);
713: }
714:
715: if (isset($bottom->colorIndex)) {
716: $borderBottomColor = self::_readColor($bottom->colorIndex,$this->_palette,$this->_version);
717: $bottom->getColor()->setRGB($borderBottomColor['rgb']);
718: }
719:
720: if (isset($left->colorIndex)) {
721: $borderLeftColor = self::_readColor($left->colorIndex,$this->_palette,$this->_version);
722: $left->getColor()->setRGB($borderLeftColor['rgb']);
723: }
724:
725: if (isset($diagonal->colorIndex)) {
726: $borderDiagonalColor = self::_readColor($diagonal->colorIndex,$this->_palette,$this->_version);
727: $diagonal->getColor()->setRGB($borderDiagonalColor['rgb']);
728: }
729: }
730: }
731:
732:
733: if (!$this->_readDataOnly && $this->_drawingGroupData) {
734: $escherWorkbook = new PHPExcel_Shared_Escher();
735: $reader = new PHPExcel_Reader_Excel5_Escher($escherWorkbook);
736: $escherWorkbook = $reader->load($this->_drawingGroupData);
737:
738:
739:
740:
741: }
742:
743:
744: foreach ($this->_sheets as $sheet) {
745:
746: if ($sheet['sheetType'] != 0x00) {
747:
748: continue;
749: }
750:
751:
752: if (isset($this->_loadSheetsOnly) && !in_array($sheet['name'], $this->_loadSheetsOnly)) {
753: continue;
754: }
755:
756:
757: $this->_phpSheet = $this->_phpExcel->createSheet();
758:
759:
760:
761: $this->_phpSheet->setTitle($sheet['name'],false);
762: $this->_phpSheet->setSheetState($sheet['sheetState']);
763:
764: $this->_pos = $sheet['offset'];
765:
766:
767: $this->_isFitToPages = false;
768:
769:
770: $this->_drawingData = '';
771:
772:
773: $this->_objs = array();
774:
775:
776: $this->_sharedFormulaParts = array();
777:
778:
779: $this->_sharedFormulas = array();
780:
781:
782: $this->_textObjects = array();
783:
784:
785: $this->_cellNotes = array();
786: $this->textObjRef = -1;
787:
788: while ($this->_pos <= $this->_dataSize - 4) {
789: $code = self::_GetInt2d($this->_data, $this->_pos);
790:
791: switch ($code) {
792: case self::XLS_Type_BOF: $this->_readBof(); break;
793: case self::XLS_Type_PRINTGRIDLINES: $this->_readPrintGridlines(); break;
794: case self::XLS_Type_DEFAULTROWHEIGHT: $this->_readDefaultRowHeight(); break;
795: case self::XLS_Type_SHEETPR: $this->_readSheetPr(); break;
796: case self::XLS_Type_HORIZONTALPAGEBREAKS: $this->_readHorizontalPageBreaks(); break;
797: case self::XLS_Type_VERTICALPAGEBREAKS: $this->_readVerticalPageBreaks(); break;
798: case self::XLS_Type_HEADER: $this->_readHeader(); break;
799: case self::XLS_Type_FOOTER: $this->_readFooter(); break;
800: case self::XLS_Type_HCENTER: $this->_readHcenter(); break;
801: case self::XLS_Type_VCENTER: $this->_readVcenter(); break;
802: case self::XLS_Type_LEFTMARGIN: $this->_readLeftMargin(); break;
803: case self::XLS_Type_RIGHTMARGIN: $this->_readRightMargin(); break;
804: case self::XLS_Type_TOPMARGIN: $this->_readTopMargin(); break;
805: case self::XLS_Type_BOTTOMMARGIN: $this->_readBottomMargin(); break;
806: case self::XLS_Type_PAGESETUP: $this->_readPageSetup(); break;
807: case self::XLS_Type_PROTECT: $this->_readProtect(); break;
808: case self::XLS_Type_SCENPROTECT: $this->_readScenProtect(); break;
809: case self::XLS_Type_OBJECTPROTECT: $this->_readObjectProtect(); break;
810: case self::XLS_Type_PASSWORD: $this->_readPassword(); break;
811: case self::XLS_Type_DEFCOLWIDTH: $this->_readDefColWidth(); break;
812: case self::XLS_Type_COLINFO: $this->_readColInfo(); break;
813: case self::XLS_Type_DIMENSION: $this->_readDefault(); break;
814: case self::XLS_Type_ROW: $this->_readRow(); break;
815: case self::XLS_Type_DBCELL: $this->_readDefault(); break;
816: case self::XLS_Type_RK: $this->_readRk(); break;
817: case self::XLS_Type_LABELSST: $this->_readLabelSst(); break;
818: case self::XLS_Type_MULRK: $this->_readMulRk(); break;
819: case self::XLS_Type_NUMBER: $this->_readNumber(); break;
820: case self::XLS_Type_FORMULA: $this->_readFormula(); break;
821: case self::XLS_Type_SHAREDFMLA: $this->_readSharedFmla(); break;
822: case self::XLS_Type_BOOLERR: $this->_readBoolErr(); break;
823: case self::XLS_Type_MULBLANK: $this->_readMulBlank(); break;
824: case self::XLS_Type_LABEL: $this->_readLabel(); break;
825: case self::XLS_Type_BLANK: $this->_readBlank(); break;
826: case self::XLS_Type_MSODRAWING: $this->_readMsoDrawing(); break;
827: case self::XLS_Type_OBJ: $this->_readObj(); break;
828: case self::XLS_Type_WINDOW2: $this->_readWindow2(); break;
829: case self::XLS_Type_PAGELAYOUTVIEW: $this->_readPageLayoutView(); break;
830: case self::XLS_Type_SCL: $this->_readScl(); break;
831: case self::XLS_Type_PANE: $this->_readPane(); break;
832: case self::XLS_Type_SELECTION: $this->_readSelection(); break;
833: case self::XLS_Type_MERGEDCELLS: $this->_readMergedCells(); break;
834: case self::XLS_Type_HYPERLINK: $this->_readHyperLink(); break;
835: case self::XLS_Type_DATAVALIDATIONS: $this->_readDataValidations(); break;
836: case self::XLS_Type_DATAVALIDATION: $this->_readDataValidation(); break;
837: case self::XLS_Type_SHEETLAYOUT: $this->_readSheetLayout(); break;
838: case self::XLS_Type_SHEETPROTECTION: $this->_readSheetProtection(); break;
839: case self::XLS_Type_RANGEPROTECTION: $this->_readRangeProtection(); break;
840: case self::XLS_Type_NOTE: $this->_readNote(); break;
841:
842: case self::XLS_Type_TXO: $this->_readTextObject(); break;
843: case self::XLS_Type_CONTINUE: $this->_readContinue(); break;
844: case self::XLS_Type_EOF: $this->_readDefault(); break 2;
845: default: $this->_readDefault(); break;
846: }
847:
848: }
849:
850:
851: if (!$this->_readDataOnly && $this->_drawingData) {
852: $escherWorksheet = new PHPExcel_Shared_Escher();
853: $reader = new PHPExcel_Reader_Excel5_Escher($escherWorksheet);
854: $escherWorksheet = $reader->load($this->_drawingData);
855:
856:
857:
858:
859:
860:
861: $allSpContainers = $escherWorksheet->getDgContainer()->getSpgrContainer()->getAllSpContainers();
862: }
863:
864:
865: foreach ($this->_objs as $n => $obj) {
866:
867:
868:
869:
870:
871: if (isset($allSpContainers[$n + 1]) && is_object($allSpContainers[$n + 1])) {
872: $spContainer = $allSpContainers[$n + 1];
873:
874:
875: if ($spContainer->getNestingLevel() > 1) {
876: continue;
877: }
878:
879:
880: list($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($spContainer->getStartCoordinates());
881: list($endColumn, $endRow) = PHPExcel_Cell::coordinateFromString($spContainer->getEndCoordinates());
882:
883: $startOffsetX = $spContainer->getStartOffsetX();
884: $startOffsetY = $spContainer->getStartOffsetY();
885: $endOffsetX = $spContainer->getEndOffsetX();
886: $endOffsetY = $spContainer->getEndOffsetY();
887:
888: $width = PHPExcel_Shared_Excel5::getDistanceX($this->_phpSheet, $startColumn, $startOffsetX, $endColumn, $endOffsetX);
889: $height = PHPExcel_Shared_Excel5::getDistanceY($this->_phpSheet, $startRow, $startOffsetY, $endRow, $endOffsetY);
890:
891:
892: $offsetX = $startOffsetX * PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, $startColumn) / 1024;
893: $offsetY = $startOffsetY * PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $startRow) / 256;
894:
895: switch ($obj['otObjType']) {
896: case 0x19:
897:
898:
899:
900:
901: if (isset($this->_cellNotes[$obj['idObjID']])) {
902: $cellNote = $this->_cellNotes[$obj['idObjID']];
903:
904: if (isset($this->_textObjects[$obj['idObjID']])) {
905: $textObject = $this->_textObjects[$obj['idObjID']];
906: $this->_cellNotes[$obj['idObjID']]['objTextData'] = $textObject;
907: }
908: }
909: break;
910:
911: case 0x08:
912:
913:
914:
915:
916: $BSEindex = $spContainer->getOPT(0x0104);
917: $BSECollection = $escherWorkbook->getDggContainer()->getBstoreContainer()->getBSECollection();
918: $BSE = $BSECollection[$BSEindex - 1];
919: $blipType = $BSE->getBlipType();
920:
921:
922: if ($blip = $BSE->getBlip()) {
923: $ih = imagecreatefromstring($blip->getData());
924: $drawing = new PHPExcel_Worksheet_MemoryDrawing();
925: $drawing->setImageResource($ih);
926:
927:
928: $drawing->setResizeProportional(false);
929: $drawing->setWidth($width);
930: $drawing->setHeight($height);
931: $drawing->setOffsetX($offsetX);
932: $drawing->setOffsetY($offsetY);
933:
934: switch ($blipType) {
935: case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG:
936: $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG);
937: $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG);
938: break;
939:
940: case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG:
941: $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG);
942: $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG);
943: break;
944: }
945:
946: $drawing->setWorksheet($this->_phpSheet);
947: $drawing->setCoordinates($spContainer->getStartCoordinates());
948: }
949:
950: break;
951:
952: default:
953:
954: break;
955:
956: }
957: }
958: }
959:
960:
961: if ($this->_version == self::XLS_BIFF8) {
962: foreach ($this->_sharedFormulaParts as $cell => $baseCell) {
963: list($column, $row) = PHPExcel_Cell::coordinateFromString($cell);
964: if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle()) ) {
965: $formula = $this->_getFormulaFromStructure($this->_sharedFormulas[$baseCell], $cell);
966: $this->_phpSheet->getCell($cell)->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA);
967: }
968: }
969: }
970:
971: if (!empty($this->_cellNotes)) {
972: foreach($this->_cellNotes as $note => $noteDetails) {
973: if (!isset($noteDetails['objTextData'])) {
974: if (isset($this->_textObjects[$note])) {
975: $textObject = $this->_textObjects[$note];
976: $noteDetails['objTextData'] = $textObject;
977: } else {
978: $noteDetails['objTextData']['text'] = '';
979: }
980: }
981:
982:
983:
984: $cellAddress = str_replace('$','',$noteDetails['cellRef']);
985: $this->_phpSheet->getComment( $cellAddress )
986: ->setAuthor( $noteDetails['author'] )
987: ->setText($this->_parseRichText($noteDetails['objTextData']['text']) );
988: }
989: }
990: }
991:
992:
993: foreach ($this->_definedname as $definedName) {
994: if ($definedName['isBuiltInName']) {
995: switch ($definedName['name']) {
996:
997: case pack('C', 0x06):
998:
999:
1000: $ranges = explode(',', $definedName['formula']);
1001:
1002: $extractedRanges = array();
1003: foreach ($ranges as $range) {
1004:
1005:
1006:
1007:
1008: $explodes = explode('!', $range);
1009: $sheetName = trim($explodes[0], "'");
1010:
1011: if (count($explodes) == 2) {
1012: if (strpos($explodes[1], ':') === FALSE) {
1013: $explodes[1] = $explodes[1] . ':' . $explodes[1];
1014: }
1015: $extractedRanges[] = str_replace('$', '', $explodes[1]);
1016: }
1017: }
1018: if ($docSheet = $this->_phpExcel->getSheetByName($sheetName)) {
1019: $docSheet->getPageSetup()->setPrintArea(implode(',', $extractedRanges));
1020: }
1021: break;
1022:
1023: case pack('C', 0x07):
1024:
1025:
1026:
1027:
1028:
1029:
1030:
1031:
1032:
1033:
1034:
1035: $ranges = explode(',', $definedName['formula']);
1036:
1037: foreach ($ranges as $range) {
1038:
1039:
1040:
1041:
1042: $explodes = explode('!', $range);
1043:
1044: if (count($explodes) == 2) {
1045: if ($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) {
1046:
1047: $extractedRange = $explodes[1];
1048: $extractedRange = str_replace('$', '', $extractedRange);
1049:
1050: $coordinateStrings = explode(':', $extractedRange);
1051: if (count($coordinateStrings) == 2) {
1052: list($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[0]);
1053: list($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[1]);
1054:
1055: if ($firstColumn == 'A' and $lastColumn == 'IV') {
1056:
1057: $docSheet->getPageSetup()->setRowsToRepeatAtTop(array($firstRow, $lastRow));
1058: } elseif ($firstRow == 1 and $lastRow == 65536) {
1059:
1060: $docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($firstColumn, $lastColumn));
1061: }
1062: }
1063: }
1064: }
1065: }
1066: break;
1067:
1068: }
1069: } else {
1070:
1071: $explodes = explode('!', $definedName['formula']);
1072:
1073: if (count($explodes) == 2) {
1074: if (($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) ||
1075: ($docSheet = $this->_phpExcel->getSheetByName(trim($explodes[0],"'")))) {
1076: $extractedRange = $explodes[1];
1077: $extractedRange = str_replace('$', '', $extractedRange);
1078:
1079: $localOnly = ($definedName['scope'] == 0) ? false : true;
1080:
1081: $scope = ($definedName['scope'] == 0) ?
1082: null : $this->_phpExcel->getSheetByName($this->_sheets[$definedName['scope'] - 1]['name']);
1083:
1084: $this->_phpExcel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $docSheet, $extractedRange, $localOnly, $scope) );
1085: }
1086: } else {
1087:
1088:
1089: }
1090: }
1091: }
1092:
1093: return $this->_phpExcel;
1094: }
1095:
1096: 1097: 1098: 1099: 1100: 1101: 1102: 1103: 1104:
1105: private function _readRecordData($data, $pos, $len)
1106: {
1107: $data = substr($data, $pos, $len);
1108:
1109:
1110: if ($this->_encryption == self::MS_BIFF_CRYPTO_NONE || $pos < $this->_encryptionStartPos) {
1111: return $data;
1112: }
1113:
1114: $recordData = '';
1115: if ($this->_encryption == self::MS_BIFF_CRYPTO_RC4) {
1116:
1117: $oldBlock = floor($this->_rc4Pos / self::REKEY_BLOCK);
1118: $block = floor($pos / self::REKEY_BLOCK);
1119: $endBlock = floor(($pos + $len) / self::REKEY_BLOCK);
1120:
1121:
1122:
1123: if ($block != $oldBlock || $pos < $this->_rc4Pos || !$this->_rc4Key) {
1124: $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt);
1125: $step = $pos % self::REKEY_BLOCK;
1126: } else {
1127: $step = $pos - $this->_rc4Pos;
1128: }
1129: $this->_rc4Key->RC4(str_repeat("\0", $step));
1130:
1131:
1132: while ($block != $endBlock) {
1133: $step = self::REKEY_BLOCK - ($pos % self::REKEY_BLOCK);
1134: $recordData .= $this->_rc4Key->RC4(substr($data, 0, $step));
1135: $data = substr($data, $step);
1136: $pos += $step;
1137: $len -= $step;
1138: $block++;
1139: $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt);
1140: }
1141: $recordData .= $this->_rc4Key->RC4(substr($data, 0, $len));
1142:
1143:
1144:
1145: $this->_rc4Pos = $pos + $len;
1146:
1147: } elseif ($this->_encryption == self::MS_BIFF_CRYPTO_XOR) {
1148: throw new PHPExcel_Reader_Exception('XOr encryption not supported');
1149: }
1150: return $recordData;
1151: }
1152:
1153: 1154: 1155: 1156: 1157:
1158: private function _loadOLE($pFilename)
1159: {
1160:
1161: $ole = new PHPExcel_Shared_OLERead();
1162:
1163:
1164: $res = $ole->read($pFilename);
1165:
1166: $this->_data = $ole->getStream($ole->wrkbook);
1167:
1168:
1169: $this->_summaryInformation = $ole->getStream($ole->summaryInformation);
1170:
1171:
1172: $this->_documentSummaryInformation = $ole->getStream($ole->documentSummaryInformation);
1173:
1174:
1175:
1176: }
1177:
1178:
1179: 1180: 1181:
1182: private function _readSummaryInformation()
1183: {
1184: if (!isset($this->_summaryInformation)) {
1185: return;
1186: }
1187:
1188:
1189:
1190:
1191:
1192:
1193:
1194: $secCount = self::_GetInt4d($this->_summaryInformation, 24);
1195:
1196:
1197:
1198: $secOffset = self::_GetInt4d($this->_summaryInformation, 44);
1199:
1200:
1201:
1202: $secLength = self::_GetInt4d($this->_summaryInformation, $secOffset);
1203:
1204:
1205: $countProperties = self::_GetInt4d($this->_summaryInformation, $secOffset+4);
1206:
1207:
1208: $codePage = 'CP1252';
1209:
1210:
1211:
1212: for ($i = 0; $i < $countProperties; ++$i) {
1213:
1214:
1215: $id = self::_GetInt4d($this->_summaryInformation, ($secOffset+8) + (8 * $i));
1216:
1217:
1218:
1219: $offset = self::_GetInt4d($this->_summaryInformation, ($secOffset+12) + (8 * $i));
1220:
1221: $type = self::_GetInt4d($this->_summaryInformation, $secOffset + $offset);
1222:
1223:
1224: $value = null;
1225:
1226:
1227: switch ($type) {
1228: case 0x02:
1229: $value = self::_GetInt2d($this->_summaryInformation, $secOffset + 4 + $offset);
1230: break;
1231:
1232: case 0x03:
1233: $value = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset);
1234: break;
1235:
1236: case 0x13:
1237:
1238: break;
1239:
1240: case 0x1E:
1241: $byteLength = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset);
1242: $value = substr($this->_summaryInformation, $secOffset + 8 + $offset, $byteLength);
1243: $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage);
1244: $value = rtrim($value);
1245: break;
1246:
1247: case 0x40:
1248:
1249: $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_summaryInformation, $secOffset + 4 + $offset, 8));
1250: break;
1251:
1252: case 0x47:
1253:
1254: break;
1255: }
1256:
1257: switch ($id) {
1258: case 0x01:
1259: $codePage = PHPExcel_Shared_CodePage::NumberToName($value);
1260: break;
1261:
1262: case 0x02:
1263: $this->_phpExcel->getProperties()->setTitle($value);
1264: break;
1265:
1266: case 0x03:
1267: $this->_phpExcel->getProperties()->setSubject($value);
1268: break;
1269:
1270: case 0x04:
1271: $this->_phpExcel->getProperties()->setCreator($value);
1272: break;
1273:
1274: case 0x05:
1275: $this->_phpExcel->getProperties()->setKeywords($value);
1276: break;
1277:
1278: case 0x06:
1279: $this->_phpExcel->getProperties()->setDescription($value);
1280: break;
1281:
1282: case 0x07:
1283:
1284: break;
1285:
1286: case 0x08:
1287: $this->_phpExcel->getProperties()->setLastModifiedBy($value);
1288: break;
1289:
1290: case 0x09:
1291:
1292: break;
1293:
1294: case 0x0A:
1295:
1296: break;
1297:
1298: case 0x0B:
1299:
1300: break;
1301:
1302: case 0x0C:
1303: $this->_phpExcel->getProperties()->setCreated($value);
1304: break;
1305:
1306: case 0x0D:
1307: $this->_phpExcel->getProperties()->setModified($value);
1308: break;
1309:
1310: case 0x0E:
1311:
1312: break;
1313:
1314: case 0x0F:
1315:
1316: break;
1317:
1318: case 0x10:
1319:
1320: break;
1321:
1322: case 0x11:
1323:
1324: break;
1325:
1326: case 0x12:
1327:
1328: break;
1329:
1330: case 0x13:
1331:
1332: break;
1333:
1334: }
1335: }
1336: }
1337:
1338:
1339: 1340: 1341:
1342: private function _readDocumentSummaryInformation()
1343: {
1344: if (!isset($this->_documentSummaryInformation)) {
1345: return;
1346: }
1347:
1348:
1349:
1350:
1351:
1352:
1353:
1354: $secCount = self::_GetInt4d($this->_documentSummaryInformation, 24);
1355:
1356:
1357:
1358:
1359: $secOffset = self::_GetInt4d($this->_documentSummaryInformation, 44);
1360:
1361:
1362:
1363:
1364: $secLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset);
1365:
1366:
1367:
1368: $countProperties = self::_GetInt4d($this->_documentSummaryInformation, $secOffset+4);
1369:
1370:
1371:
1372: $codePage = 'CP1252';
1373:
1374:
1375:
1376: for ($i = 0; $i < $countProperties; ++$i) {
1377:
1378:
1379: $id = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+8) + (8 * $i));
1380:
1381:
1382:
1383:
1384: $offset = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+12) + (8 * $i));
1385:
1386: $type = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + $offset);
1387:
1388:
1389:
1390: $value = null;
1391:
1392:
1393: switch ($type) {
1394: case 0x02:
1395: $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset);
1396: break;
1397:
1398: case 0x03:
1399: $value = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset);
1400: break;
1401:
1402: case 0x0B:
1403: $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset);
1404: $value = ($value == 0 ? false : true);
1405: break;
1406:
1407: case 0x13:
1408:
1409: break;
1410:
1411: case 0x1E:
1412: $byteLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset);
1413: $value = substr($this->_documentSummaryInformation, $secOffset + 8 + $offset, $byteLength);
1414: $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage);
1415: $value = rtrim($value);
1416: break;
1417:
1418: case 0x40:
1419:
1420: $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_documentSummaryInformation, $secOffset + 4 + $offset, 8));
1421: break;
1422:
1423: case 0x47:
1424:
1425: break;
1426: }
1427:
1428: switch ($id) {
1429: case 0x01:
1430: $codePage = PHPExcel_Shared_CodePage::NumberToName($value);
1431: break;
1432:
1433: case 0x02:
1434: $this->_phpExcel->getProperties()->setCategory($value);
1435: break;
1436:
1437: case 0x03:
1438:
1439: break;
1440:
1441: case 0x04:
1442:
1443: break;
1444:
1445: case 0x05:
1446:
1447: break;
1448:
1449: case 0x06:
1450:
1451: break;
1452:
1453: case 0x07:
1454:
1455: break;
1456:
1457: case 0x08:
1458:
1459: break;
1460:
1461: case 0x09:
1462:
1463: break;
1464:
1465: case 0x0A:
1466:
1467: break;
1468:
1469: case 0x0B:
1470:
1471: break;
1472:
1473: case 0x0C:
1474:
1475: break;
1476:
1477: case 0x0D:
1478:
1479: break;
1480:
1481: case 0x0E:
1482: $this->_phpExcel->getProperties()->setManager($value);
1483: break;
1484:
1485: case 0x0F:
1486: $this->_phpExcel->getProperties()->setCompany($value);
1487: break;
1488:
1489: case 0x10:
1490:
1491: break;
1492:
1493: }
1494: }
1495: }
1496:
1497:
1498: 1499: 1500:
1501: private function _readDefault()
1502: {
1503: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
1504:
1505:
1506:
1507: $this->_pos += 4 + $length;
1508: }
1509:
1510:
1511: 1512: 1513: 1514:
1515: private function _readNote()
1516: {
1517:
1518: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
1519: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
1520:
1521:
1522: $this->_pos += 4 + $length;
1523:
1524: if ($this->_readDataOnly) {
1525: return;
1526: }
1527:
1528: $cellAddress = $this->_readBIFF8CellAddress(substr($recordData, 0, 4));
1529: if ($this->_version == self::XLS_BIFF8) {
1530: $noteObjID = self::_GetInt2d($recordData, 6);
1531: $noteAuthor = self::_readUnicodeStringLong(substr($recordData, 8));
1532: $noteAuthor = $noteAuthor['value'];
1533:
1534:
1535:
1536:
1537: $this->_cellNotes[$noteObjID] = array('cellRef' => $cellAddress,
1538: 'objectID' => $noteObjID,
1539: 'author' => $noteAuthor
1540: );
1541: } else {
1542: $extension = false;
1543: if ($cellAddress == '$B$65536') {
1544:
1545:
1546:
1547: $row = self::_GetInt2d($recordData, 0);
1548: $extension = true;
1549: $cellAddress = array_pop(array_keys($this->_phpSheet->getComments()));
1550: }
1551:
1552:
1553: $cellAddress = str_replace('$','',$cellAddress);
1554: $noteLength = self::_GetInt2d($recordData, 4);
1555: $noteText = trim(substr($recordData, 6));
1556:
1557:
1558:
1559: if ($extension) {
1560:
1561: $comment = $this->_phpSheet->getComment( $cellAddress );
1562: $commentText = $comment->getText()->getPlainText();
1563: $comment->setText($this->_parseRichText($commentText.$noteText) );
1564: } else {
1565:
1566: $this->_phpSheet->getComment( $cellAddress )
1567:
1568: ->setText($this->_parseRichText($noteText) );
1569: }
1570: }
1571:
1572: }
1573:
1574:
1575: 1576: 1577:
1578: private function _readTextObject()
1579: {
1580: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
1581: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
1582:
1583:
1584: $this->_pos += 4 + $length;
1585:
1586: if ($this->_readDataOnly) {
1587: return;
1588: }
1589:
1590:
1591:
1592:
1593:
1594:
1595:
1596: $grbitOpts = self::_GetInt2d($recordData, 0);
1597: $rot = self::_GetInt2d($recordData, 2);
1598: $cchText = self::_GetInt2d($recordData, 10);
1599: $cbRuns = self::_GetInt2d($recordData, 12);
1600: $text = $this->_getSplicedRecordData();
1601:
1602: $this->_textObjects[$this->textObjRef] = array(
1603: 'text' => substr($text["recordData"],$text["spliceOffsets"][0]+1,$cchText),
1604: 'format' => substr($text["recordData"],$text["spliceOffsets"][1],$cbRuns),
1605: 'alignment' => $grbitOpts,
1606: 'rotation' => $rot
1607: );
1608:
1609:
1610:
1611:
1612: }
1613:
1614:
1615: 1616: 1617:
1618: private function _readBof()
1619: {
1620: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
1621: $recordData = substr($this->_data, $this->_pos + 4, $length);
1622:
1623:
1624: $this->_pos += 4 + $length;
1625:
1626:
1627: $substreamType = self::_GetInt2d($recordData, 2);
1628:
1629: switch ($substreamType) {
1630: case self::XLS_WorkbookGlobals:
1631: $version = self::_GetInt2d($recordData, 0);
1632: if (($version != self::XLS_BIFF8) && ($version != self::XLS_BIFF7)) {
1633: throw new PHPExcel_Reader_Exception('Cannot read this Excel file. Version is too old.');
1634: }
1635: $this->_version = $version;
1636: break;
1637:
1638: case self::XLS_Worksheet:
1639:
1640:
1641: break;
1642:
1643: default:
1644:
1645:
1646: do {
1647: $code = self::_GetInt2d($this->_data, $this->_pos);
1648: $this->_readDefault();
1649: } while ($code != self::XLS_Type_EOF && $this->_pos < $this->_dataSize);
1650: break;
1651: }
1652: }
1653:
1654:
1655: 1656: 1657: 1658: 1659: 1660: 1661: 1662: 1663: 1664: 1665: 1666: 1667: 1668: 1669:
1670: private function _readFilepass()
1671: {
1672: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
1673:
1674: if ($length != 54) {
1675: throw new PHPExcel_Reader_Exception('Unexpected file pass record length');
1676: }
1677:
1678: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
1679:
1680:
1681: $this->_pos += 4 + $length;
1682:
1683: if (!$this->_verifyPassword(
1684: 'VelvetSweatshop',
1685: substr($recordData, 6, 16),
1686: substr($recordData, 22, 16),
1687: substr($recordData, 38, 16),
1688: $this->_md5Ctxt
1689: )) {
1690: throw new PHPExcel_Reader_Exception('Decryption password incorrect');
1691: }
1692:
1693: $this->_encryption = self::MS_BIFF_CRYPTO_RC4;
1694:
1695:
1696: $this->_encryptionStartPos = $this->_pos + self::_GetInt2d($this->_data, $this->_pos + 2);
1697: }
1698:
1699: 1700: 1701: 1702: 1703: 1704: 1705: 1706:
1707: private function _makeKey($block, $valContext)
1708: {
1709: $pwarray = str_repeat("\0", 64);
1710:
1711: for ($i = 0; $i < 5; $i++) {
1712: $pwarray[$i] = $valContext[$i];
1713: }
1714:
1715: $pwarray[5] = chr($block & 0xff);
1716: $pwarray[6] = chr(($block >> 8) & 0xff);
1717: $pwarray[7] = chr(($block >> 16) & 0xff);
1718: $pwarray[8] = chr(($block >> 24) & 0xff);
1719:
1720: $pwarray[9] = "\x80";
1721: $pwarray[56] = "\x48";
1722:
1723: $md5 = new PHPExcel_Reader_Excel5_MD5();
1724: $md5->add($pwarray);
1725:
1726: $s = $md5->getContext();
1727: return new PHPExcel_Reader_Excel5_RC4($s);
1728: }
1729:
1730: 1731: 1732: 1733: 1734: 1735: 1736: 1737: 1738: 1739: 1740:
1741: private function _verifyPassword($password, $docid, $salt_data, $hashedsalt_data, &$valContext)
1742: {
1743: $pwarray = str_repeat("\0", 64);
1744:
1745: for ($i = 0; $i < strlen($password); $i++) {
1746: $o = ord(substr($password, $i, 1));
1747: $pwarray[2 * $i] = chr($o & 0xff);
1748: $pwarray[2 * $i + 1] = chr(($o >> 8) & 0xff);
1749: }
1750: $pwarray[2 * $i] = chr(0x80);
1751: $pwarray[56] = chr(($i << 4) & 0xff);
1752:
1753: $md5 = new PHPExcel_Reader_Excel5_MD5();
1754: $md5->add($pwarray);
1755:
1756: $mdContext1 = $md5->getContext();
1757:
1758: $offset = 0;
1759: $keyoffset = 0;
1760: $tocopy = 5;
1761:
1762: $md5->reset();
1763:
1764: while ($offset != 16) {
1765: if ((64 - $offset) < 5) {
1766: $tocopy = 64 - $offset;
1767: }
1768:
1769: for ($i = 0; $i <= $tocopy; $i++) {
1770: $pwarray[$offset + $i] = $mdContext1[$keyoffset + $i];
1771: }
1772:
1773: $offset += $tocopy;
1774:
1775: if ($offset == 64) {
1776: $md5->add($pwarray);
1777: $keyoffset = $tocopy;
1778: $tocopy = 5 - $tocopy;
1779: $offset = 0;
1780: continue;
1781: }
1782:
1783: $keyoffset = 0;
1784: $tocopy = 5;
1785: for ($i = 0; $i < 16; $i++) {
1786: $pwarray[$offset + $i] = $docid[$i];
1787: }
1788: $offset += 16;
1789: }
1790:
1791: $pwarray[16] = "\x80";
1792: for ($i = 0; $i < 47; $i++) {
1793: $pwarray[17 + $i] = "\0";
1794: }
1795: $pwarray[56] = "\x80";
1796: $pwarray[57] = "\x0a";
1797:
1798: $md5->add($pwarray);
1799: $valContext = $md5->getContext();
1800:
1801: $key = $this->_makeKey(0, $valContext);
1802:
1803: $salt = $key->RC4($salt_data);
1804: $hashedsalt = $key->RC4($hashedsalt_data);
1805:
1806: $salt .= "\x80" . str_repeat("\0", 47);
1807: $salt[56] = "\x80";
1808:
1809: $md5->reset();
1810: $md5->add($salt);
1811: $mdContext2 = $md5->getContext();
1812:
1813: return $mdContext2 == $hashedsalt;
1814: }
1815:
1816: 1817: 1818: 1819: 1820: 1821: 1822: 1823: 1824:
1825: private function _readCodepage()
1826: {
1827: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
1828: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
1829:
1830:
1831: $this->_pos += 4 + $length;
1832:
1833:
1834: $codepage = self::_GetInt2d($recordData, 0);
1835:
1836: $this->_codepage = PHPExcel_Shared_CodePage::NumberToName($codepage);
1837: }
1838:
1839:
1840: 1841: 1842: 1843: 1844: 1845: 1846: 1847: 1848: 1849: 1850: 1851:
1852: private function _readDateMode()
1853: {
1854: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
1855: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
1856:
1857:
1858: $this->_pos += 4 + $length;
1859:
1860:
1861: PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900);
1862: if (ord($recordData{0}) == 1) {
1863: PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904);
1864: }
1865: }
1866:
1867:
1868: 1869: 1870:
1871: private function _readFont()
1872: {
1873: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
1874: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
1875:
1876:
1877: $this->_pos += 4 + $length;
1878:
1879: if (!$this->_readDataOnly) {
1880: $objFont = new PHPExcel_Style_Font();
1881:
1882:
1883: $size = self::_GetInt2d($recordData, 0);
1884: $objFont->setSize($size / 20);
1885:
1886:
1887:
1888:
1889: $isItalic = (0x0002 & self::_GetInt2d($recordData, 2)) >> 1;
1890: if ($isItalic) $objFont->setItalic(true);
1891:
1892:
1893:
1894: $isStrike = (0x0008 & self::_GetInt2d($recordData, 2)) >> 3;
1895: if ($isStrike) $objFont->setStrikethrough(true);
1896:
1897:
1898: $colorIndex = self::_GetInt2d($recordData, 4);
1899: $objFont->colorIndex = $colorIndex;
1900:
1901:
1902: $weight = self::_GetInt2d($recordData, 6);
1903: switch ($weight) {
1904: case 0x02BC:
1905: $objFont->setBold(true);
1906: break;
1907: }
1908:
1909:
1910: $escapement = self::_GetInt2d($recordData, 8);
1911: switch ($escapement) {
1912: case 0x0001:
1913: $objFont->setSuperScript(true);
1914: break;
1915: case 0x0002:
1916: $objFont->setSubScript(true);
1917: break;
1918: }
1919:
1920:
1921: $underlineType = ord($recordData{10});
1922: switch ($underlineType) {
1923: case 0x00:
1924: break;
1925: case 0x01:
1926: $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);
1927: break;
1928: case 0x02:
1929: $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLE);
1930: break;
1931: case 0x21:
1932: $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING);
1933: break;
1934: case 0x22:
1935: $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING);
1936: break;
1937: }
1938:
1939:
1940:
1941:
1942:
1943: if ($this->_version == self::XLS_BIFF8) {
1944: $string = self::_readUnicodeStringShort(substr($recordData, 14));
1945: } else {
1946: $string = $this->_readByteStringShort(substr($recordData, 14));
1947: }
1948: $objFont->setName($string['value']);
1949:
1950: $this->_objFonts[] = $objFont;
1951: }
1952: }
1953:
1954:
1955: 1956: 1957: 1958: 1959: 1960: 1961: 1962: 1963: 1964: 1965: 1966: 1967: 1968:
1969: private function _readFormat()
1970: {
1971: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
1972: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
1973:
1974:
1975: $this->_pos += 4 + $length;
1976:
1977: if (!$this->_readDataOnly) {
1978: $indexCode = self::_GetInt2d($recordData, 0);
1979:
1980: if ($this->_version == self::XLS_BIFF8) {
1981: $string = self::_readUnicodeStringLong(substr($recordData, 2));
1982: } else {
1983:
1984: $string = $this->_readByteStringShort(substr($recordData, 2));
1985: }
1986:
1987: $formatString = $string['value'];
1988: $this->_formats[$indexCode] = $formatString;
1989: }
1990: }
1991:
1992:
1993: 1994: 1995: 1996: 1997: 1998: 1999: 2000: 2001: 2002: 2003: 2004: 2005: 2006:
2007: private function _readXf()
2008: {
2009: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
2010: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
2011:
2012:
2013: $this->_pos += 4 + $length;
2014:
2015: $objStyle = new PHPExcel_Style();
2016:
2017: if (!$this->_readDataOnly) {
2018:
2019: if (self::_GetInt2d($recordData, 0) < 4) {
2020: $fontIndex = self::_GetInt2d($recordData, 0);
2021: } else {
2022:
2023:
2024: $fontIndex = self::_GetInt2d($recordData, 0) - 1;
2025: }
2026: $objStyle->setFont($this->_objFonts[$fontIndex]);
2027:
2028:
2029: $numberFormatIndex = self::_GetInt2d($recordData, 2);
2030: if (isset($this->_formats[$numberFormatIndex])) {
2031:
2032: $numberformat = array('code' => $this->_formats[$numberFormatIndex]);
2033: } elseif (($code = PHPExcel_Style_NumberFormat::builtInFormatCode($numberFormatIndex)) !== '') {
2034:
2035: $numberformat = array('code' => $code);
2036: } else {
2037:
2038: $numberformat = array('code' => 'General');
2039: }
2040: $objStyle->getNumberFormat()->setFormatCode($numberformat['code']);
2041:
2042:
2043:
2044: $xfTypeProt = self::_GetInt2d($recordData, 4);
2045:
2046: $isLocked = (0x01 & $xfTypeProt) >> 0;
2047: $objStyle->getProtection()->setLocked($isLocked ?
2048: PHPExcel_Style_Protection::PROTECTION_INHERIT : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED);
2049:
2050:
2051: $isHidden = (0x02 & $xfTypeProt) >> 1;
2052: $objStyle->getProtection()->setHidden($isHidden ?
2053: PHPExcel_Style_Protection::PROTECTION_PROTECTED : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED);
2054:
2055:
2056: $isCellStyleXf = (0x04 & $xfTypeProt) >> 2;
2057:
2058:
2059:
2060: $horAlign = (0x07 & ord($recordData{6})) >> 0;
2061: switch ($horAlign) {
2062: case 0:
2063: $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_GENERAL);
2064: break;
2065: case 1:
2066: $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
2067: break;
2068: case 2:
2069: $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
2070: break;
2071: case 3:
2072: $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
2073: break;
2074: case 4:
2075: $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_FILL);
2076: break;
2077: case 5:
2078: $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY);
2079: break;
2080: case 6:
2081: $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS);
2082: break;
2083: }
2084:
2085: $wrapText = (0x08 & ord($recordData{6})) >> 3;
2086: switch ($wrapText) {
2087: case 0:
2088: $objStyle->getAlignment()->setWrapText(false);
2089: break;
2090: case 1:
2091: $objStyle->getAlignment()->setWrapText(true);
2092: break;
2093: }
2094:
2095: $vertAlign = (0x70 & ord($recordData{6})) >> 4;
2096: switch ($vertAlign) {
2097: case 0:
2098: $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP);
2099: break;
2100: case 1:
2101: $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);
2102: break;
2103: case 2:
2104: $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_BOTTOM);
2105: break;
2106: case 3:
2107: $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_JUSTIFY);
2108: break;
2109: }
2110:
2111: if ($this->_version == self::XLS_BIFF8) {
2112:
2113: $angle = ord($recordData{7});
2114: $rotation = 0;
2115: if ($angle <= 90) {
2116: $rotation = $angle;
2117: } else if ($angle <= 180) {
2118: $rotation = 90 - $angle;
2119: } else if ($angle == 255) {
2120: $rotation = -165;
2121: }
2122: $objStyle->getAlignment()->setTextRotation($rotation);
2123:
2124:
2125:
2126: $indent = (0x0F & ord($recordData{8})) >> 0;
2127: $objStyle->getAlignment()->setIndent($indent);
2128:
2129:
2130: $shrinkToFit = (0x10 & ord($recordData{8})) >> 4;
2131: switch ($shrinkToFit) {
2132: case 0:
2133: $objStyle->getAlignment()->setShrinkToFit(false);
2134: break;
2135: case 1:
2136: $objStyle->getAlignment()->setShrinkToFit(true);
2137: break;
2138: }
2139:
2140:
2141:
2142:
2143:
2144: if ($bordersLeftStyle = self::_mapBorderStyle((0x0000000F & self::_GetInt4d($recordData, 10)) >> 0)) {
2145: $objStyle->getBorders()->getLeft()->setBorderStyle($bordersLeftStyle);
2146: }
2147:
2148: if ($bordersRightStyle = self::_mapBorderStyle((0x000000F0 & self::_GetInt4d($recordData, 10)) >> 4)) {
2149: $objStyle->getBorders()->getRight()->setBorderStyle($bordersRightStyle);
2150: }
2151:
2152: if ($bordersTopStyle = self::_mapBorderStyle((0x00000F00 & self::_GetInt4d($recordData, 10)) >> 8)) {
2153: $objStyle->getBorders()->getTop()->setBorderStyle($bordersTopStyle);
2154: }
2155:
2156: if ($bordersBottomStyle = self::_mapBorderStyle((0x0000F000 & self::_GetInt4d($recordData, 10)) >> 12)) {
2157: $objStyle->getBorders()->getBottom()->setBorderStyle($bordersBottomStyle);
2158: }
2159:
2160: $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & self::_GetInt4d($recordData, 10)) >> 16;
2161:
2162:
2163: $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & self::_GetInt4d($recordData, 10)) >> 23;
2164:
2165:
2166: $diagonalDown = (0x40000000 & self::_GetInt4d($recordData, 10)) >> 30 ?
2167: true : false;
2168:
2169:
2170: $diagonalUp = (0x80000000 & self::_GetInt4d($recordData, 10)) >> 31 ?
2171: true : false;
2172:
2173: if ($diagonalUp == false && $diagonalDown == false) {
2174: $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE);
2175: } elseif ($diagonalUp == true && $diagonalDown == false) {
2176: $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP);
2177: } elseif ($diagonalUp == false && $diagonalDown == true) {
2178: $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN);
2179: } elseif ($diagonalUp == true && $diagonalDown == true) {
2180: $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH);
2181: }
2182:
2183:
2184:
2185: $objStyle->getBorders()->getTop()->colorIndex = (0x0000007F & self::_GetInt4d($recordData, 14)) >> 0;
2186:
2187:
2188: $objStyle->getBorders()->getBottom()->colorIndex = (0x00003F80 & self::_GetInt4d($recordData, 14)) >> 7;
2189:
2190:
2191: $objStyle->getBorders()->getDiagonal()->colorIndex = (0x001FC000 & self::_GetInt4d($recordData, 14)) >> 14;
2192:
2193:
2194: if ($bordersDiagonalStyle = self::_mapBorderStyle((0x01E00000 & self::_GetInt4d($recordData, 14)) >> 21)) {
2195: $objStyle->getBorders()->getDiagonal()->setBorderStyle($bordersDiagonalStyle);
2196: }
2197:
2198:
2199: if ($fillType = self::_mapFillPattern((0xFC000000 & self::_GetInt4d($recordData, 14)) >> 26)) {
2200: $objStyle->getFill()->setFillType($fillType);
2201: }
2202:
2203:
2204: $objStyle->getFill()->startcolorIndex = (0x007F & self::_GetInt2d($recordData, 18)) >> 0;
2205:
2206:
2207: $objStyle->getFill()->endcolorIndex = (0x3F80 & self::_GetInt2d($recordData, 18)) >> 7;
2208: } else {
2209:
2210:
2211:
2212: $orientationAndFlags = ord($recordData{7});
2213:
2214:
2215: $xfOrientation = (0x03 & $orientationAndFlags) >> 0;
2216: switch ($xfOrientation) {
2217: case 0:
2218: $objStyle->getAlignment()->setTextRotation(0);
2219: break;
2220: case 1:
2221: $objStyle->getAlignment()->setTextRotation(-165);
2222: break;
2223: case 2:
2224: $objStyle->getAlignment()->setTextRotation(90);
2225: break;
2226: case 3:
2227: $objStyle->getAlignment()->setTextRotation(-90);
2228: break;
2229: }
2230:
2231:
2232: $borderAndBackground = self::_GetInt4d($recordData, 8);
2233:
2234:
2235: $objStyle->getFill()->startcolorIndex = (0x0000007F & $borderAndBackground) >> 0;
2236:
2237:
2238: $objStyle->getFill()->endcolorIndex = (0x00003F80 & $borderAndBackground) >> 7;
2239:
2240:
2241: $objStyle->getFill()->setFillType(self::_mapFillPattern((0x003F0000 & $borderAndBackground) >> 16));
2242:
2243:
2244: $objStyle->getBorders()->getBottom()->setBorderStyle(self::_mapBorderStyle((0x01C00000 & $borderAndBackground) >> 22));
2245:
2246:
2247: $objStyle->getBorders()->getBottom()->colorIndex = (0xFE000000 & $borderAndBackground) >> 25;
2248:
2249:
2250: $borderLines = self::_GetInt4d($recordData, 12);
2251:
2252:
2253: $objStyle->getBorders()->getTop()->setBorderStyle(self::_mapBorderStyle((0x00000007 & $borderLines) >> 0));
2254:
2255:
2256: $objStyle->getBorders()->getLeft()->setBorderStyle(self::_mapBorderStyle((0x00000038 & $borderLines) >> 3));
2257:
2258:
2259: $objStyle->getBorders()->getRight()->setBorderStyle(self::_mapBorderStyle((0x000001C0 & $borderLines) >> 6));
2260:
2261:
2262: $objStyle->getBorders()->getTop()->colorIndex = (0x0000FE00 & $borderLines) >> 9;
2263:
2264:
2265: $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & $borderLines) >> 16;
2266:
2267:
2268: $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & $borderLines) >> 23;
2269: }
2270:
2271:
2272: if ($isCellStyleXf) {
2273:
2274: if ($this->_xfIndex == 0) {
2275: $this->_phpExcel->addCellStyleXf($objStyle);
2276: $this->_mapCellStyleXfIndex[$this->_xfIndex] = 0;
2277: }
2278: } else {
2279:
2280: $this->_phpExcel->addCellXf($objStyle);
2281: $this->_mapCellXfIndex[$this->_xfIndex] = count($this->_phpExcel->getCellXfCollection()) - 1;
2282: }
2283:
2284:
2285: ++$this->_xfIndex;
2286: }
2287: }
2288:
2289:
2290: 2291: 2292:
2293: private function _readXfExt()
2294: {
2295: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
2296: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
2297:
2298:
2299: $this->_pos += 4 + $length;
2300:
2301: if (!$this->_readDataOnly) {
2302:
2303:
2304:
2305:
2306:
2307:
2308:
2309:
2310:
2311: $ixfe = self::_GetInt2d($recordData, 14);
2312:
2313:
2314:
2315:
2316: $cexts = self::_GetInt2d($recordData, 18);
2317:
2318:
2319: $offset = 20;
2320: while ($offset < $length) {
2321:
2322: $extType = self::_GetInt2d($recordData, $offset);
2323:
2324:
2325: $cb = self::_GetInt2d($recordData, $offset + 2);
2326:
2327:
2328: $extData = substr($recordData, $offset + 4, $cb);
2329:
2330: switch ($extType) {
2331: case 4:
2332: $xclfType = self::_GetInt2d($extData, 0);
2333: $xclrValue = substr($extData, 4, 4);
2334:
2335: if ($xclfType == 2) {
2336: $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));
2337:
2338:
2339: if ( isset($this->_mapCellXfIndex[$ixfe]) ) {
2340: $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill();
2341: $fill->getStartColor()->setRGB($rgb);
2342: unset($fill->startcolorIndex);
2343: }
2344: }
2345: break;
2346:
2347: case 5:
2348: $xclfType = self::_GetInt2d($extData, 0);
2349: $xclrValue = substr($extData, 4, 4);
2350:
2351: if ($xclfType == 2) {
2352: $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));
2353:
2354:
2355: if ( isset($this->_mapCellXfIndex[$ixfe]) ) {
2356: $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill();
2357: $fill->getEndColor()->setRGB($rgb);
2358: unset($fill->endcolorIndex);
2359: }
2360: }
2361: break;
2362:
2363: case 7:
2364: $xclfType = self::_GetInt2d($extData, 0);
2365: $xclrValue = substr($extData, 4, 4);
2366:
2367: if ($xclfType == 2) {
2368: $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));
2369:
2370:
2371: if ( isset($this->_mapCellXfIndex[$ixfe]) ) {
2372: $top = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getTop();
2373: $top->getColor()->setRGB($rgb);
2374: unset($top->colorIndex);
2375: }
2376: }
2377: break;
2378:
2379: case 8:
2380: $xclfType = self::_GetInt2d($extData, 0);
2381: $xclrValue = substr($extData, 4, 4);
2382:
2383: if ($xclfType == 2) {
2384: $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));
2385:
2386:
2387: if ( isset($this->_mapCellXfIndex[$ixfe]) ) {
2388: $bottom = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getBottom();
2389: $bottom->getColor()->setRGB($rgb);
2390: unset($bottom->colorIndex);
2391: }
2392: }
2393: break;
2394:
2395: case 9:
2396: $xclfType = self::_GetInt2d($extData, 0);
2397: $xclrValue = substr($extData, 4, 4);
2398:
2399: if ($xclfType == 2) {
2400: $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));
2401:
2402:
2403: if ( isset($this->_mapCellXfIndex[$ixfe]) ) {
2404: $left = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getLeft();
2405: $left->getColor()->setRGB($rgb);
2406: unset($left->colorIndex);
2407: }
2408: }
2409: break;
2410:
2411: case 10:
2412: $xclfType = self::_GetInt2d($extData, 0);
2413: $xclrValue = substr($extData, 4, 4);
2414:
2415: if ($xclfType == 2) {
2416: $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));
2417:
2418:
2419: if ( isset($this->_mapCellXfIndex[$ixfe]) ) {
2420: $right = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getRight();
2421: $right->getColor()->setRGB($rgb);
2422: unset($right->colorIndex);
2423: }
2424: }
2425: break;
2426:
2427: case 11:
2428: $xclfType = self::_GetInt2d($extData, 0);
2429: $xclrValue = substr($extData, 4, 4);
2430:
2431: if ($xclfType == 2) {
2432: $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));
2433:
2434:
2435: if ( isset($this->_mapCellXfIndex[$ixfe]) ) {
2436: $diagonal = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getDiagonal();
2437: $diagonal->getColor()->setRGB($rgb);
2438: unset($diagonal->colorIndex);
2439: }
2440: }
2441: break;
2442:
2443: case 13:
2444: $xclfType = self::_GetInt2d($extData, 0);
2445: $xclrValue = substr($extData, 4, 4);
2446:
2447: if ($xclfType == 2) {
2448: $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));
2449:
2450:
2451: if ( isset($this->_mapCellXfIndex[$ixfe]) ) {
2452: $font = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFont();
2453: $font->getColor()->setRGB($rgb);
2454: unset($font->colorIndex);
2455: }
2456: }
2457: break;
2458: }
2459:
2460: $offset += $cb;
2461: }
2462: }
2463:
2464: }
2465:
2466:
2467: 2468: 2469:
2470: private function _readStyle()
2471: {
2472: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
2473: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
2474:
2475:
2476: $this->_pos += 4 + $length;
2477:
2478: if (!$this->_readDataOnly) {
2479:
2480: $ixfe = self::_GetInt2d($recordData, 0);
2481:
2482:
2483: $xfIndex = (0x0FFF & $ixfe) >> 0;
2484:
2485:
2486: $isBuiltIn = (bool) ((0x8000 & $ixfe) >> 15);
2487:
2488: if ($isBuiltIn) {
2489:
2490: $builtInId = ord($recordData{2});
2491:
2492: switch ($builtInId) {
2493: case 0x00:
2494:
2495: break;
2496:
2497: default:
2498: break;
2499: }
2500:
2501: } else {
2502:
2503: }
2504: }
2505: }
2506:
2507:
2508: 2509: 2510:
2511: private function _readPalette()
2512: {
2513: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
2514: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
2515:
2516:
2517: $this->_pos += 4 + $length;
2518:
2519: if (!$this->_readDataOnly) {
2520:
2521: $nm = self::_GetInt2d($recordData, 0);
2522:
2523:
2524: for ($i = 0; $i < $nm; ++$i) {
2525: $rgb = substr($recordData, 2 + 4 * $i, 4);
2526: $this->_palette[] = self::_readRGB($rgb);
2527: }
2528: }
2529: }
2530:
2531:
2532: 2533: 2534: 2535: 2536: 2537: 2538: 2539: 2540: 2541: 2542: 2543:
2544: private function _readSheet()
2545: {
2546: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
2547: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
2548:
2549:
2550:
2551: $rec_offset = self::_GetInt4d($this->_data, $this->_pos + 4);
2552:
2553:
2554: $this->_pos += 4 + $length;
2555:
2556:
2557: switch (ord($recordData{4})) {
2558: case 0x00: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; break;
2559: case 0x01: $sheetState = PHPExcel_Worksheet::SHEETSTATE_HIDDEN; break;
2560: case 0x02: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN; break;
2561: default: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; break;
2562: }
2563:
2564:
2565: $sheetType = ord($recordData{5});
2566:
2567:
2568: if ($this->_version == self::XLS_BIFF8) {
2569: $string = self::_readUnicodeStringShort(substr($recordData, 6));
2570: $rec_name = $string['value'];
2571: } elseif ($this->_version == self::XLS_BIFF7) {
2572: $string = $this->_readByteStringShort(substr($recordData, 6));
2573: $rec_name = $string['value'];
2574: }
2575:
2576: $this->_sheets[] = array(
2577: 'name' => $rec_name,
2578: 'offset' => $rec_offset,
2579: 'sheetState' => $sheetState,
2580: 'sheetType' => $sheetType,
2581: );
2582: }
2583:
2584:
2585: 2586: 2587:
2588: private function _readExternalBook()
2589: {
2590: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
2591: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
2592:
2593:
2594: $this->_pos += 4 + $length;
2595:
2596:
2597: $offset = 0;
2598:
2599:
2600: if (strlen($recordData) > 4) {
2601:
2602:
2603: $nm = self::_GetInt2d($recordData, 0);
2604: $offset += 2;
2605:
2606:
2607: $encodedUrlString = self::_readUnicodeStringLong(substr($recordData, 2));
2608: $offset += $encodedUrlString['size'];
2609:
2610:
2611: $externalSheetNames = array();
2612: for ($i = 0; $i < $nm; ++$i) {
2613: $externalSheetNameString = self::_readUnicodeStringLong(substr($recordData, $offset));
2614: $externalSheetNames[] = $externalSheetNameString['value'];
2615: $offset += $externalSheetNameString['size'];
2616: }
2617:
2618:
2619: $this->_externalBooks[] = array(
2620: 'type' => 'external',
2621: 'encodedUrl' => $encodedUrlString['value'],
2622: 'externalSheetNames' => $externalSheetNames,
2623: );
2624:
2625: } elseif (substr($recordData, 2, 2) == pack('CC', 0x01, 0x04)) {
2626:
2627:
2628:
2629: $this->_externalBooks[] = array(
2630: 'type' => 'internal',
2631: );
2632: } elseif (substr($recordData, 0, 4) == pack('vCC', 0x0001, 0x01, 0x3A)) {
2633:
2634:
2635: $this->_externalBooks[] = array(
2636: 'type' => 'addInFunction',
2637: );
2638: } elseif (substr($recordData, 0, 2) == pack('v', 0x0000)) {
2639:
2640:
2641:
2642: $this->_externalBooks[] = array(
2643: 'type' => 'DDEorOLE',
2644: );
2645: }
2646: }
2647:
2648:
2649: 2650: 2651:
2652: private function _readExternName()
2653: {
2654: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
2655: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
2656:
2657:
2658: $this->_pos += 4 + $length;
2659:
2660:
2661: if ($this->_version == self::XLS_BIFF8) {
2662:
2663: $options = self::_GetInt2d($recordData, 0);
2664:
2665:
2666:
2667:
2668:
2669:
2670: $nameString = self::_readUnicodeStringShort(substr($recordData, 6));
2671:
2672:
2673: $offset = 6 + $nameString['size'];
2674: $formula = $this->_getFormulaFromStructure(substr($recordData, $offset));
2675:
2676: $this->_externalNames[] = array(
2677: 'name' => $nameString['value'],
2678: 'formula' => $formula,
2679: );
2680: }
2681: }
2682:
2683:
2684: 2685: 2686:
2687: private function _readExternSheet()
2688: {
2689: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
2690: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
2691:
2692:
2693: $this->_pos += 4 + $length;
2694:
2695:
2696: if ($this->_version == self::XLS_BIFF8) {
2697:
2698: $nm = self::_GetInt2d($recordData, 0);
2699: for ($i = 0; $i < $nm; ++$i) {
2700: $this->_ref[] = array(
2701:
2702: 'externalBookIndex' => self::_GetInt2d($recordData, 2 + 6 * $i),
2703:
2704: 'firstSheetIndex' => self::_GetInt2d($recordData, 4 + 6 * $i),
2705:
2706: 'lastSheetIndex' => self::_GetInt2d($recordData, 6 + 6 * $i),
2707: );
2708: }
2709: }
2710: }
2711:
2712:
2713: 2714: 2715: 2716: 2717: 2718: 2719: 2720: 2721: 2722: 2723:
2724: private function _readDefinedName()
2725: {
2726: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
2727: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
2728:
2729:
2730: $this->_pos += 4 + $length;
2731:
2732: if ($this->_version == self::XLS_BIFF8) {
2733:
2734:
2735:
2736: $opts = self::_GetInt2d($recordData, 0);
2737:
2738:
2739: $isBuiltInName = (0x0020 & $opts) >> 5;
2740:
2741:
2742:
2743:
2744: $nlen = ord($recordData{3});
2745:
2746:
2747:
2748: $flen = self::_GetInt2d($recordData, 4);
2749:
2750:
2751: $scope = self::_GetInt2d($recordData, 8);
2752:
2753:
2754: $string = self::_readUnicodeString(substr($recordData, 14), $nlen);
2755:
2756:
2757: $offset = 14 + $string['size'];
2758: $formulaStructure = pack('v', $flen) . substr($recordData, $offset);
2759:
2760: try {
2761: $formula = $this->_getFormulaFromStructure($formulaStructure);
2762: } catch (PHPExcel_Exception $e) {
2763: $formula = '';
2764: }
2765:
2766: $this->_definedname[] = array(
2767: 'isBuiltInName' => $isBuiltInName,
2768: 'name' => $string['value'],
2769: 'formula' => $formula,
2770: 'scope' => $scope,
2771: );
2772: }
2773: }
2774:
2775:
2776: 2777: 2778:
2779: private function _readMsoDrawingGroup()
2780: {
2781: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
2782:
2783:
2784: $splicedRecordData = $this->_getSplicedRecordData();
2785: $recordData = $splicedRecordData['recordData'];
2786:
2787: $this->_drawingGroupData .= $recordData;
2788: }
2789:
2790:
2791: 2792: 2793: 2794: 2795: 2796: 2797: 2798: 2799: 2800: 2801:
2802: private function _readSst()
2803: {
2804:
2805: $pos = 0;
2806:
2807:
2808: $splicedRecordData = $this->_getSplicedRecordData();
2809:
2810: $recordData = $splicedRecordData['recordData'];
2811: $spliceOffsets = $splicedRecordData['spliceOffsets'];
2812:
2813:
2814: $pos += 4;
2815:
2816:
2817: $nm = self::_GetInt4d($recordData, 4);
2818: $pos += 4;
2819:
2820:
2821: for ($i = 0; $i < $nm; ++$i) {
2822:
2823:
2824: $numChars = self::_GetInt2d($recordData, $pos);
2825: $pos += 2;
2826:
2827:
2828: $optionFlags = ord($recordData{$pos});
2829: ++$pos;
2830:
2831:
2832: $isCompressed = (($optionFlags & 0x01) == 0) ;
2833:
2834:
2835: $hasAsian = (($optionFlags & 0x04) != 0);
2836:
2837:
2838: $hasRichText = (($optionFlags & 0x08) != 0);
2839:
2840: if ($hasRichText) {
2841:
2842: $formattingRuns = self::_GetInt2d($recordData, $pos);
2843: $pos += 2;
2844: }
2845:
2846: if ($hasAsian) {
2847:
2848: $extendedRunLength = self::_GetInt4d($recordData, $pos);
2849: $pos += 4;
2850: }
2851:
2852:
2853: $len = ($isCompressed) ? $numChars : $numChars * 2;
2854:
2855:
2856: foreach ($spliceOffsets as $spliceOffset) {
2857:
2858:
2859: if ($pos <= $spliceOffset) {
2860: $limitpos = $spliceOffset;
2861: break;
2862: }
2863: }
2864:
2865: if ($pos + $len <= $limitpos) {
2866:
2867:
2868: $retstr = substr($recordData, $pos, $len);
2869: $pos += $len;
2870:
2871: } else {
2872:
2873:
2874:
2875: $retstr = substr($recordData, $pos, $limitpos - $pos);
2876:
2877: $bytesRead = $limitpos - $pos;
2878:
2879:
2880: $charsLeft = $numChars - (($isCompressed) ? $bytesRead : ($bytesRead / 2));
2881:
2882: $pos = $limitpos;
2883:
2884:
2885: while ($charsLeft > 0) {
2886:
2887:
2888: foreach ($spliceOffsets as $spliceOffset) {
2889: if ($pos < $spliceOffset) {
2890: $limitpos = $spliceOffset;
2891: break;
2892: }
2893: }
2894:
2895:
2896:
2897: $option = ord($recordData{$pos});
2898: ++$pos;
2899:
2900: if ($isCompressed && ($option == 0)) {
2901:
2902:
2903: $len = min($charsLeft, $limitpos - $pos);
2904: $retstr .= substr($recordData, $pos, $len);
2905: $charsLeft -= $len;
2906: $isCompressed = true;
2907:
2908: } elseif (!$isCompressed && ($option != 0)) {
2909:
2910:
2911: $len = min($charsLeft * 2, $limitpos - $pos);
2912: $retstr .= substr($recordData, $pos, $len);
2913: $charsLeft -= $len / 2;
2914: $isCompressed = false;
2915:
2916: } elseif (!$isCompressed && ($option == 0)) {
2917:
2918:
2919: $len = min($charsLeft, $limitpos - $pos);
2920: for ($j = 0; $j < $len; ++$j) {
2921: $retstr .= $recordData{$pos + $j} . chr(0);
2922: }
2923: $charsLeft -= $len;
2924: $isCompressed = false;
2925:
2926: } else {
2927:
2928:
2929: $newstr = '';
2930: for ($j = 0; $j < strlen($retstr); ++$j) {
2931: $newstr .= $retstr[$j] . chr(0);
2932: }
2933: $retstr = $newstr;
2934: $len = min($charsLeft * 2, $limitpos - $pos);
2935: $retstr .= substr($recordData, $pos, $len);
2936: $charsLeft -= $len / 2;
2937: $isCompressed = false;
2938: }
2939:
2940: $pos += $len;
2941: }
2942: }
2943:
2944:
2945: $retstr = self::_encodeUTF16($retstr, $isCompressed);
2946:
2947:
2948: $fmtRuns = array();
2949: if ($hasRichText) {
2950:
2951: for ($j = 0; $j < $formattingRuns; ++$j) {
2952:
2953: $charPos = self::_GetInt2d($recordData, $pos + $j * 4);
2954:
2955:
2956: $fontIndex = self::_GetInt2d($recordData, $pos + 2 + $j * 4);
2957:
2958: $fmtRuns[] = array(
2959: 'charPos' => $charPos,
2960: 'fontIndex' => $fontIndex,
2961: );
2962: }
2963: $pos += 4 * $formattingRuns;
2964: }
2965:
2966:
2967: if ($hasAsian) {
2968:
2969: $pos += $extendedRunLength;
2970: }
2971:
2972:
2973: $this->_sst[] = array(
2974: 'value' => $retstr,
2975: 'fmtRuns' => $fmtRuns,
2976: );
2977: }
2978:
2979:
2980: }
2981:
2982:
2983: 2984: 2985:
2986: private function _readPrintGridlines()
2987: {
2988: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
2989: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
2990:
2991:
2992: $this->_pos += 4 + $length;
2993:
2994: if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) {
2995:
2996: $printGridlines = (bool) self::_GetInt2d($recordData, 0);
2997: $this->_phpSheet->setPrintGridlines($printGridlines);
2998: }
2999: }
3000:
3001:
3002: 3003: 3004:
3005: private function _readDefaultRowHeight()
3006: {
3007: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3008: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3009:
3010:
3011: $this->_pos += 4 + $length;
3012:
3013:
3014:
3015: $height = self::_GetInt2d($recordData, 2);
3016: $this->_phpSheet->getDefaultRowDimension()->setRowHeight($height / 20);
3017: }
3018:
3019:
3020: 3021: 3022:
3023: private function _readSheetPr()
3024: {
3025: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3026: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3027:
3028:
3029: $this->_pos += 4 + $length;
3030:
3031:
3032:
3033:
3034: $isSummaryBelow = (0x0040 & self::_GetInt2d($recordData, 0)) >> 6;
3035: $this->_phpSheet->setShowSummaryBelow($isSummaryBelow);
3036:
3037:
3038: $isSummaryRight = (0x0080 & self::_GetInt2d($recordData, 0)) >> 7;
3039: $this->_phpSheet->setShowSummaryRight($isSummaryRight);
3040:
3041:
3042:
3043: $this->_isFitToPages = (bool) ((0x0100 & self::_GetInt2d($recordData, 0)) >> 8);
3044: }
3045:
3046:
3047: 3048: 3049:
3050: private function _readHorizontalPageBreaks()
3051: {
3052: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3053: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3054:
3055:
3056: $this->_pos += 4 + $length;
3057:
3058: if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) {
3059:
3060:
3061: $nm = self::_GetInt2d($recordData, 0);
3062:
3063:
3064: for ($i = 0; $i < $nm; ++$i) {
3065: $r = self::_GetInt2d($recordData, 2 + 6 * $i);
3066: $cf = self::_GetInt2d($recordData, 2 + 6 * $i + 2);
3067: $cl = self::_GetInt2d($recordData, 2 + 6 * $i + 4);
3068:
3069:
3070: $this->_phpSheet->setBreakByColumnAndRow($cf, $r, PHPExcel_Worksheet::BREAK_ROW);
3071: }
3072: }
3073: }
3074:
3075:
3076: 3077: 3078:
3079: private function _readVerticalPageBreaks()
3080: {
3081: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3082: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3083:
3084:
3085: $this->_pos += 4 + $length;
3086:
3087: if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) {
3088:
3089: $nm = self::_GetInt2d($recordData, 0);
3090:
3091:
3092: for ($i = 0; $i < $nm; ++$i) {
3093: $c = self::_GetInt2d($recordData, 2 + 6 * $i);
3094: $rf = self::_GetInt2d($recordData, 2 + 6 * $i + 2);
3095: $rl = self::_GetInt2d($recordData, 2 + 6 * $i + 4);
3096:
3097:
3098: $this->_phpSheet->setBreakByColumnAndRow($c, $rf, PHPExcel_Worksheet::BREAK_COLUMN);
3099: }
3100: }
3101: }
3102:
3103:
3104: 3105: 3106:
3107: private function _readHeader()
3108: {
3109: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3110: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3111:
3112:
3113: $this->_pos += 4 + $length;
3114:
3115: if (!$this->_readDataOnly) {
3116:
3117:
3118: if ($recordData) {
3119: if ($this->_version == self::XLS_BIFF8) {
3120: $string = self::_readUnicodeStringLong($recordData);
3121: } else {
3122: $string = $this->_readByteStringShort($recordData);
3123: }
3124:
3125: $this->_phpSheet->getHeaderFooter()->setOddHeader($string['value']);
3126: $this->_phpSheet->getHeaderFooter()->setEvenHeader($string['value']);
3127: }
3128: }
3129: }
3130:
3131:
3132: 3133: 3134:
3135: private function _readFooter()
3136: {
3137: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3138: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3139:
3140:
3141: $this->_pos += 4 + $length;
3142:
3143: if (!$this->_readDataOnly) {
3144:
3145:
3146: if ($recordData) {
3147: if ($this->_version == self::XLS_BIFF8) {
3148: $string = self::_readUnicodeStringLong($recordData);
3149: } else {
3150: $string = $this->_readByteStringShort($recordData);
3151: }
3152: $this->_phpSheet->getHeaderFooter()->setOddFooter($string['value']);
3153: $this->_phpSheet->getHeaderFooter()->setEvenFooter($string['value']);
3154: }
3155: }
3156: }
3157:
3158:
3159: 3160: 3161:
3162: private function _readHcenter()
3163: {
3164: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3165: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3166:
3167:
3168: $this->_pos += 4 + $length;
3169:
3170: if (!$this->_readDataOnly) {
3171:
3172: $isHorizontalCentered = (bool) self::_GetInt2d($recordData, 0);
3173:
3174: $this->_phpSheet->getPageSetup()->setHorizontalCentered($isHorizontalCentered);
3175: }
3176: }
3177:
3178:
3179: 3180: 3181:
3182: private function _readVcenter()
3183: {
3184: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3185: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3186:
3187:
3188: $this->_pos += 4 + $length;
3189:
3190: if (!$this->_readDataOnly) {
3191:
3192: $isVerticalCentered = (bool) self::_GetInt2d($recordData, 0);
3193:
3194: $this->_phpSheet->getPageSetup()->setVerticalCentered($isVerticalCentered);
3195: }
3196: }
3197:
3198:
3199: 3200: 3201:
3202: private function _readLeftMargin()
3203: {
3204: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3205: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3206:
3207:
3208: $this->_pos += 4 + $length;
3209:
3210: if (!$this->_readDataOnly) {
3211:
3212: $this->_phpSheet->getPageMargins()->setLeft(self::_extractNumber($recordData));
3213: }
3214: }
3215:
3216:
3217: 3218: 3219:
3220: private function _readRightMargin()
3221: {
3222: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3223: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3224:
3225:
3226: $this->_pos += 4 + $length;
3227:
3228: if (!$this->_readDataOnly) {
3229:
3230: $this->_phpSheet->getPageMargins()->setRight(self::_extractNumber($recordData));
3231: }
3232: }
3233:
3234:
3235: 3236: 3237:
3238: private function _readTopMargin()
3239: {
3240: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3241: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3242:
3243:
3244: $this->_pos += 4 + $length;
3245:
3246: if (!$this->_readDataOnly) {
3247:
3248: $this->_phpSheet->getPageMargins()->setTop(self::_extractNumber($recordData));
3249: }
3250: }
3251:
3252:
3253: 3254: 3255:
3256: private function _readBottomMargin()
3257: {
3258: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3259: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3260:
3261:
3262: $this->_pos += 4 + $length;
3263:
3264: if (!$this->_readDataOnly) {
3265:
3266: $this->_phpSheet->getPageMargins()->setBottom(self::_extractNumber($recordData));
3267: }
3268: }
3269:
3270:
3271: 3272: 3273:
3274: private function _readPageSetup()
3275: {
3276: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3277: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3278:
3279:
3280: $this->_pos += 4 + $length;
3281:
3282: if (!$this->_readDataOnly) {
3283:
3284: $paperSize = self::_GetInt2d($recordData, 0);
3285:
3286:
3287: $scale = self::_GetInt2d($recordData, 2);
3288:
3289:
3290: $fitToWidth = self::_GetInt2d($recordData, 6);
3291:
3292:
3293: $fitToHeight = self::_GetInt2d($recordData, 8);
3294:
3295:
3296:
3297:
3298: $isPortrait = (0x0002 & self::_GetInt2d($recordData, 10)) >> 1;
3299:
3300:
3301:
3302: $isNotInit = (0x0004 & self::_GetInt2d($recordData, 10)) >> 2;
3303:
3304: if (!$isNotInit) {
3305: $this->_phpSheet->getPageSetup()->setPaperSize($paperSize);
3306: switch ($isPortrait) {
3307: case 0: $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); break;
3308: case 1: $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT); break;
3309: }
3310:
3311: $this->_phpSheet->getPageSetup()->setScale($scale, false);
3312: $this->_phpSheet->getPageSetup()->setFitToPage((bool) $this->_isFitToPages);
3313: $this->_phpSheet->getPageSetup()->setFitToWidth($fitToWidth, false);
3314: $this->_phpSheet->getPageSetup()->setFitToHeight($fitToHeight, false);
3315: }
3316:
3317:
3318: $marginHeader = self::_extractNumber(substr($recordData, 16, 8));
3319: $this->_phpSheet->getPageMargins()->setHeader($marginHeader);
3320:
3321:
3322: $marginFooter = self::_extractNumber(substr($recordData, 24, 8));
3323: $this->_phpSheet->getPageMargins()->setFooter($marginFooter);
3324: }
3325: }
3326:
3327:
3328: 3329: 3330: 3331:
3332: private function _readProtect()
3333: {
3334: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3335: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3336:
3337:
3338: $this->_pos += 4 + $length;
3339:
3340: if ($this->_readDataOnly) {
3341: return;
3342: }
3343:
3344:
3345:
3346:
3347: $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0;
3348: $this->_phpSheet->getProtection()->setSheet((bool)$bool);
3349: }
3350:
3351:
3352: 3353: 3354:
3355: private function _readScenProtect()
3356: {
3357: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3358: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3359:
3360:
3361: $this->_pos += 4 + $length;
3362:
3363: if ($this->_readDataOnly) {
3364: return;
3365: }
3366:
3367:
3368:
3369:
3370: $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0;
3371:
3372: $this->_phpSheet->getProtection()->setScenarios((bool)$bool);
3373: }
3374:
3375:
3376: 3377: 3378:
3379: private function _readObjectProtect()
3380: {
3381: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3382: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3383:
3384:
3385: $this->_pos += 4 + $length;
3386:
3387: if ($this->_readDataOnly) {
3388: return;
3389: }
3390:
3391:
3392:
3393:
3394: $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0;
3395:
3396: $this->_phpSheet->getProtection()->setObjects((bool)$bool);
3397: }
3398:
3399:
3400: 3401: 3402:
3403: private function _readPassword()
3404: {
3405: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3406: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3407:
3408:
3409: $this->_pos += 4 + $length;
3410:
3411: if (!$this->_readDataOnly) {
3412:
3413: $password = strtoupper(dechex(self::_GetInt2d($recordData, 0)));
3414: $this->_phpSheet->getProtection()->setPassword($password, true);
3415: }
3416: }
3417:
3418:
3419: 3420: 3421:
3422: private function _readDefColWidth()
3423: {
3424: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3425: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3426:
3427:
3428: $this->_pos += 4 + $length;
3429:
3430:
3431: $width = self::_GetInt2d($recordData, 0);
3432: if ($width != 8) {
3433: $this->_phpSheet->getDefaultColumnDimension()->setWidth($width);
3434: }
3435: }
3436:
3437:
3438: 3439: 3440:
3441: private function _readColInfo()
3442: {
3443: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3444: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3445:
3446:
3447: $this->_pos += 4 + $length;
3448:
3449: if (!$this->_readDataOnly) {
3450:
3451: $fc = self::_GetInt2d($recordData, 0);
3452:
3453:
3454: $lc = self::_GetInt2d($recordData, 2);
3455:
3456:
3457: $width = self::_GetInt2d($recordData, 4);
3458:
3459:
3460: $xfIndex = self::_GetInt2d($recordData, 6);
3461:
3462:
3463:
3464:
3465: $isHidden = (0x0001 & self::_GetInt2d($recordData, 8)) >> 0;
3466:
3467:
3468: $level = (0x0700 & self::_GetInt2d($recordData, 8)) >> 8;
3469:
3470:
3471: $isCollapsed = (0x1000 & self::_GetInt2d($recordData, 8)) >> 12;
3472:
3473:
3474:
3475: for ($i = $fc; $i <= $lc; ++$i) {
3476: if ($lc == 255 || $lc == 256) {
3477: $this->_phpSheet->getDefaultColumnDimension()->setWidth($width / 256);
3478: break;
3479: }
3480: $this->_phpSheet->getColumnDimensionByColumn($i)->setWidth($width / 256);
3481: $this->_phpSheet->getColumnDimensionByColumn($i)->setVisible(!$isHidden);
3482: $this->_phpSheet->getColumnDimensionByColumn($i)->setOutlineLevel($level);
3483: $this->_phpSheet->getColumnDimensionByColumn($i)->setCollapsed($isCollapsed);
3484: $this->_phpSheet->getColumnDimensionByColumn($i)->setXfIndex($this->_mapCellXfIndex[$xfIndex]);
3485: }
3486: }
3487: }
3488:
3489:
3490: 3491: 3492: 3493: 3494: 3495: 3496: 3497: 3498: 3499:
3500: private function _readRow()
3501: {
3502: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3503: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3504:
3505:
3506: $this->_pos += 4 + $length;
3507:
3508: if (!$this->_readDataOnly) {
3509:
3510: $r = self::_GetInt2d($recordData, 0);
3511:
3512:
3513:
3514:
3515:
3516:
3517:
3518:
3519: $height = (0x7FFF & self::_GetInt2d($recordData, 6)) >> 0;
3520:
3521:
3522: $useDefaultHeight = (0x8000 & self::_GetInt2d($recordData, 6)) >> 15;
3523:
3524: if (!$useDefaultHeight) {
3525: $this->_phpSheet->getRowDimension($r + 1)->setRowHeight($height / 20);
3526: }
3527:
3528:
3529:
3530:
3531:
3532:
3533:
3534:
3535: $level = (0x00000007 & self::_GetInt4d($recordData, 12)) >> 0;
3536: $this->_phpSheet->getRowDimension($r + 1)->setOutlineLevel($level);
3537:
3538:
3539: $isCollapsed = (0x00000010 & self::_GetInt4d($recordData, 12)) >> 4;
3540: $this->_phpSheet->getRowDimension($r + 1)->setCollapsed($isCollapsed);
3541:
3542:
3543: $isHidden = (0x00000020 & self::_GetInt4d($recordData, 12)) >> 5;
3544: $this->_phpSheet->getRowDimension($r + 1)->setVisible(!$isHidden);
3545:
3546:
3547: $hasExplicitFormat = (0x00000080 & self::_GetInt4d($recordData, 12)) >> 7;
3548:
3549:
3550: $xfIndex = (0x0FFF0000 & self::_GetInt4d($recordData, 12)) >> 16;
3551:
3552: if ($hasExplicitFormat) {
3553: $this->_phpSheet->getRowDimension($r + 1)->setXfIndex($this->_mapCellXfIndex[$xfIndex]);
3554: }
3555: }
3556: }
3557:
3558:
3559: 3560: 3561: 3562: 3563: 3564: 3565: 3566: 3567: 3568: 3569:
3570: private function _readRk()
3571: {
3572: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3573: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3574:
3575:
3576: $this->_pos += 4 + $length;
3577:
3578:
3579: $row = self::_GetInt2d($recordData, 0);
3580:
3581:
3582: $column = self::_GetInt2d($recordData, 2);
3583: $columnString = PHPExcel_Cell::stringFromColumnIndex($column);
3584:
3585:
3586: if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {
3587:
3588: $xfIndex = self::_GetInt2d($recordData, 4);
3589:
3590:
3591: $rknum = self::_GetInt4d($recordData, 6);
3592: $numValue = self::_GetIEEE754($rknum);
3593:
3594: $cell = $this->_phpSheet->getCell($columnString . ($row + 1));
3595: if (!$this->_readDataOnly) {
3596:
3597: $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]);
3598: }
3599:
3600:
3601: $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC);
3602: }
3603: }
3604:
3605:
3606: 3607: 3608: 3609: 3610: 3611: 3612: 3613: 3614:
3615: private function _readLabelSst()
3616: {
3617: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3618: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3619:
3620:
3621: $this->_pos += 4 + $length;
3622:
3623:
3624: $row = self::_GetInt2d($recordData, 0);
3625:
3626:
3627: $column = self::_GetInt2d($recordData, 2);
3628: $columnString = PHPExcel_Cell::stringFromColumnIndex($column);
3629:
3630:
3631: if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {
3632:
3633: $xfIndex = self::_GetInt2d($recordData, 4);
3634:
3635:
3636: $index = self::_GetInt4d($recordData, 6);
3637:
3638:
3639: if (($fmtRuns = $this->_sst[$index]['fmtRuns']) && !$this->_readDataOnly) {
3640:
3641: $richText = new PHPExcel_RichText();
3642: $charPos = 0;
3643: $sstCount = count($this->_sst[$index]['fmtRuns']);
3644: for ($i = 0; $i <= $sstCount; ++$i) {
3645: if (isset($fmtRuns[$i])) {
3646: $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, $fmtRuns[$i]['charPos'] - $charPos);
3647: $charPos = $fmtRuns[$i]['charPos'];
3648: } else {
3649: $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, PHPExcel_Shared_String::CountCharacters($this->_sst[$index]['value']));
3650: }
3651:
3652: if (PHPExcel_Shared_String::CountCharacters($text) > 0) {
3653: if ($i == 0) {
3654: $richText->createText($text);
3655: } else {
3656: $textRun = $richText->createTextRun($text);
3657: if (isset($fmtRuns[$i - 1])) {
3658: if ($fmtRuns[$i - 1]['fontIndex'] < 4) {
3659: $fontIndex = $fmtRuns[$i - 1]['fontIndex'];
3660: } else {
3661:
3662:
3663: $fontIndex = $fmtRuns[$i - 1]['fontIndex'] - 1;
3664: }
3665: $textRun->setFont(clone $this->_objFonts[$fontIndex]);
3666: }
3667: }
3668: }
3669: }
3670: $cell = $this->_phpSheet->getCell($columnString . ($row + 1));
3671: $cell->setValueExplicit($richText, PHPExcel_Cell_DataType::TYPE_STRING);
3672: } else {
3673: $cell = $this->_phpSheet->getCell($columnString . ($row + 1));
3674: $cell->setValueExplicit($this->_sst[$index]['value'], PHPExcel_Cell_DataType::TYPE_STRING);
3675: }
3676:
3677: if (!$this->_readDataOnly) {
3678:
3679: $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]);
3680: }
3681: }
3682: }
3683:
3684:
3685: 3686: 3687: 3688: 3689: 3690: 3691: 3692:
3693: private function _readMulRk()
3694: {
3695: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3696: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3697:
3698:
3699: $this->_pos += 4 + $length;
3700:
3701:
3702: $row = self::_GetInt2d($recordData, 0);
3703:
3704:
3705: $colFirst = self::_GetInt2d($recordData, 2);
3706:
3707:
3708: $colLast = self::_GetInt2d($recordData, $length - 2);
3709: $columns = $colLast - $colFirst + 1;
3710:
3711:
3712: $offset = 4;
3713:
3714: for ($i = 0; $i < $columns; ++$i) {
3715: $columnString = PHPExcel_Cell::stringFromColumnIndex($colFirst + $i);
3716:
3717:
3718: if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {
3719:
3720:
3721: $xfIndex = self::_GetInt2d($recordData, $offset);
3722:
3723:
3724: $numValue = self::_GetIEEE754(self::_GetInt4d($recordData, $offset + 2));
3725: $cell = $this->_phpSheet->getCell($columnString . ($row + 1));
3726: if (!$this->_readDataOnly) {
3727:
3728: $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]);
3729: }
3730:
3731:
3732: $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC);
3733: }
3734:
3735: $offset += 6;
3736: }
3737: }
3738:
3739:
3740: 3741: 3742: 3743: 3744: 3745: 3746: 3747:
3748: private function _readNumber()
3749: {
3750: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3751: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3752:
3753:
3754: $this->_pos += 4 + $length;
3755:
3756:
3757: $row = self::_GetInt2d($recordData, 0);
3758:
3759:
3760: $column = self::_GetInt2d($recordData, 2);
3761: $columnString = PHPExcel_Cell::stringFromColumnIndex($column);
3762:
3763:
3764: if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {
3765:
3766: $xfIndex = self::_GetInt2d($recordData, 4);
3767:
3768: $numValue = self::_extractNumber(substr($recordData, 6, 8));
3769:
3770: $cell = $this->_phpSheet->getCell($columnString . ($row + 1));
3771: if (!$this->_readDataOnly) {
3772:
3773: $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]);
3774: }
3775:
3776:
3777: $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC);
3778: }
3779: }
3780:
3781:
3782: 3783: 3784: 3785: 3786: 3787: 3788: 3789:
3790: private function _readFormula()
3791: {
3792: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3793: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3794:
3795:
3796: $this->_pos += 4 + $length;
3797:
3798:
3799: $row = self::_GetInt2d($recordData, 0);
3800:
3801:
3802: $column = self::_GetInt2d($recordData, 2);
3803: $columnString = PHPExcel_Cell::stringFromColumnIndex($column);
3804:
3805:
3806: $formulaStructure = substr($recordData, 20);
3807:
3808:
3809: $options = self::_GetInt2d($recordData, 14);
3810:
3811:
3812:
3813:
3814: $isPartOfSharedFormula = (bool) (0x0008 & $options);
3815:
3816:
3817:
3818:
3819:
3820: $isPartOfSharedFormula = $isPartOfSharedFormula && ord($formulaStructure{2}) == 0x01;
3821:
3822: if ($isPartOfSharedFormula) {
3823:
3824:
3825: $baseRow = self::_GetInt2d($formulaStructure, 3);
3826: $baseCol = self::_GetInt2d($formulaStructure, 5);
3827: $this->_baseCell = PHPExcel_Cell::stringFromColumnIndex($baseCol). ($baseRow + 1);
3828: }
3829:
3830:
3831: if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {
3832:
3833: if ($isPartOfSharedFormula) {
3834:
3835: $this->_sharedFormulaParts[$columnString . ($row + 1)] = $this->_baseCell;
3836: }
3837:
3838:
3839:
3840:
3841: $xfIndex = self::_GetInt2d($recordData, 4);
3842:
3843:
3844: if ( (ord($recordData{6}) == 0)
3845: && (ord($recordData{12}) == 255)
3846: && (ord($recordData{13}) == 255) ) {
3847:
3848:
3849: $dataType = PHPExcel_Cell_DataType::TYPE_STRING;
3850:
3851:
3852: $code = self::_GetInt2d($this->_data, $this->_pos);
3853: if ($code == self::XLS_Type_SHAREDFMLA) {
3854: $this->_readSharedFmla();
3855: }
3856:
3857:
3858: $value = $this->_readString();
3859:
3860: } elseif ((ord($recordData{6}) == 1)
3861: && (ord($recordData{12}) == 255)
3862: && (ord($recordData{13}) == 255)) {
3863:
3864:
3865: $dataType = PHPExcel_Cell_DataType::TYPE_BOOL;
3866: $value = (bool) ord($recordData{8});
3867:
3868: } elseif ((ord($recordData{6}) == 2)
3869: && (ord($recordData{12}) == 255)
3870: && (ord($recordData{13}) == 255)) {
3871:
3872:
3873: $dataType = PHPExcel_Cell_DataType::TYPE_ERROR;
3874: $value = self::_mapErrorCode(ord($recordData{8}));
3875:
3876: } elseif ((ord($recordData{6}) == 3)
3877: && (ord($recordData{12}) == 255)
3878: && (ord($recordData{13}) == 255)) {
3879:
3880:
3881: $dataType = PHPExcel_Cell_DataType::TYPE_NULL;
3882: $value = '';
3883:
3884: } else {
3885:
3886:
3887: $dataType = PHPExcel_Cell_DataType::TYPE_NUMERIC;
3888: $value = self::_extractNumber(substr($recordData, 6, 8));
3889:
3890: }
3891:
3892: $cell = $this->_phpSheet->getCell($columnString . ($row + 1));
3893: if (!$this->_readDataOnly) {
3894:
3895: $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]);
3896: }
3897:
3898:
3899: if (!$isPartOfSharedFormula) {
3900:
3901:
3902: try {
3903: if ($this->_version != self::XLS_BIFF8) {
3904: throw new PHPExcel_Reader_Exception('Not BIFF8. Can only read BIFF8 formulas');
3905: }
3906: $formula = $this->_getFormulaFromStructure($formulaStructure);
3907: $cell->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA);
3908:
3909: } catch (PHPExcel_Exception $e) {
3910: $cell->setValueExplicit($value, $dataType);
3911: }
3912: } else {
3913: if ($this->_version == self::XLS_BIFF8) {
3914:
3915: } else {
3916: $cell->setValueExplicit($value, $dataType);
3917: }
3918: }
3919:
3920:
3921: $cell->setCalculatedValue($value);
3922: }
3923: }
3924:
3925:
3926: 3927: 3928: 3929: 3930:
3931: private function _readSharedFmla()
3932: {
3933: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3934: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3935:
3936:
3937: $this->_pos += 4 + $length;
3938:
3939:
3940: $cellRange = substr($recordData, 0, 6);
3941: $cellRange = $this->_readBIFF5CellRangeAddressFixed($cellRange);
3942:
3943:
3944:
3945:
3946: $no = ord($recordData{7});
3947:
3948:
3949: $formula = substr($recordData, 8);
3950:
3951:
3952: $this->_sharedFormulas[$this->_baseCell] = $formula;
3953:
3954: }
3955:
3956:
3957: 3958: 3959: 3960: 3961: 3962: 3963:
3964: private function _readString()
3965: {
3966: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3967: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3968:
3969:
3970: $this->_pos += 4 + $length;
3971:
3972: if ($this->_version == self::XLS_BIFF8) {
3973: $string = self::_readUnicodeStringLong($recordData);
3974: $value = $string['value'];
3975: } else {
3976: $string = $this->_readByteStringLong($recordData);
3977: $value = $string['value'];
3978: }
3979:
3980: return $value;
3981: }
3982:
3983:
3984: 3985: 3986: 3987: 3988: 3989: 3990: 3991:
3992: private function _readBoolErr()
3993: {
3994: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
3995: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
3996:
3997:
3998: $this->_pos += 4 + $length;
3999:
4000:
4001: $row = self::_GetInt2d($recordData, 0);
4002:
4003:
4004: $column = self::_GetInt2d($recordData, 2);
4005: $columnString = PHPExcel_Cell::stringFromColumnIndex($column);
4006:
4007:
4008: if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {
4009:
4010: $xfIndex = self::_GetInt2d($recordData, 4);
4011:
4012:
4013: $boolErr = ord($recordData{6});
4014:
4015:
4016: $isError = ord($recordData{7});
4017:
4018: $cell = $this->_phpSheet->getCell($columnString . ($row + 1));
4019: switch ($isError) {
4020: case 0:
4021: $value = (bool) $boolErr;
4022:
4023:
4024: $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_BOOL);
4025: break;
4026:
4027: case 1:
4028: $value = self::_mapErrorCode($boolErr);
4029:
4030:
4031: $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_ERROR);
4032: break;
4033: }
4034:
4035: if (!$this->_readDataOnly) {
4036:
4037: $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]);
4038: }
4039: }
4040: }
4041:
4042:
4043: 4044: 4045: 4046: 4047: 4048: 4049: 4050:
4051: private function _readMulBlank()
4052: {
4053: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4054: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4055:
4056:
4057: $this->_pos += 4 + $length;
4058:
4059:
4060: $row = self::_GetInt2d($recordData, 0);
4061:
4062:
4063: $fc = self::_GetInt2d($recordData, 2);
4064:
4065:
4066:
4067: if (!$this->_readDataOnly) {
4068: for ($i = 0; $i < $length / 2 - 3; ++$i) {
4069: $columnString = PHPExcel_Cell::stringFromColumnIndex($fc + $i);
4070:
4071:
4072: if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {
4073: $xfIndex = self::_GetInt2d($recordData, 4 + 2 * $i);
4074: $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]);
4075: }
4076: }
4077: }
4078:
4079:
4080: }
4081:
4082:
4083: 4084: 4085: 4086: 4087: 4088: 4089: 4090: 4091: 4092:
4093: private function _readLabel()
4094: {
4095: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4096: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4097:
4098:
4099: $this->_pos += 4 + $length;
4100:
4101:
4102: $row = self::_GetInt2d($recordData, 0);
4103:
4104:
4105: $column = self::_GetInt2d($recordData, 2);
4106: $columnString = PHPExcel_Cell::stringFromColumnIndex($column);
4107:
4108:
4109: if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {
4110:
4111: $xfIndex = self::_GetInt2d($recordData, 4);
4112:
4113:
4114:
4115: if ($this->_version == self::XLS_BIFF8) {
4116: $string = self::_readUnicodeStringLong(substr($recordData, 6));
4117: $value = $string['value'];
4118: } else {
4119: $string = $this->_readByteStringLong(substr($recordData, 6));
4120: $value = $string['value'];
4121: }
4122: $cell = $this->_phpSheet->getCell($columnString . ($row + 1));
4123: $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING);
4124:
4125: if (!$this->_readDataOnly) {
4126:
4127: $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]);
4128: }
4129: }
4130: }
4131:
4132:
4133: 4134: 4135:
4136: private function _readBlank()
4137: {
4138: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4139: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4140:
4141:
4142: $this->_pos += 4 + $length;
4143:
4144:
4145: $row = self::_GetInt2d($recordData, 0);
4146:
4147:
4148: $col = self::_GetInt2d($recordData, 2);
4149: $columnString = PHPExcel_Cell::stringFromColumnIndex($col);
4150:
4151:
4152: if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {
4153:
4154: $xfIndex = self::_GetInt2d($recordData, 4);
4155:
4156:
4157: if (!$this->_readDataOnly) {
4158: $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]);
4159: }
4160: }
4161:
4162: }
4163:
4164:
4165: 4166: 4167:
4168: private function _readMsoDrawing()
4169: {
4170: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4171:
4172:
4173: $splicedRecordData = $this->_getSplicedRecordData();
4174: $recordData = $splicedRecordData['recordData'];
4175:
4176: $this->_drawingData .= $recordData;
4177: }
4178:
4179:
4180: 4181: 4182:
4183: private function _readObj()
4184: {
4185: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4186: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4187:
4188:
4189: $this->_pos += 4 + $length;
4190:
4191: if ($this->_readDataOnly || $this->_version != self::XLS_BIFF8) {
4192: return;
4193: }
4194:
4195:
4196:
4197:
4198:
4199:
4200:
4201:
4202:
4203:
4204: $ftCmoType = self::_GetInt2d($recordData, 0);
4205: $cbCmoSize = self::_GetInt2d($recordData, 2);
4206: $otObjType = self::_GetInt2d($recordData, 4);
4207: $idObjID = self::_GetInt2d($recordData, 6);
4208: $grbitOpts = self::_GetInt2d($recordData, 6);
4209:
4210: $this->_objs[] = array(
4211: 'ftCmoType' => $ftCmoType,
4212: 'cbCmoSize' => $cbCmoSize,
4213: 'otObjType' => $otObjType,
4214: 'idObjID' => $idObjID,
4215: 'grbitOpts' => $grbitOpts
4216: );
4217: $this->textObjRef = $idObjID;
4218:
4219:
4220:
4221:
4222: }
4223:
4224:
4225: 4226: 4227:
4228: private function _readWindow2()
4229: {
4230: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4231: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4232:
4233:
4234: $this->_pos += 4 + $length;
4235:
4236:
4237: $options = self::_GetInt2d($recordData, 0);
4238:
4239:
4240: $firstVisibleRow = self::_GetInt2d($recordData, 2);
4241:
4242:
4243: $firstVisibleColumn = self::_GetInt2d($recordData, 4);
4244: if ($this->_version === self::XLS_BIFF8) {
4245:
4246:
4247:
4248:
4249: $zoomscaleInPageBreakPreview = self::_GetInt2d($recordData, 10);
4250: if ($zoomscaleInPageBreakPreview === 0) $zoomscaleInPageBreakPreview = 60;
4251: $zoomscaleInNormalView = self::_GetInt2d($recordData, 12);
4252: if ($zoomscaleInNormalView === 0) $zoomscaleInNormalView = 100;
4253: }
4254:
4255:
4256: $showGridlines = (bool) ((0x0002 & $options) >> 1);
4257: $this->_phpSheet->setShowGridlines($showGridlines);
4258:
4259:
4260: $showRowColHeaders = (bool) ((0x0004 & $options) >> 2);
4261: $this->_phpSheet->setShowRowColHeaders($showRowColHeaders);
4262:
4263:
4264: $this->_frozen = (bool) ((0x0008 & $options) >> 3);
4265:
4266:
4267: $this->_phpSheet->setRightToLeft((bool)((0x0040 & $options) >> 6));
4268:
4269:
4270: $isActive = (bool) ((0x0400 & $options) >> 10);
4271: if ($isActive) {
4272: $this->_phpExcel->setActiveSheetIndex($this->_phpExcel->getIndex($this->_phpSheet));
4273: }
4274:
4275:
4276: $isPageBreakPreview = (bool) ((0x0800 & $options) >> 11);
4277:
4278:
4279:
4280: if ($this->_phpSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT) {
4281:
4282: $view = $isPageBreakPreview? PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW :
4283: PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL;
4284: $this->_phpSheet->getSheetView()->setView($view);
4285: if ($this->_version === self::XLS_BIFF8) {
4286: $zoomScale = $isPageBreakPreview? $zoomscaleInPageBreakPreview : $zoomscaleInNormalView;
4287: $this->_phpSheet->getSheetView()->setZoomScale($zoomScale);
4288: $this->_phpSheet->getSheetView()->setZoomScaleNormal($zoomscaleInNormalView);
4289: }
4290: }
4291: }
4292:
4293: 4294: 4295:
4296: private function _readPageLayoutView(){
4297: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4298: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4299:
4300:
4301: $this->_pos += 4 + $length;
4302:
4303:
4304:
4305:
4306:
4307: $rt = self::_GetInt2d($recordData, 0);
4308:
4309:
4310: $grbitFrt = self::_GetInt2d($recordData, 2);
4311:
4312:
4313:
4314:
4315: $wScalePLV = self::_GetInt2d($recordData, 12);
4316:
4317: $grbit = self::_GetInt2d($recordData, 14);
4318:
4319:
4320: $fPageLayoutView = $grbit & 0x01;
4321: $fRulerVisible = ($grbit >> 1) & 0x01;
4322: $fWhitespaceHidden = ($grbit >> 3) & 0x01;
4323:
4324: if ($fPageLayoutView === 1) {
4325: $this->_phpSheet->getSheetView()->setView(PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT);
4326: $this->_phpSheet->getSheetView()->setZoomScale($wScalePLV);
4327: }
4328:
4329: }
4330:
4331: 4332: 4333:
4334: private function _readScl()
4335: {
4336: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4337: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4338:
4339:
4340: $this->_pos += 4 + $length;
4341:
4342:
4343: $numerator = self::_GetInt2d($recordData, 0);
4344:
4345:
4346: $denumerator = self::_GetInt2d($recordData, 2);
4347:
4348:
4349: $this->_phpSheet->getSheetView()->setZoomScale($numerator * 100 / $denumerator);
4350: }
4351:
4352:
4353: 4354: 4355:
4356: private function _readPane()
4357: {
4358: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4359: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4360:
4361:
4362: $this->_pos += 4 + $length;
4363:
4364: if (!$this->_readDataOnly) {
4365:
4366: $px = self::_GetInt2d($recordData, 0);
4367:
4368:
4369: $py = self::_GetInt2d($recordData, 2);
4370:
4371: if ($this->_frozen) {
4372:
4373: $this->_phpSheet->freezePane(PHPExcel_Cell::stringFromColumnIndex($px) . ($py + 1));
4374: } else {
4375:
4376: }
4377: }
4378: }
4379:
4380:
4381: 4382: 4383:
4384: private function _readSelection()
4385: {
4386: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4387: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4388:
4389:
4390: $this->_pos += 4 + $length;
4391:
4392: if (!$this->_readDataOnly) {
4393:
4394: $paneId = ord($recordData{0});
4395:
4396:
4397: $r = self::_GetInt2d($recordData, 1);
4398:
4399:
4400: $c = self::_GetInt2d($recordData, 3);
4401:
4402:
4403:
4404: $index = self::_GetInt2d($recordData, 5);
4405:
4406:
4407: $data = substr($recordData, 7);
4408: $cellRangeAddressList = $this->_readBIFF5CellRangeAddressList($data);
4409:
4410: $selectedCells = $cellRangeAddressList['cellRangeAddresses'][0];
4411:
4412:
4413: if (preg_match('/^([A-Z]+1\:[A-Z]+)16384$/', $selectedCells)) {
4414: $selectedCells = preg_replace('/^([A-Z]+1\:[A-Z]+)16384$/', '${1}1048576', $selectedCells);
4415: }
4416:
4417:
4418: if (preg_match('/^([A-Z]+1\:[A-Z]+)65536$/', $selectedCells)) {
4419: $selectedCells = preg_replace('/^([A-Z]+1\:[A-Z]+)65536$/', '${1}1048576', $selectedCells);
4420: }
4421:
4422:
4423: if (preg_match('/^(A[0-9]+\:)IV([0-9]+)$/', $selectedCells)) {
4424: $selectedCells = preg_replace('/^(A[0-9]+\:)IV([0-9]+)$/', '${1}XFD${2}', $selectedCells);
4425: }
4426:
4427: $this->_phpSheet->setSelectedCells($selectedCells);
4428: }
4429: }
4430:
4431:
4432: private function _includeCellRangeFiltered($cellRangeAddress)
4433: {
4434: $includeCellRange = true;
4435: if ($this->getReadFilter() !== NULL) {
4436: $includeCellRange = false;
4437: $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($cellRangeAddress);
4438: $rangeBoundaries[1][0]++;
4439: for ($row = $rangeBoundaries[0][1]; $row <= $rangeBoundaries[1][1]; $row++) {
4440: for ($column = $rangeBoundaries[0][0]; $column != $rangeBoundaries[1][0]; $column++) {
4441: if ($this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle())) {
4442: $includeCellRange = true;
4443: break 2;
4444: }
4445: }
4446: }
4447: }
4448: return $includeCellRange;
4449: }
4450:
4451:
4452: 4453: 4454: 4455: 4456: 4457: 4458: 4459: 4460:
4461: private function _readMergedCells()
4462: {
4463: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4464: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4465:
4466:
4467: $this->_pos += 4 + $length;
4468:
4469: if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) {
4470: $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($recordData);
4471: foreach ($cellRangeAddressList['cellRangeAddresses'] as $cellRangeAddress) {
4472: if ((strpos($cellRangeAddress,':') !== FALSE) &&
4473: ($this->_includeCellRangeFiltered($cellRangeAddress))) {
4474: $this->_phpSheet->mergeCells($cellRangeAddress);
4475: }
4476: }
4477: }
4478: }
4479:
4480:
4481: 4482: 4483:
4484: private function _readHyperLink()
4485: {
4486: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4487: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4488:
4489:
4490: $this->_pos += 4 + $length;
4491:
4492: if (!$this->_readDataOnly) {
4493:
4494: try {
4495: $cellRange = $this->_readBIFF8CellRangeAddressFixed($recordData, 0, 8);
4496: } catch (PHPExcel_Exception $e) {
4497: return;
4498: }
4499:
4500:
4501:
4502:
4503:
4504:
4505:
4506:
4507: $isFileLinkOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 0;
4508:
4509:
4510: $isAbsPathOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 1;
4511:
4512:
4513: $hasDesc = (0x00000014 & self::_GetInt2d($recordData, 28)) >> 2;
4514:
4515:
4516: $hasText = (0x00000008 & self::_GetInt2d($recordData, 28)) >> 3;
4517:
4518:
4519: $hasFrame = (0x00000080 & self::_GetInt2d($recordData, 28)) >> 7;
4520:
4521:
4522: $isUNC = (0x00000100 & self::_GetInt2d($recordData, 28)) >> 8;
4523:
4524:
4525: $offset = 32;
4526:
4527: if ($hasDesc) {
4528:
4529: $dl = self::_GetInt4d($recordData, 32);
4530:
4531: $desc = self::_encodeUTF16(substr($recordData, 36, 2 * ($dl - 1)), false);
4532: $offset += 4 + 2 * $dl;
4533: }
4534: if ($hasFrame) {
4535: $fl = self::_GetInt4d($recordData, $offset);
4536: $offset += 4 + 2 * $fl;
4537: }
4538:
4539:
4540: $hyperlinkType = null;
4541:
4542: if ($isUNC) {
4543: $hyperlinkType = 'UNC';
4544: } else if (!$isFileLinkOrUrl) {
4545: $hyperlinkType = 'workbook';
4546: } else if (ord($recordData{$offset}) == 0x03) {
4547: $hyperlinkType = 'local';
4548: } else if (ord($recordData{$offset}) == 0xE0) {
4549: $hyperlinkType = 'URL';
4550: }
4551:
4552: switch ($hyperlinkType) {
4553: case 'URL':
4554:
4555:
4556:
4557:
4558: $offset += 16;
4559:
4560: $us = self::_GetInt4d($recordData, $offset);
4561: $offset += 4;
4562:
4563: $url = self::_encodeUTF16(substr($recordData, $offset, $us - 2), false);
4564: $url .= $hasText ? '#' : '';
4565: $offset += $us;
4566: break;
4567:
4568: case 'local':
4569:
4570:
4571:
4572:
4573:
4574:
4575: $offset += 16;
4576:
4577:
4578: $upLevelCount = self::_GetInt2d($recordData, $offset);
4579: $offset += 2;
4580:
4581:
4582: $sl = self::_GetInt4d($recordData, $offset);
4583: $offset += 4;
4584:
4585:
4586: $shortenedFilePath = substr($recordData, $offset, $sl);
4587: $shortenedFilePath = self::_encodeUTF16($shortenedFilePath, true);
4588: $shortenedFilePath = substr($shortenedFilePath, 0, -1);
4589:
4590: $offset += $sl;
4591:
4592:
4593: $offset += 24;
4594:
4595:
4596:
4597: $sz = self::_GetInt4d($recordData, $offset);
4598: $offset += 4;
4599:
4600:
4601: if ($sz > 0) {
4602:
4603: $xl = self::_GetInt4d($recordData, $offset);
4604: $offset += 4;
4605:
4606:
4607: $offset += 2;
4608:
4609:
4610: $extendedFilePath = substr($recordData, $offset, $xl);
4611: $extendedFilePath = self::_encodeUTF16($extendedFilePath, false);
4612: $offset += $xl;
4613: }
4614:
4615:
4616: $url = str_repeat('..\\', $upLevelCount);
4617: $url .= ($sz > 0) ?
4618: $extendedFilePath : $shortenedFilePath;
4619: $url .= $hasText ? '#' : '';
4620:
4621: break;
4622:
4623:
4624: case 'UNC':
4625:
4626:
4627: return;
4628:
4629: case 'workbook':
4630:
4631:
4632: $url = 'sheet://';
4633: break;
4634:
4635: default:
4636: return;
4637:
4638: }
4639:
4640: if ($hasText) {
4641:
4642: $tl = self::_GetInt4d($recordData, $offset);
4643: $offset += 4;
4644:
4645: $text = self::_encodeUTF16(substr($recordData, $offset, 2 * ($tl - 1)), false);
4646: $url .= $text;
4647: }
4648:
4649:
4650: foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cellRange) as $coordinate) {
4651: $this->_phpSheet->getCell($coordinate)->getHyperLink()->setUrl($url);
4652: }
4653: }
4654: }
4655:
4656:
4657: 4658: 4659:
4660: private function _readDataValidations()
4661: {
4662: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4663: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4664:
4665:
4666: $this->_pos += 4 + $length;
4667: }
4668:
4669:
4670: 4671: 4672:
4673: private function _readDataValidation()
4674: {
4675: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4676: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4677:
4678:
4679: $this->_pos += 4 + $length;
4680:
4681: if ($this->_readDataOnly) {
4682: return;
4683: }
4684:
4685:
4686: $options = self::_GetInt4d($recordData, 0);
4687:
4688:
4689: $type = (0x0000000F & $options) >> 0;
4690: switch ($type) {
4691: case 0x00: $type = PHPExcel_Cell_DataValidation::TYPE_NONE; break;
4692: case 0x01: $type = PHPExcel_Cell_DataValidation::TYPE_WHOLE; break;
4693: case 0x02: $type = PHPExcel_Cell_DataValidation::TYPE_DECIMAL; break;
4694: case 0x03: $type = PHPExcel_Cell_DataValidation::TYPE_LIST; break;
4695: case 0x04: $type = PHPExcel_Cell_DataValidation::TYPE_DATE; break;
4696: case 0x05: $type = PHPExcel_Cell_DataValidation::TYPE_TIME; break;
4697: case 0x06: $type = PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH; break;
4698: case 0x07: $type = PHPExcel_Cell_DataValidation::TYPE_CUSTOM; break;
4699: }
4700:
4701:
4702: $errorStyle = (0x00000070 & $options) >> 4;
4703: switch ($errorStyle) {
4704: case 0x00: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; break;
4705: case 0x01: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_WARNING; break;
4706: case 0x02: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_INFORMATION; break;
4707: }
4708:
4709:
4710:
4711: $explicitFormula = (0x00000080 & $options) >> 7;
4712:
4713:
4714: $allowBlank = (0x00000100 & $options) >> 8;
4715:
4716:
4717: $suppressDropDown = (0x00000200 & $options) >> 9;
4718:
4719:
4720: $showInputMessage = (0x00040000 & $options) >> 18;
4721:
4722:
4723: $showErrorMessage = (0x00080000 & $options) >> 19;
4724:
4725:
4726: $operator = (0x00F00000 & $options) >> 20;
4727: switch ($operator) {
4728: case 0x00: $operator = PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN ; break;
4729: case 0x01: $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN ; break;
4730: case 0x02: $operator = PHPExcel_Cell_DataValidation::OPERATOR_EQUAL ; break;
4731: case 0x03: $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL ; break;
4732: case 0x04: $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN ; break;
4733: case 0x05: $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN ; break;
4734: case 0x06: $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL; break;
4735: case 0x07: $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL ; break;
4736: }
4737:
4738:
4739: $offset = 4;
4740: $string = self::_readUnicodeStringLong(substr($recordData, $offset));
4741: $promptTitle = $string['value'] !== chr(0) ?
4742: $string['value'] : '';
4743: $offset += $string['size'];
4744:
4745:
4746: $string = self::_readUnicodeStringLong(substr($recordData, $offset));
4747: $errorTitle = $string['value'] !== chr(0) ?
4748: $string['value'] : '';
4749: $offset += $string['size'];
4750:
4751:
4752: $string = self::_readUnicodeStringLong(substr($recordData, $offset));
4753: $prompt = $string['value'] !== chr(0) ?
4754: $string['value'] : '';
4755: $offset += $string['size'];
4756:
4757:
4758: $string = self::_readUnicodeStringLong(substr($recordData, $offset));
4759: $error = $string['value'] !== chr(0) ?
4760: $string['value'] : '';
4761: $offset += $string['size'];
4762:
4763:
4764: $sz1 = self::_GetInt2d($recordData, $offset);
4765: $offset += 2;
4766:
4767:
4768: $offset += 2;
4769:
4770:
4771: $formula1 = substr($recordData, $offset, $sz1);
4772: $formula1 = pack('v', $sz1) . $formula1;
4773: try {
4774: $formula1 = $this->_getFormulaFromStructure($formula1);
4775:
4776:
4777: if ($type == PHPExcel_Cell_DataValidation::TYPE_LIST) {
4778: $formula1 = str_replace(chr(0), ',', $formula1);
4779: }
4780: } catch (PHPExcel_Exception $e) {
4781: return;
4782: }
4783: $offset += $sz1;
4784:
4785:
4786: $sz2 = self::_GetInt2d($recordData, $offset);
4787: $offset += 2;
4788:
4789:
4790: $offset += 2;
4791:
4792:
4793: $formula2 = substr($recordData, $offset, $sz2);
4794: $formula2 = pack('v', $sz2) . $formula2;
4795: try {
4796: $formula2 = $this->_getFormulaFromStructure($formula2);
4797: } catch (PHPExcel_Exception $e) {
4798: return;
4799: }
4800: $offset += $sz2;
4801:
4802:
4803: $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList(substr($recordData, $offset));
4804: $cellRangeAddresses = $cellRangeAddressList['cellRangeAddresses'];
4805:
4806: foreach ($cellRangeAddresses as $cellRange) {
4807: $stRange = $this->_phpSheet->shrinkRangeToFit($cellRange);
4808: $stRange = PHPExcel_Cell::extractAllCellReferencesInRange($stRange);
4809: foreach ($stRange as $coordinate) {
4810: $objValidation = $this->_phpSheet->getCell($coordinate)->getDataValidation();
4811: $objValidation->setType($type);
4812: $objValidation->setErrorStyle($errorStyle);
4813: $objValidation->setAllowBlank((bool)$allowBlank);
4814: $objValidation->setShowInputMessage((bool)$showInputMessage);
4815: $objValidation->setShowErrorMessage((bool)$showErrorMessage);
4816: $objValidation->setShowDropDown(!$suppressDropDown);
4817: $objValidation->setOperator($operator);
4818: $objValidation->setErrorTitle($errorTitle);
4819: $objValidation->setError($error);
4820: $objValidation->setPromptTitle($promptTitle);
4821: $objValidation->setPrompt($prompt);
4822: $objValidation->setFormula1($formula1);
4823: $objValidation->setFormula2($formula2);
4824: }
4825: }
4826:
4827: }
4828:
4829:
4830: 4831: 4832:
4833: private function _readSheetLayout()
4834: {
4835: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4836: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4837:
4838:
4839: $this->_pos += 4 + $length;
4840:
4841:
4842: $offset = 0;
4843:
4844: if (!$this->_readDataOnly) {
4845:
4846:
4847:
4848:
4849:
4850:
4851: $sz = self::_GetInt4d($recordData, 12);
4852:
4853: switch ($sz) {
4854: case 0x14:
4855:
4856: $colorIndex = self::_GetInt2d($recordData, 16);
4857: $color = self::_readColor($colorIndex,$this->_palette,$this->_version);
4858: $this->_phpSheet->getTabColor()->setRGB($color['rgb']);
4859: break;
4860:
4861: case 0x28:
4862:
4863: return;
4864: break;
4865: }
4866: }
4867: }
4868:
4869:
4870: 4871: 4872:
4873: private function _readSheetProtection()
4874: {
4875: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4876: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4877:
4878:
4879: $this->_pos += 4 + $length;
4880:
4881: if ($this->_readDataOnly) {
4882: return;
4883: }
4884:
4885:
4886:
4887:
4888:
4889:
4890:
4891:
4892: $isf = self::_GetInt2d($recordData, 12);
4893: if ($isf != 2) {
4894: return;
4895: }
4896:
4897:
4898:
4899:
4900:
4901:
4902:
4903: $options = self::_GetInt2d($recordData, 19);
4904:
4905:
4906: $bool = (0x0001 & $options) >> 0;
4907: $this->_phpSheet->getProtection()->setObjects(!$bool);
4908:
4909:
4910: $bool = (0x0002 & $options) >> 1;
4911: $this->_phpSheet->getProtection()->setScenarios(!$bool);
4912:
4913:
4914: $bool = (0x0004 & $options) >> 2;
4915: $this->_phpSheet->getProtection()->setFormatCells(!$bool);
4916:
4917:
4918: $bool = (0x0008 & $options) >> 3;
4919: $this->_phpSheet->getProtection()->setFormatColumns(!$bool);
4920:
4921:
4922: $bool = (0x0010 & $options) >> 4;
4923: $this->_phpSheet->getProtection()->setFormatRows(!$bool);
4924:
4925:
4926: $bool = (0x0020 & $options) >> 5;
4927: $this->_phpSheet->getProtection()->setInsertColumns(!$bool);
4928:
4929:
4930: $bool = (0x0040 & $options) >> 6;
4931: $this->_phpSheet->getProtection()->setInsertRows(!$bool);
4932:
4933:
4934: $bool = (0x0080 & $options) >> 7;
4935: $this->_phpSheet->getProtection()->setInsertHyperlinks(!$bool);
4936:
4937:
4938: $bool = (0x0100 & $options) >> 8;
4939: $this->_phpSheet->getProtection()->setDeleteColumns(!$bool);
4940:
4941:
4942: $bool = (0x0200 & $options) >> 9;
4943: $this->_phpSheet->getProtection()->setDeleteRows(!$bool);
4944:
4945:
4946: $bool = (0x0400 & $options) >> 10;
4947: $this->_phpSheet->getProtection()->setSelectLockedCells(!$bool);
4948:
4949:
4950: $bool = (0x0800 & $options) >> 11;
4951: $this->_phpSheet->getProtection()->setSort(!$bool);
4952:
4953:
4954: $bool = (0x1000 & $options) >> 12;
4955: $this->_phpSheet->getProtection()->setAutoFilter(!$bool);
4956:
4957:
4958: $bool = (0x2000 & $options) >> 13;
4959: $this->_phpSheet->getProtection()->setPivotTables(!$bool);
4960:
4961:
4962: $bool = (0x4000 & $options) >> 14;
4963: $this->_phpSheet->getProtection()->setSelectUnlockedCells(!$bool);
4964:
4965:
4966: }
4967:
4968:
4969: 4970: 4971: 4972: 4973:
4974: private function _readRangeProtection()
4975: {
4976: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
4977: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
4978:
4979:
4980: $this->_pos += 4 + $length;
4981:
4982:
4983: $offset = 0;
4984:
4985: if (!$this->_readDataOnly) {
4986: $offset += 12;
4987:
4988:
4989: $isf = self::_GetInt2d($recordData, 12);
4990: if ($isf != 2) {
4991:
4992: return;
4993: }
4994: $offset += 2;
4995:
4996: $offset += 5;
4997:
4998:
4999: $cref = self::_GetInt2d($recordData, 19);
5000: $offset += 2;
5001:
5002: $offset += 6;
5003:
5004:
5005: $cellRanges = array();
5006: for ($i = 0; $i < $cref; ++$i) {
5007: try {
5008: $cellRange = $this->_readBIFF8CellRangeAddressFixed(substr($recordData, 27 + 8 * $i, 8));
5009: } catch (PHPExcel_Exception $e) {
5010: return;
5011: }
5012: $cellRanges[] = $cellRange;
5013: $offset += 8;
5014: }
5015:
5016:
5017: $rgbFeat = substr($recordData, $offset);
5018: $offset += 4;
5019:
5020:
5021: $wPassword = self::_GetInt4d($recordData, $offset);
5022: $offset += 4;
5023:
5024:
5025: if ($cellRanges) {
5026: $this->_phpSheet->protectCells(implode(' ', $cellRanges), strtoupper(dechex($wPassword)), true);
5027: }
5028: }
5029: }
5030:
5031:
5032: 5033: 5034:
5035: private function _readImData()
5036: {
5037: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
5038:
5039:
5040: $splicedRecordData = $this->_getSplicedRecordData();
5041: $recordData = $splicedRecordData['recordData'];
5042:
5043:
5044:
5045:
5046: $cf = self::_GetInt2d($recordData, 0);
5047:
5048:
5049: $env = self::_GetInt2d($recordData, 2);
5050:
5051:
5052: $lcb = self::_GetInt4d($recordData, 4);
5053:
5054:
5055: $iData = substr($recordData, 8);
5056:
5057: switch ($cf) {
5058: case 0x09:
5059:
5060:
5061:
5062: $bcSize = self::_GetInt4d($iData, 0);
5063:
5064:
5065:
5066: $bcWidth = self::_GetInt2d($iData, 4);
5067:
5068:
5069:
5070: $bcHeight = self::_GetInt2d($iData, 6);
5071:
5072: $ih = imagecreatetruecolor($bcWidth, $bcHeight);
5073:
5074:
5075:
5076:
5077: $bcBitCount = self::_GetInt2d($iData, 10);
5078:
5079:
5080: $rgbString = substr($iData, 12);
5081: $rgbTriples = array();
5082: while (strlen($rgbString) > 0) {
5083: $rgbTriples[] = unpack('Cb/Cg/Cr', $rgbString);
5084: $rgbString = substr($rgbString, 3);
5085: }
5086: $x = 0;
5087: $y = 0;
5088: foreach ($rgbTriples as $i => $rgbTriple) {
5089: $color = imagecolorallocate($ih, $rgbTriple['r'], $rgbTriple['g'], $rgbTriple['b']);
5090: imagesetpixel($ih, $x, $bcHeight - 1 - $y, $color);
5091: $x = ($x + 1) % $bcWidth;
5092: $y = $y + floor(($x + 1) / $bcWidth);
5093: }
5094:
5095:
5096: $drawing = new PHPExcel_Worksheet_Drawing();
5097: $drawing->setPath($filename);
5098: $drawing->setWorksheet($this->_phpSheet);
5099:
5100: break;
5101:
5102: case 0x02:
5103: case 0x0e:
5104: default;
5105: break;
5106:
5107: }
5108:
5109:
5110: }
5111:
5112:
5113: 5114: 5115: 5116: 5117:
5118: private function _readContinue()
5119: {
5120: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
5121: $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);
5122:
5123:
5124:
5125: if ($this->_drawingData == '') {
5126:
5127: $this->_pos += 4 + $length;
5128:
5129: return;
5130: }
5131:
5132:
5133: if ($length < 4) {
5134:
5135: $this->_pos += 4 + $length;
5136:
5137: return;
5138: }
5139:
5140:
5141:
5142:
5143:
5144:
5145:
5146: $validSplitPoints = array(0xF003, 0xF004, 0xF00D);
5147:
5148: $splitPoint = self::_GetInt2d($recordData, 2);
5149: if (in_array($splitPoint, $validSplitPoints)) {
5150:
5151: $splicedRecordData = $this->_getSplicedRecordData();
5152: $this->_drawingData .= $splicedRecordData['recordData'];
5153:
5154: return;
5155: }
5156:
5157:
5158: $this->_pos += 4 + $length;
5159:
5160: }
5161:
5162:
5163: 5164: 5165: 5166: 5167: 5168: 5169: 5170:
5171: private function _getSplicedRecordData()
5172: {
5173: $data = '';
5174: $spliceOffsets = array();
5175:
5176: $i = 0;
5177: $spliceOffsets[0] = 0;
5178:
5179: do {
5180: ++$i;
5181:
5182:
5183: $identifier = self::_GetInt2d($this->_data, $this->_pos);
5184:
5185: $length = self::_GetInt2d($this->_data, $this->_pos + 2);
5186: $data .= $this->_readRecordData($this->_data, $this->_pos + 4, $length);
5187:
5188: $spliceOffsets[$i] = $spliceOffsets[$i - 1] + $length;
5189:
5190: $this->_pos += 4 + $length;
5191: $nextIdentifier = self::_GetInt2d($this->_data, $this->_pos);
5192: }
5193: while ($nextIdentifier == self::XLS_Type_CONTINUE);
5194:
5195: $splicedData = array(
5196: 'recordData' => $data,
5197: 'spliceOffsets' => $spliceOffsets,
5198: );
5199:
5200: return $splicedData;
5201:
5202: }
5203:
5204:
5205: 5206: 5207: 5208: 5209: 5210: 5211:
5212: private function _getFormulaFromStructure($formulaStructure, $baseCell = 'A1')
5213: {
5214:
5215: $sz = self::_GetInt2d($formulaStructure, 0);
5216:
5217:
5218: $formulaData = substr($formulaStructure, 2, $sz);
5219:
5220:
5221:
5222:
5223:
5224:
5225:
5226:
5227:
5228: if (strlen($formulaStructure) > 2 + $sz) {
5229: $additionalData = substr($formulaStructure, 2 + $sz);
5230:
5231:
5232:
5233:
5234:
5235:
5236: } else {
5237: $additionalData = '';
5238: }
5239:
5240: return $this->_getFormulaFromData($formulaData, $additionalData, $baseCell);
5241: }
5242:
5243:
5244: 5245: 5246: 5247: 5248: 5249: 5250: 5251:
5252: private function _getFormulaFromData($formulaData, $additionalData = '', $baseCell = 'A1')
5253: {
5254:
5255: $tokens = array();
5256:
5257: while (strlen($formulaData) > 0 and $token = $this->_getNextToken($formulaData, $baseCell)) {
5258: $tokens[] = $token;
5259: $formulaData = substr($formulaData, $token['size']);
5260:
5261:
5262:
5263: }
5264:
5265: $formulaString = $this->_createFormulaFromTokens($tokens, $additionalData);
5266:
5267: return $formulaString;
5268: }
5269:
5270:
5271: 5272: 5273: 5274: 5275: 5276: 5277: 5278:
5279: private function _createFormulaFromTokens($tokens, $additionalData)
5280: {
5281:
5282: if (empty($tokens)) {
5283: return '';
5284: }
5285:
5286: $formulaStrings = array();
5287: foreach ($tokens as $token) {
5288:
5289: $space0 = isset($space0) ? $space0 : '';
5290: $space1 = isset($space1) ? $space1 : '';
5291: $space2 = isset($space2) ? $space2 : '';
5292: $space3 = isset($space3) ? $space3 : '';
5293: $space4 = isset($space4) ? $space4 : '';
5294: $space5 = isset($space5) ? $space5 : '';
5295:
5296: switch ($token['name']) {
5297: case 'tAdd':
5298: case 'tConcat':
5299: case 'tDiv':
5300: case 'tEQ':
5301: case 'tGE':
5302: case 'tGT':
5303: case 'tIsect':
5304: case 'tLE':
5305: case 'tList':
5306: case 'tLT':
5307: case 'tMul':
5308: case 'tNE':
5309: case 'tPower':
5310: case 'tRange':
5311: case 'tSub':
5312: $op2 = array_pop($formulaStrings);
5313: $op1 = array_pop($formulaStrings);
5314: $formulaStrings[] = "$op1$space1$space0{$token['data']}$op2";
5315: unset($space0, $space1);
5316: break;
5317: case 'tUplus':
5318: case 'tUminus':
5319: $op = array_pop($formulaStrings);
5320: $formulaStrings[] = "$space1$space0{$token['data']}$op";
5321: unset($space0, $space1);
5322: break;
5323: case 'tPercent':
5324: $op = array_pop($formulaStrings);
5325: $formulaStrings[] = "$op$space1$space0{$token['data']}";
5326: unset($space0, $space1);
5327: break;
5328: case 'tAttrVolatile':
5329: case 'tAttrIf':
5330: case 'tAttrSkip':
5331: case 'tAttrChoose':
5332:
5333:
5334: break;
5335: case 'tAttrSpace':
5336:
5337: switch ($token['data']['spacetype']) {
5338: case 'type0':
5339: $space0 = str_repeat(' ', $token['data']['spacecount']);
5340: break;
5341: case 'type1':
5342: $space1 = str_repeat("\n", $token['data']['spacecount']);
5343: break;
5344: case 'type2':
5345: $space2 = str_repeat(' ', $token['data']['spacecount']);
5346: break;
5347: case 'type3':
5348: $space3 = str_repeat("\n", $token['data']['spacecount']);
5349: break;
5350: case 'type4':
5351: $space4 = str_repeat(' ', $token['data']['spacecount']);
5352: break;
5353: case 'type5':
5354: $space5 = str_repeat("\n", $token['data']['spacecount']);
5355: break;
5356: }
5357: break;
5358: case 'tAttrSum':
5359: $op = array_pop($formulaStrings);
5360: $formulaStrings[] = "{$space1}{$space0}SUM($op)";
5361: unset($space0, $space1);
5362: break;
5363: case 'tFunc':
5364: case 'tFuncV':
5365: if ($token['data']['function'] != '') {
5366:
5367: $ops = array();
5368: for ($i = 0; $i < $token['data']['args']; ++$i) {
5369: $ops[] = array_pop($formulaStrings);
5370: }
5371: $ops = array_reverse($ops);
5372: $formulaStrings[] = "$space1$space0{$token['data']['function']}(" . implode(',', $ops) . ")";
5373: unset($space0, $space1);
5374: } else {
5375:
5376: $ops = array();
5377: for ($i = 0; $i < $token['data']['args'] - 1; ++$i) {
5378: $ops[] = array_pop($formulaStrings);
5379: }
5380: $ops = array_reverse($ops);
5381: $function = array_pop($formulaStrings);
5382: $formulaStrings[] = "$space1$space0$function(" . implode(',', $ops) . ")";
5383: unset($space0, $space1);
5384: }
5385: break;
5386: case 'tParen':
5387: $expression = array_pop($formulaStrings);
5388: $formulaStrings[] = "$space3$space2($expression$space5$space4)";
5389: unset($space2, $space3, $space4, $space5);
5390: break;
5391: case 'tArray':
5392: $constantArray = self::_readBIFF8ConstantArray($additionalData);
5393: $formulaStrings[] = $space1 . $space0 . $constantArray['value'];
5394: $additionalData = substr($additionalData, $constantArray['size']);
5395: unset($space0, $space1);
5396: break;
5397: case 'tMemArea':
5398:
5399: $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($additionalData);
5400: $additionalData = substr($additionalData, $cellRangeAddressList['size']);
5401: $formulaStrings[] = "$space1$space0{$token['data']}";
5402: unset($space0, $space1);
5403: break;
5404: case 'tArea':
5405: case 'tBool':
5406: case 'tErr':
5407: case 'tInt':
5408: case 'tMemErr':
5409: case 'tMemFunc':
5410: case 'tMissArg':
5411: case 'tName':
5412: case 'tNameX':
5413: case 'tNum':
5414: case 'tRef':
5415: case 'tRef3d':
5416: case 'tArea3d':
5417: case 'tRefN':
5418: case 'tAreaN':
5419: case 'tStr':
5420: $formulaStrings[] = "$space1$space0{$token['data']}";
5421: unset($space0, $space1);
5422: break;
5423: }
5424: }
5425: $formulaString = $formulaStrings[0];
5426:
5427:
5428:
5429:
5430:
5431: return $formulaString;
5432: }
5433:
5434:
5435: 5436: 5437: 5438: 5439: 5440: 5441: 5442:
5443: private function _getNextToken($formulaData, $baseCell = 'A1')
5444: {
5445:
5446: $id = ord($formulaData[0]);
5447: $name = false;
5448:
5449: switch ($id) {
5450: case 0x03: $name = 'tAdd'; $size = 1; $data = '+'; break;
5451: case 0x04: $name = 'tSub'; $size = 1; $data = '-'; break;
5452: case 0x05: $name = 'tMul'; $size = 1; $data = '*'; break;
5453: case 0x06: $name = 'tDiv'; $size = 1; $data = '/'; break;
5454: case 0x07: $name = 'tPower'; $size = 1; $data = '^'; break;
5455: case 0x08: $name = 'tConcat'; $size = 1; $data = '&'; break;
5456: case 0x09: $name = 'tLT'; $size = 1; $data = '<'; break;
5457: case 0x0A: $name = 'tLE'; $size = 1; $data = '<='; break;
5458: case 0x0B: $name = 'tEQ'; $size = 1; $data = '='; break;
5459: case 0x0C: $name = 'tGE'; $size = 1; $data = '>='; break;
5460: case 0x0D: $name = 'tGT'; $size = 1; $data = '>'; break;
5461: case 0x0E: $name = 'tNE'; $size = 1; $data = '<>'; break;
5462: case 0x0F: $name = 'tIsect'; $size = 1; $data = ' '; break;
5463: case 0x10: $name = 'tList'; $size = 1; $data = ','; break;
5464: case 0x11: $name = 'tRange'; $size = 1; $data = ':'; break;
5465: case 0x12: $name = 'tUplus'; $size = 1; $data = '+'; break;
5466: case 0x13: $name = 'tUminus'; $size = 1; $data = '-'; break;
5467: case 0x14: $name = 'tPercent'; $size = 1; $data = '%'; break;
5468: case 0x15:
5469: $name = 'tParen';
5470: $size = 1;
5471: $data = null;
5472: break;
5473: case 0x16:
5474: $name = 'tMissArg';
5475: $size = 1;
5476: $data = '';
5477: break;
5478: case 0x17:
5479: $name = 'tStr';
5480:
5481: $string = self::_readUnicodeStringShort(substr($formulaData, 1));
5482: $size = 1 + $string['size'];
5483: $data = self::_UTF8toExcelDoubleQuoted($string['value']);
5484: break;
5485: case 0x19:
5486:
5487: switch (ord($formulaData[1])) {
5488: case 0x01:
5489: $name = 'tAttrVolatile';
5490: $size = 4;
5491: $data = null;
5492: break;
5493: case 0x02:
5494: $name = 'tAttrIf';
5495: $size = 4;
5496: $data = null;
5497: break;
5498: case 0x04:
5499: $name = 'tAttrChoose';
5500:
5501: $nc = self::_GetInt2d($formulaData, 2);
5502:
5503:
5504: $size = 2 * $nc + 6;
5505: $data = null;
5506: break;
5507: case 0x08:
5508: $name = 'tAttrSkip';
5509: $size = 4;
5510: $data = null;
5511: break;
5512: case 0x10:
5513: $name = 'tAttrSum';
5514: $size = 4;
5515: $data = null;
5516: break;
5517: case 0x40:
5518: case 0x41:
5519: $name = 'tAttrSpace';
5520: $size = 4;
5521:
5522: switch (ord($formulaData[2])) {
5523: case 0x00:
5524: $spacetype = 'type0';
5525: break;
5526: case 0x01:
5527: $spacetype = 'type1';
5528: break;
5529: case 0x02:
5530: $spacetype = 'type2';
5531: break;
5532: case 0x03:
5533: $spacetype = 'type3';
5534: break;
5535: case 0x04:
5536: $spacetype = 'type4';
5537: break;
5538: case 0x05:
5539: $spacetype = 'type5';
5540: break;
5541: default:
5542: throw new PHPExcel_Reader_Exception('Unrecognized space type in tAttrSpace token');
5543: break;
5544: }
5545:
5546: $spacecount = ord($formulaData[3]);
5547:
5548: $data = array('spacetype' => $spacetype, 'spacecount' => $spacecount);
5549: break;
5550: default:
5551: throw new PHPExcel_Reader_Exception('Unrecognized attribute flag in tAttr token');
5552: break;
5553: }
5554: break;
5555: case 0x1C:
5556:
5557: $name = 'tErr';
5558: $size = 2;
5559: $data = self::_mapErrorCode(ord($formulaData[1]));
5560: break;
5561: case 0x1D:
5562:
5563: $name = 'tBool';
5564: $size = 2;
5565: $data = ord($formulaData[1]) ? 'TRUE' : 'FALSE';
5566: break;
5567: case 0x1E:
5568:
5569: $name = 'tInt';
5570: $size = 3;
5571: $data = self::_GetInt2d($formulaData, 1);
5572: break;
5573: case 0x1F:
5574:
5575: $name = 'tNum';
5576: $size = 9;
5577: $data = self::_extractNumber(substr($formulaData, 1));
5578: $data = str_replace(',', '.', (string)$data);
5579: break;
5580: case 0x20:
5581: case 0x40:
5582: case 0x60:
5583:
5584: $name = 'tArray';
5585: $size = 8;
5586: $data = null;
5587: break;
5588: case 0x21:
5589: case 0x41:
5590: case 0x61:
5591: $name = 'tFunc';
5592: $size = 3;
5593:
5594: switch (self::_GetInt2d($formulaData, 1)) {
5595: case 2: $function = 'ISNA'; $args = 1; break;
5596: case 3: $function = 'ISERROR'; $args = 1; break;
5597: case 10: $function = 'NA'; $args = 0; break;
5598: case 15: $function = 'SIN'; $args = 1; break;
5599: case 16: $function = 'COS'; $args = 1; break;
5600: case 17: $function = 'TAN'; $args = 1; break;
5601: case 18: $function = 'ATAN'; $args = 1; break;
5602: case 19: $function = 'PI'; $args = 0; break;
5603: case 20: $function = 'SQRT'; $args = 1; break;
5604: case 21: $function = 'EXP'; $args = 1; break;
5605: case 22: $function = 'LN'; $args = 1; break;
5606: case 23: $function = 'LOG10'; $args = 1; break;
5607: case 24: $function = 'ABS'; $args = 1; break;
5608: case 25: $function = 'INT'; $args = 1; break;
5609: case 26: $function = 'SIGN'; $args = 1; break;
5610: case 27: $function = 'ROUND'; $args = 2; break;
5611: case 30: $function = 'REPT'; $args = 2; break;
5612: case 31: $function = 'MID'; $args = 3; break;
5613: case 32: $function = 'LEN'; $args = 1; break;
5614: case 33: $function = 'VALUE'; $args = 1; break;
5615: case 34: $function = 'TRUE'; $args = 0; break;
5616: case 35: $function = 'FALSE'; $args = 0; break;
5617: case 38: $function = 'NOT'; $args = 1; break;
5618: case 39: $function = 'MOD'; $args = 2; break;
5619: case 40: $function = 'DCOUNT'; $args = 3; break;
5620: case 41: $function = 'DSUM'; $args = 3; break;
5621: case 42: $function = 'DAVERAGE'; $args = 3; break;
5622: case 43: $function = 'DMIN'; $args = 3; break;
5623: case 44: $function = 'DMAX'; $args = 3; break;
5624: case 45: $function = 'DSTDEV'; $args = 3; break;
5625: case 48: $function = 'TEXT'; $args = 2; break;
5626: case 61: $function = 'MIRR'; $args = 3; break;
5627: case 63: $function = 'RAND'; $args = 0; break;
5628: case 65: $function = 'DATE'; $args = 3; break;
5629: case 66: $function = 'TIME'; $args = 3; break;
5630: case 67: $function = 'DAY'; $args = 1; break;
5631: case 68: $function = 'MONTH'; $args = 1; break;
5632: case 69: $function = 'YEAR'; $args = 1; break;
5633: case 71: $function = 'HOUR'; $args = 1; break;
5634: case 72: $function = 'MINUTE'; $args = 1; break;
5635: case 73: $function = 'SECOND'; $args = 1; break;
5636: case 74: $function = 'NOW'; $args = 0; break;
5637: case 75: $function = 'AREAS'; $args = 1; break;
5638: case 76: $function = 'ROWS'; $args = 1; break;
5639: case 77: $function = 'COLUMNS'; $args = 1; break;
5640: case 83: $function = 'TRANSPOSE'; $args = 1; break;
5641: case 86: $function = 'TYPE'; $args = 1; break;
5642: case 97: $function = 'ATAN2'; $args = 2; break;
5643: case 98: $function = 'ASIN'; $args = 1; break;
5644: case 99: $function = 'ACOS'; $args = 1; break;
5645: case 105: $function = 'ISREF'; $args = 1; break;
5646: case 111: $function = 'CHAR'; $args = 1; break;
5647: case 112: $function = 'LOWER'; $args = 1; break;
5648: case 113: $function = 'UPPER'; $args = 1; break;
5649: case 114: $function = 'PROPER'; $args = 1; break;
5650: case 117: $function = 'EXACT'; $args = 2; break;
5651: case 118: $function = 'TRIM'; $args = 1; break;
5652: case 119: $function = 'REPLACE'; $args = 4; break;
5653: case 121: $function = 'CODE'; $args = 1; break;
5654: case 126: $function = 'ISERR'; $args = 1; break;
5655: case 127: $function = 'ISTEXT'; $args = 1; break;
5656: case 128: $function = 'ISNUMBER'; $args = 1; break;
5657: case 129: $function = 'ISBLANK'; $args = 1; break;
5658: case 130: $function = 'T'; $args = 1; break;
5659: case 131: $function = 'N'; $args = 1; break;
5660: case 140: $function = 'DATEVALUE'; $args = 1; break;
5661: case 141: $function = 'TIMEVALUE'; $args = 1; break;
5662: case 142: $function = 'SLN'; $args = 3; break;
5663: case 143: $function = 'SYD'; $args = 4; break;
5664: case 162: $function = 'CLEAN'; $args = 1; break;
5665: case 163: $function = 'MDETERM'; $args = 1; break;
5666: case 164: $function = 'MINVERSE'; $args = 1; break;
5667: case 165: $function = 'MMULT'; $args = 2; break;
5668: case 184: $function = 'FACT'; $args = 1; break;
5669: case 189: $function = 'DPRODUCT'; $args = 3; break;
5670: case 190: $function = 'ISNONTEXT'; $args = 1; break;
5671: case 195: $function = 'DSTDEVP'; $args = 3; break;
5672: case 196: $function = 'DVARP'; $args = 3; break;
5673: case 198: $function = 'ISLOGICAL'; $args = 1; break;
5674: case 199: $function = 'DCOUNTA'; $args = 3; break;
5675: case 207: $function = 'REPLACEB'; $args = 4; break;
5676: case 210: $function = 'MIDB'; $args = 3; break;
5677: case 211: $function = 'LENB'; $args = 1; break;
5678: case 212: $function = 'ROUNDUP'; $args = 2; break;
5679: case 213: $function = 'ROUNDDOWN'; $args = 2; break;
5680: case 214: $function = 'ASC'; $args = 1; break;
5681: case 215: $function = 'DBCS'; $args = 1; break;
5682: case 221: $function = 'TODAY'; $args = 0; break;
5683: case 229: $function = 'SINH'; $args = 1; break;
5684: case 230: $function = 'COSH'; $args = 1; break;
5685: case 231: $function = 'TANH'; $args = 1; break;
5686: case 232: $function = 'ASINH'; $args = 1; break;
5687: case 233: $function = 'ACOSH'; $args = 1; break;
5688: case 234: $function = 'ATANH'; $args = 1; break;
5689: case 235: $function = 'DGET'; $args = 3; break;
5690: case 244: $function = 'INFO'; $args = 1; break;
5691: case 252: $function = 'FREQUENCY'; $args = 2; break;
5692: case 261: $function = 'ERROR.TYPE'; $args = 1; break;
5693: case 271: $function = 'GAMMALN'; $args = 1; break;
5694: case 273: $function = 'BINOMDIST'; $args = 4; break;
5695: case 274: $function = 'CHIDIST'; $args = 2; break;
5696: case 275: $function = 'CHIINV'; $args = 2; break;
5697: case 276: $function = 'COMBIN'; $args = 2; break;
5698: case 277: $function = 'CONFIDENCE'; $args = 3; break;
5699: case 278: $function = 'CRITBINOM'; $args = 3; break;
5700: case 279: $function = 'EVEN'; $args = 1; break;
5701: case 280: $function = 'EXPONDIST'; $args = 3; break;
5702: case 281: $function = 'FDIST'; $args = 3; break;
5703: case 282: $function = 'FINV'; $args = 3; break;
5704: case 283: $function = 'FISHER'; $args = 1; break;
5705: case 284: $function = 'FISHERINV'; $args = 1; break;
5706: case 285: $function = 'FLOOR'; $args = 2; break;
5707: case 286: $function = 'GAMMADIST'; $args = 4; break;
5708: case 287: $function = 'GAMMAINV'; $args = 3; break;
5709: case 288: $function = 'CEILING'; $args = 2; break;
5710: case 289: $function = 'HYPGEOMDIST'; $args = 4; break;
5711: case 290: $function = 'LOGNORMDIST'; $args = 3; break;
5712: case 291: $function = 'LOGINV'; $args = 3; break;
5713: case 292: $function = 'NEGBINOMDIST'; $args = 3; break;
5714: case 293: $function = 'NORMDIST'; $args = 4; break;
5715: case 294: $function = 'NORMSDIST'; $args = 1; break;
5716: case 295: $function = 'NORMINV'; $args = 3; break;
5717: case 296: $function = 'NORMSINV'; $args = 1; break;
5718: case 297: $function = 'STANDARDIZE'; $args = 3; break;
5719: case 298: $function = 'ODD'; $args = 1; break;
5720: case 299: $function = 'PERMUT'; $args = 2; break;
5721: case 300: $function = 'POISSON'; $args = 3; break;
5722: case 301: $function = 'TDIST'; $args = 3; break;
5723: case 302: $function = 'WEIBULL'; $args = 4; break;
5724: case 303: $function = 'SUMXMY2'; $args = 2; break;
5725: case 304: $function = 'SUMX2MY2'; $args = 2; break;
5726: case 305: $function = 'SUMX2PY2'; $args = 2; break;
5727: case 306: $function = 'CHITEST'; $args = 2; break;
5728: case 307: $function = 'CORREL'; $args = 2; break;
5729: case 308: $function = 'COVAR'; $args = 2; break;
5730: case 309: $function = 'FORECAST'; $args = 3; break;
5731: case 310: $function = 'FTEST'; $args = 2; break;
5732: case 311: $function = 'INTERCEPT'; $args = 2; break;
5733: case 312: $function = 'PEARSON'; $args = 2; break;
5734: case 313: $function = 'RSQ'; $args = 2; break;
5735: case 314: $function = 'STEYX'; $args = 2; break;
5736: case 315: $function = 'SLOPE'; $args = 2; break;
5737: case 316: $function = 'TTEST'; $args = 4; break;
5738: case 325: $function = 'LARGE'; $args = 2; break;
5739: case 326: $function = 'SMALL'; $args = 2; break;
5740: case 327: $function = 'QUARTILE'; $args = 2; break;
5741: case 328: $function = 'PERCENTILE'; $args = 2; break;
5742: case 331: $function = 'TRIMMEAN'; $args = 2; break;
5743: case 332: $function = 'TINV'; $args = 2; break;
5744: case 337: $function = 'POWER'; $args = 2; break;
5745: case 342: $function = 'RADIANS'; $args = 1; break;
5746: case 343: $function = 'DEGREES'; $args = 1; break;
5747: case 346: $function = 'COUNTIF'; $args = 2; break;
5748: case 347: $function = 'COUNTBLANK'; $args = 1; break;
5749: case 350: $function = 'ISPMT'; $args = 4; break;
5750: case 351: $function = 'DATEDIF'; $args = 3; break;
5751: case 352: $function = 'DATESTRING'; $args = 1; break;
5752: case 353: $function = 'NUMBERSTRING'; $args = 2; break;
5753: case 360: $function = 'PHONETIC'; $args = 1; break;
5754: case 368: $function = 'BAHTTEXT'; $args = 1; break;
5755: default:
5756: throw new PHPExcel_Reader_Exception('Unrecognized function in formula');
5757: break;
5758: }
5759: $data = array('function' => $function, 'args' => $args);
5760: break;
5761: case 0x22:
5762: case 0x42:
5763: case 0x62:
5764: $name = 'tFuncV';
5765: $size = 4;
5766:
5767: $args = ord($formulaData[1]);
5768:
5769: $index = self::_GetInt2d($formulaData, 2);
5770: switch ($index) {
5771: case 0: $function = 'COUNT'; break;
5772: case 1: $function = 'IF'; break;
5773: case 4: $function = 'SUM'; break;
5774: case 5: $function = 'AVERAGE'; break;
5775: case 6: $function = 'MIN'; break;
5776: case 7: $function = 'MAX'; break;
5777: case 8: $function = 'ROW'; break;
5778: case 9: $function = 'COLUMN'; break;
5779: case 11: $function = 'NPV'; break;
5780: case 12: $function = 'STDEV'; break;
5781: case 13: $function = 'DOLLAR'; break;
5782: case 14: $function = 'FIXED'; break;
5783: case 28: $function = 'LOOKUP'; break;
5784: case 29: $function = 'INDEX'; break;
5785: case 36: $function = 'AND'; break;
5786: case 37: $function = 'OR'; break;
5787: case 46: $function = 'VAR'; break;
5788: case 49: $function = 'LINEST'; break;
5789: case 50: $function = 'TREND'; break;
5790: case 51: $function = 'LOGEST'; break;
5791: case 52: $function = 'GROWTH'; break;
5792: case 56: $function = 'PV'; break;
5793: case 57: $function = 'FV'; break;
5794: case 58: $function = 'NPER'; break;
5795: case 59: $function = 'PMT'; break;
5796: case 60: $function = 'RATE'; break;
5797: case 62: $function = 'IRR'; break;
5798: case 64: $function = 'MATCH'; break;
5799: case 70: $function = 'WEEKDAY'; break;
5800: case 78: $function = 'OFFSET'; break;
5801: case 82: $function = 'SEARCH'; break;
5802: case 100: $function = 'CHOOSE'; break;
5803: case 101: $function = 'HLOOKUP'; break;
5804: case 102: $function = 'VLOOKUP'; break;
5805: case 109: $function = 'LOG'; break;
5806: case 115: $function = 'LEFT'; break;
5807: case 116: $function = 'RIGHT'; break;
5808: case 120: $function = 'SUBSTITUTE'; break;
5809: case 124: $function = 'FIND'; break;
5810: case 125: $function = 'CELL'; break;
5811: case 144: $function = 'DDB'; break;
5812: case 148: $function = 'INDIRECT'; break;
5813: case 167: $function = 'IPMT'; break;
5814: case 168: $function = 'PPMT'; break;
5815: case 169: $function = 'COUNTA'; break;
5816: case 183: $function = 'PRODUCT'; break;
5817: case 193: $function = 'STDEVP'; break;
5818: case 194: $function = 'VARP'; break;
5819: case 197: $function = 'TRUNC'; break;
5820: case 204: $function = 'USDOLLAR'; break;
5821: case 205: $function = 'FINDB'; break;
5822: case 206: $function = 'SEARCHB'; break;
5823: case 208: $function = 'LEFTB'; break;
5824: case 209: $function = 'RIGHTB'; break;
5825: case 216: $function = 'RANK'; break;
5826: case 219: $function = 'ADDRESS'; break;
5827: case 220: $function = 'DAYS360'; break;
5828: case 222: $function = 'VDB'; break;
5829: case 227: $function = 'MEDIAN'; break;
5830: case 228: $function = 'SUMPRODUCT'; break;
5831: case 247: $function = 'DB'; break;
5832: case 255: $function = ''; break;
5833: case 269: $function = 'AVEDEV'; break;
5834: case 270: $function = 'BETADIST'; break;
5835: case 272: $function = 'BETAINV'; break;
5836: case 317: $function = 'PROB'; break;
5837: case 318: $function = 'DEVSQ'; break;
5838: case 319: $function = 'GEOMEAN'; break;
5839: case 320: $function = 'HARMEAN'; break;
5840: case 321: $function = 'SUMSQ'; break;
5841: case 322: $function = 'KURT'; break;
5842: case 323: $function = 'SKEW'; break;
5843: case 324: $function = 'ZTEST'; break;
5844: case 329: $function = 'PERCENTRANK'; break;
5845: case 330: $function = 'MODE'; break;
5846: case 336: $function = 'CONCATENATE'; break;
5847: case 344: $function = 'SUBTOTAL'; break;
5848: case 345: $function = 'SUMIF'; break;
5849: case 354: $function = 'ROMAN'; break;
5850: case 358: $function = 'GETPIVOTDATA'; break;
5851: case 359: $function = 'HYPERLINK'; break;
5852: case 361: $function = 'AVERAGEA'; break;
5853: case 362: $function = 'MAXA'; break;
5854: case 363: $function = 'MINA'; break;
5855: case 364: $function = 'STDEVPA'; break;
5856: case 365: $function = 'VARPA'; break;
5857: case 366: $function = 'STDEVA'; break;
5858: case 367: $function = 'VARA'; break;
5859: default:
5860: throw new PHPExcel_Reader_Exception('Unrecognized function in formula');
5861: break;
5862: }
5863: $data = array('function' => $function, 'args' => $args);
5864: break;
5865: case 0x23:
5866: case 0x43:
5867: case 0x63:
5868: $name = 'tName';
5869: $size = 5;
5870:
5871: $definedNameIndex = self::_GetInt2d($formulaData, 1) - 1;
5872:
5873: $data = $this->_definedname[$definedNameIndex]['name'];
5874: break;
5875: case 0x24:
5876: case 0x44:
5877: case 0x64:
5878: $name = 'tRef';
5879: $size = 5;
5880: $data = $this->_readBIFF8CellAddress(substr($formulaData, 1, 4));
5881: break;
5882: case 0x25:
5883: case 0x45:
5884: case 0x65:
5885: $name = 'tArea';
5886: $size = 9;
5887: $data = $this->_readBIFF8CellRangeAddress(substr($formulaData, 1, 8));
5888: break;
5889: case 0x26:
5890: case 0x46:
5891: case 0x66:
5892: $name = 'tMemArea';
5893:
5894:
5895: $subSize = self::_GetInt2d($formulaData, 5);
5896: $size = 7 + $subSize;
5897: $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize));
5898: break;
5899: case 0x27:
5900: case 0x47:
5901: case 0x67:
5902: $name = 'tMemErr';
5903:
5904:
5905: $subSize = self::_GetInt2d($formulaData, 5);
5906: $size = 7 + $subSize;
5907: $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize));
5908: break;
5909: case 0x29:
5910: case 0x49:
5911: case 0x69:
5912: $name = 'tMemFunc';
5913:
5914: $subSize = self::_GetInt2d($formulaData, 1);
5915: $size = 3 + $subSize;
5916: $data = $this->_getFormulaFromData(substr($formulaData, 3, $subSize));
5917: break;
5918:
5919: case 0x2C:
5920: case 0x4C:
5921: case 0x6C:
5922: $name = 'tRefN';
5923: $size = 5;
5924: $data = $this->_readBIFF8CellAddressB(substr($formulaData, 1, 4), $baseCell);
5925: break;
5926:
5927: case 0x2D:
5928: case 0x4D:
5929: case 0x6D:
5930: $name = 'tAreaN';
5931: $size = 9;
5932: $data = $this->_readBIFF8CellRangeAddressB(substr($formulaData, 1, 8), $baseCell);
5933: break;
5934:
5935: case 0x39:
5936: case 0x59:
5937: case 0x79:
5938: $name = 'tNameX';
5939: $size = 7;
5940:
5941:
5942: $index = self::_GetInt2d($formulaData, 3);
5943:
5944: $data = $this->_externalNames[$index - 1]['name'];
5945:
5946: break;
5947:
5948: case 0x3A:
5949: case 0x5A:
5950: case 0x7A:
5951: $name = 'tRef3d';
5952: $size = 7;
5953:
5954: try {
5955:
5956: $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1));
5957:
5958: $cellAddress = $this->_readBIFF8CellAddress(substr($formulaData, 3, 4));
5959:
5960: $data = "$sheetRange!$cellAddress";
5961: } catch (PHPExcel_Exception $e) {
5962:
5963: $data = '#REF!';
5964: }
5965:
5966: break;
5967: case 0x3B:
5968: case 0x5B:
5969: case 0x7B:
5970: $name = 'tArea3d';
5971: $size = 11;
5972:
5973: try {
5974:
5975: $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1));
5976:
5977: $cellRangeAddress = $this->_readBIFF8CellRangeAddress(substr($formulaData, 3, 8));
5978:
5979: $data = "$sheetRange!$cellRangeAddress";
5980: } catch (PHPExcel_Exception $e) {
5981:
5982: $data = '#REF!';
5983: }
5984:
5985: break;
5986:
5987: default:
5988: throw new PHPExcel_Reader_Exception('Unrecognized token ' . sprintf('%02X', $id) . ' in formula');
5989: break;
5990: }
5991:
5992: return array(
5993: 'id' => $id,
5994: 'name' => $name,
5995: 'size' => $size,
5996: 'data' => $data,
5997: );
5998: }
5999:
6000:
6001: 6002: 6003: 6004: 6005: 6006: 6007:
6008: private function _readBIFF8CellAddress($cellAddressStructure)
6009: {
6010:
6011: $row = self::_GetInt2d($cellAddressStructure, 0) + 1;
6012:
6013:
6014:
6015:
6016: $column = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($cellAddressStructure, 2));
6017:
6018:
6019: if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) {
6020: $column = '$' . $column;
6021: }
6022:
6023: if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) {
6024: $row = '$' . $row;
6025: }
6026:
6027: return $column . $row;
6028: }
6029:
6030:
6031: 6032: 6033: 6034: 6035: 6036: 6037: 6038: 6039:
6040: private function _readBIFF8CellAddressB($cellAddressStructure, $baseCell = 'A1')
6041: {
6042: list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell);
6043: $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1;
6044:
6045:
6046: $rowIndex = self::_GetInt2d($cellAddressStructure, 0);
6047: $row = self::_GetInt2d($cellAddressStructure, 0) + 1;
6048:
6049:
6050:
6051:
6052: $colIndex = 0x00FF & self::_GetInt2d($cellAddressStructure, 2);
6053:
6054:
6055: if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) {
6056: $column = PHPExcel_Cell::stringFromColumnIndex($colIndex);
6057: $column = '$' . $column;
6058: } else {
6059: $colIndex = ($colIndex <= 127) ? $colIndex : $colIndex - 256;
6060: $column = PHPExcel_Cell::stringFromColumnIndex($baseCol + $colIndex);
6061: }
6062:
6063:
6064: if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) {
6065: $row = '$' . $row;
6066: } else {
6067: $rowIndex = ($rowIndex <= 32767) ? $rowIndex : $rowIndex - 65536;
6068: $row = $baseRow + $rowIndex;
6069: }
6070:
6071: return $column . $row;
6072: }
6073:
6074:
6075: 6076: 6077: 6078: 6079: 6080: 6081: 6082: 6083:
6084: private function _readBIFF5CellRangeAddressFixed($subData)
6085: {
6086:
6087: $fr = self::_GetInt2d($subData, 0) + 1;
6088:
6089:
6090: $lr = self::_GetInt2d($subData, 2) + 1;
6091:
6092:
6093: $fc = ord($subData{4});
6094:
6095:
6096: $lc = ord($subData{5});
6097:
6098:
6099: if ($fr > $lr || $fc > $lc) {
6100: throw new PHPExcel_Reader_Exception('Not a cell range address');
6101: }
6102:
6103:
6104: $fc = PHPExcel_Cell::stringFromColumnIndex($fc);
6105: $lc = PHPExcel_Cell::stringFromColumnIndex($lc);
6106:
6107: if ($fr == $lr and $fc == $lc) {
6108: return "$fc$fr";
6109: }
6110: return "$fc$fr:$lc$lr";
6111: }
6112:
6113:
6114: 6115: 6116: 6117: 6118: 6119: 6120: 6121: 6122:
6123: private function _readBIFF8CellRangeAddressFixed($subData)
6124: {
6125:
6126: $fr = self::_GetInt2d($subData, 0) + 1;
6127:
6128:
6129: $lr = self::_GetInt2d($subData, 2) + 1;
6130:
6131:
6132: $fc = self::_GetInt2d($subData, 4);
6133:
6134:
6135: $lc = self::_GetInt2d($subData, 6);
6136:
6137:
6138: if ($fr > $lr || $fc > $lc) {
6139: throw new PHPExcel_Reader_Exception('Not a cell range address');
6140: }
6141:
6142:
6143: $fc = PHPExcel_Cell::stringFromColumnIndex($fc);
6144: $lc = PHPExcel_Cell::stringFromColumnIndex($lc);
6145:
6146: if ($fr == $lr and $fc == $lc) {
6147: return "$fc$fr";
6148: }
6149: return "$fc$fr:$lc$lr";
6150: }
6151:
6152:
6153: 6154: 6155: 6156: 6157: 6158: 6159: 6160:
6161: private function _readBIFF8CellRangeAddress($subData)
6162: {
6163:
6164:
6165:
6166:
6167: $fr = self::_GetInt2d($subData, 0) + 1;
6168:
6169:
6170: $lr = self::_GetInt2d($subData, 2) + 1;
6171:
6172:
6173:
6174:
6175: $fc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 4));
6176:
6177:
6178: if (!(0x4000 & self::_GetInt2d($subData, 4))) {
6179: $fc = '$' . $fc;
6180: }
6181:
6182:
6183: if (!(0x8000 & self::_GetInt2d($subData, 4))) {
6184: $fr = '$' . $fr;
6185: }
6186:
6187:
6188:
6189:
6190: $lc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 6));
6191:
6192:
6193: if (!(0x4000 & self::_GetInt2d($subData, 6))) {
6194: $lc = '$' . $lc;
6195: }
6196:
6197:
6198: if (!(0x8000 & self::_GetInt2d($subData, 6))) {
6199: $lr = '$' . $lr;
6200: }
6201:
6202: return "$fc$fr:$lc$lr";
6203: }
6204:
6205:
6206: 6207: 6208: 6209: 6210: 6211: 6212: 6213: 6214:
6215: private function _readBIFF8CellRangeAddressB($subData, $baseCell = 'A1')
6216: {
6217: list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell);
6218: $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1;
6219:
6220:
6221:
6222:
6223:
6224: $frIndex = self::_GetInt2d($subData, 0);
6225:
6226:
6227: $lrIndex = self::_GetInt2d($subData, 2);
6228:
6229:
6230:
6231:
6232: $fcIndex = 0x00FF & self::_GetInt2d($subData, 4);
6233:
6234:
6235: if (!(0x4000 & self::_GetInt2d($subData, 4))) {
6236:
6237: $fc = PHPExcel_Cell::stringFromColumnIndex($fcIndex);
6238: $fc = '$' . $fc;
6239: } else {
6240:
6241: $fcIndex = ($fcIndex <= 127) ? $fcIndex : $fcIndex - 256;
6242: $fc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $fcIndex);
6243: }
6244:
6245:
6246: if (!(0x8000 & self::_GetInt2d($subData, 4))) {
6247:
6248: $fr = $frIndex + 1;
6249: $fr = '$' . $fr;
6250: } else {
6251:
6252: $frIndex = ($frIndex <= 32767) ? $frIndex : $frIndex - 65536;
6253: $fr = $baseRow + $frIndex;
6254: }
6255:
6256:
6257:
6258:
6259: $lcIndex = 0x00FF & self::_GetInt2d($subData, 6);
6260: $lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256;
6261: $lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex);
6262:
6263:
6264: if (!(0x4000 & self::_GetInt2d($subData, 6))) {
6265:
6266: $lc = PHPExcel_Cell::stringFromColumnIndex($lcIndex);
6267: $lc = '$' . $lc;
6268: } else {
6269:
6270: $lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256;
6271: $lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex);
6272: }
6273:
6274:
6275: if (!(0x8000 & self::_GetInt2d($subData, 6))) {
6276:
6277: $lr = $lrIndex + 1;
6278: $lr = '$' . $lr;
6279: } else {
6280:
6281: $lrIndex = ($lrIndex <= 32767) ? $lrIndex : $lrIndex - 65536;
6282: $lr = $baseRow + $lrIndex;
6283: }
6284:
6285: return "$fc$fr:$lc$lr";
6286: }
6287:
6288:
6289: 6290: 6291: 6292: 6293: 6294: 6295:
6296: private function _readBIFF8CellRangeAddressList($subData)
6297: {
6298: $cellRangeAddresses = array();
6299:
6300:
6301: $nm = self::_GetInt2d($subData, 0);
6302:
6303: $offset = 2;
6304:
6305: for ($i = 0; $i < $nm; ++$i) {
6306: $cellRangeAddresses[] = $this->_readBIFF8CellRangeAddressFixed(substr($subData, $offset, 8));
6307: $offset += 8;
6308: }
6309:
6310: return array(
6311: 'size' => 2 + 8 * $nm,
6312: 'cellRangeAddresses' => $cellRangeAddresses,
6313: );
6314: }
6315:
6316:
6317: 6318: 6319: 6320: 6321: 6322: 6323:
6324: private function _readBIFF5CellRangeAddressList($subData)
6325: {
6326: $cellRangeAddresses = array();
6327:
6328:
6329: $nm = self::_GetInt2d($subData, 0);
6330:
6331: $offset = 2;
6332:
6333: for ($i = 0; $i < $nm; ++$i) {
6334: $cellRangeAddresses[] = $this->_readBIFF5CellRangeAddressFixed(substr($subData, $offset, 6));
6335: $offset += 6;
6336: }
6337:
6338: return array(
6339: 'size' => 2 + 6 * $nm,
6340: 'cellRangeAddresses' => $cellRangeAddresses,
6341: );
6342: }
6343:
6344:
6345: 6346: 6347: 6348: 6349: 6350: 6351: 6352: 6353: 6354:
6355: private function _readSheetRangeByRefIndex($index)
6356: {
6357: if (isset($this->_ref[$index])) {
6358:
6359: $type = $this->_externalBooks[$this->_ref[$index]['externalBookIndex']]['type'];
6360:
6361: switch ($type) {
6362: case 'internal':
6363:
6364: if ($this->_ref[$index]['firstSheetIndex'] == 0xFFFF or $this->_ref[$index]['lastSheetIndex'] == 0xFFFF) {
6365: throw new PHPExcel_Reader_Exception('Deleted sheet reference');
6366: }
6367:
6368:
6369: $firstSheetName = $this->_sheets[$this->_ref[$index]['firstSheetIndex']]['name'];
6370: $lastSheetName = $this->_sheets[$this->_ref[$index]['lastSheetIndex']]['name'];
6371:
6372: if ($firstSheetName == $lastSheetName) {
6373:
6374: $sheetRange = $firstSheetName;
6375: } else {
6376: $sheetRange = "$firstSheetName:$lastSheetName";
6377: }
6378:
6379:
6380: $sheetRange = str_replace("'", "''", $sheetRange);
6381:
6382:
6383:
6384:
6385:
6386: if (preg_match("/[ !\"@#£$%&{()}<>=+'|^,;-]/", $sheetRange)) {
6387: $sheetRange = "'$sheetRange'";
6388: }
6389:
6390: return $sheetRange;
6391: break;
6392:
6393: default:
6394:
6395: throw new PHPExcel_Reader_Exception('Excel5 reader only supports internal sheets in fomulas');
6396: break;
6397: }
6398: }
6399: return false;
6400: }
6401:
6402:
6403: 6404: 6405: 6406: 6407: 6408: 6409: 6410:
6411: private static function _readBIFF8ConstantArray($arrayData)
6412: {
6413:
6414: $nc = ord($arrayData[0]);
6415:
6416:
6417: $nr = self::_GetInt2d($arrayData, 1);
6418: $size = 3;
6419: $arrayData = substr($arrayData, 3);
6420:
6421:
6422: $matrixChunks = array();
6423: for ($r = 1; $r <= $nr + 1; ++$r) {
6424: $items = array();
6425: for ($c = 1; $c <= $nc + 1; ++$c) {
6426: $constant = self::_readBIFF8Constant($arrayData);
6427: $items[] = $constant['value'];
6428: $arrayData = substr($arrayData, $constant['size']);
6429: $size += $constant['size'];
6430: }
6431: $matrixChunks[] = implode(',', $items);
6432: }
6433: $matrix = '{' . implode(';', $matrixChunks) . '}';
6434:
6435: return array(
6436: 'value' => $matrix,
6437: 'size' => $size,
6438: );
6439: }
6440:
6441:
6442: 6443: 6444: 6445: 6446: 6447: 6448: 6449:
6450: private static function _readBIFF8Constant($valueData)
6451: {
6452:
6453: $identifier = ord($valueData[0]);
6454:
6455: switch ($identifier) {
6456: case 0x00:
6457: $value = '';
6458: $size = 9;
6459: break;
6460: case 0x01:
6461:
6462: $value = self::_extractNumber(substr($valueData, 1, 8));
6463: $size = 9;
6464: break;
6465: case 0x02:
6466:
6467: $string = self::_readUnicodeStringLong(substr($valueData, 1));
6468: $value = '"' . $string['value'] . '"';
6469: $size = 1 + $string['size'];
6470: break;
6471: case 0x04:
6472:
6473: if (ord($valueData[1])) {
6474: $value = 'TRUE';
6475: } else {
6476: $value = 'FALSE';
6477: }
6478: $size = 9;
6479: break;
6480: case 0x10:
6481:
6482: $value = self::_mapErrorCode(ord($valueData[1]));
6483: $size = 9;
6484: break;
6485: }
6486: return array(
6487: 'value' => $value,
6488: 'size' => $size,
6489: );
6490: }
6491:
6492:
6493: 6494: 6495: 6496: 6497: 6498: 6499:
6500: private static function _readRGB($rgb)
6501: {
6502:
6503: $r = ord($rgb{0});
6504:
6505:
6506: $g = ord($rgb{1});
6507:
6508:
6509: $b = ord($rgb{2});
6510:
6511:
6512: $rgb = sprintf('%02X%02X%02X', $r, $g, $b);
6513:
6514: return array('rgb' => $rgb);
6515: }
6516:
6517:
6518: 6519: 6520: 6521: 6522: 6523: 6524:
6525: private function _readByteStringShort($subData)
6526: {
6527:
6528: $ln = ord($subData[0]);
6529:
6530:
6531: $value = $this->_decodeCodepage(substr($subData, 1, $ln));
6532:
6533: return array(
6534: 'value' => $value,
6535: 'size' => 1 + $ln,
6536: );
6537: }
6538:
6539:
6540: 6541: 6542: 6543: 6544: 6545: 6546:
6547: private function _readByteStringLong($subData)
6548: {
6549:
6550: $ln = self::_GetInt2d($subData, 0);
6551:
6552:
6553: $value = $this->_decodeCodepage(substr($subData, 2));
6554:
6555:
6556: return array(
6557: 'value' => $value,
6558: 'size' => 2 + $ln,
6559: );
6560: }
6561:
6562:
6563: 6564: 6565: 6566: 6567: 6568: 6569: 6570:
6571: private static function _readUnicodeStringShort($subData)
6572: {
6573: $value = '';
6574:
6575:
6576: $characterCount = ord($subData[0]);
6577:
6578: $string = self::_readUnicodeString(substr($subData, 1), $characterCount);
6579:
6580:
6581: $string['size'] += 1;
6582:
6583: return $string;
6584: }
6585:
6586:
6587: 6588: 6589: 6590: 6591: 6592: 6593: 6594:
6595: private static function _readUnicodeStringLong($subData)
6596: {
6597: $value = '';
6598:
6599:
6600: $characterCount = self::_GetInt2d($subData, 0);
6601:
6602: $string = self::_readUnicodeString(substr($subData, 2), $characterCount);
6603:
6604:
6605: $string['size'] += 2;
6606:
6607: return $string;
6608: }
6609:
6610:
6611: 6612: 6613: 6614: 6615: 6616: 6617: 6618: 6619:
6620: private static function _readUnicodeString($subData, $characterCount)
6621: {
6622: $value = '';
6623:
6624:
6625:
6626:
6627: $isCompressed = !((0x01 & ord($subData[0])) >> 0);
6628:
6629:
6630: $hasAsian = (0x04) & ord($subData[0]) >> 2;
6631:
6632:
6633: $hasRichText = (0x08) & ord($subData[0]) >> 3;
6634:
6635:
6636:
6637:
6638: $value = self::_encodeUTF16(substr($subData, 1, $isCompressed ? $characterCount : 2 * $characterCount), $isCompressed);
6639:
6640: return array(
6641: 'value' => $value,
6642: 'size' => $isCompressed ? 1 + $characterCount : 1 + 2 * $characterCount,
6643: );
6644: }
6645:
6646:
6647: 6648: 6649: 6650: 6651: 6652: 6653:
6654: private static function _UTF8toExcelDoubleQuoted($value)
6655: {
6656: return '"' . str_replace('"', '""', $value) . '"';
6657: }
6658:
6659:
6660: 6661: 6662: 6663: 6664: 6665:
6666: private static function _extractNumber($data)
6667: {
6668: $rknumhigh = self::_GetInt4d($data, 4);
6669: $rknumlow = self::_GetInt4d($data, 0);
6670: $sign = ($rknumhigh & 0x80000000) >> 31;
6671: $exp = (($rknumhigh & 0x7ff00000) >> 20) - 1023;
6672: $mantissa = (0x100000 | ($rknumhigh & 0x000fffff));
6673: $mantissalow1 = ($rknumlow & 0x80000000) >> 31;
6674: $mantissalow2 = ($rknumlow & 0x7fffffff);
6675: $value = $mantissa / pow( 2 , (20 - $exp));
6676:
6677: if ($mantissalow1 != 0) {
6678: $value += 1 / pow (2 , (21 - $exp));
6679: }
6680:
6681: $value += $mantissalow2 / pow (2 , (52 - $exp));
6682: if ($sign) {
6683: $value *= -1;
6684: }
6685:
6686: return $value;
6687: }
6688:
6689:
6690: private static function _GetIEEE754($rknum)
6691: {
6692: if (($rknum & 0x02) != 0) {
6693: $value = $rknum >> 2;
6694: } else {
6695:
6696:
6697:
6698:
6699:
6700: $sign = ($rknum & 0x80000000) >> 31;
6701: $exp = ($rknum & 0x7ff00000) >> 20;
6702: $mantissa = (0x100000 | ($rknum & 0x000ffffc));
6703: $value = $mantissa / pow( 2 , (20- ($exp - 1023)));
6704: if ($sign) {
6705: $value = -1 * $value;
6706: }
6707:
6708: }
6709: if (($rknum & 0x01) != 0) {
6710: $value /= 100;
6711: }
6712: return $value;
6713: }
6714:
6715:
6716: 6717: 6718: 6719: 6720: 6721: 6722:
6723: private static function _encodeUTF16($string, $compressed = '')
6724: {
6725: if ($compressed) {
6726: $string = self::_uncompressByteString($string);
6727: }
6728:
6729: return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', 'UTF-16LE');
6730: }
6731:
6732:
6733: 6734: 6735: 6736: 6737: 6738:
6739: private static function _uncompressByteString($string)
6740: {
6741: $uncompressedString = '';
6742: $strLen = strlen($string);
6743: for ($i = 0; $i < $strLen; ++$i) {
6744: $uncompressedString .= $string[$i] . "\0";
6745: }
6746:
6747: return $uncompressedString;
6748: }
6749:
6750:
6751: 6752: 6753: 6754: 6755: 6756:
6757: private function _decodeCodepage($string)
6758: {
6759: return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', $this->_codepage);
6760: }
6761:
6762:
6763: 6764: 6765: 6766: 6767: 6768: 6769:
6770: public static function _GetInt2d($data, $pos)
6771: {
6772: return ord($data[$pos]) | (ord($data[$pos+1]) << 8);
6773: }
6774:
6775:
6776: 6777: 6778: 6779: 6780: 6781: 6782:
6783: public static function _GetInt4d($data, $pos)
6784: {
6785:
6786:
6787:
6788: $_or_24 = ord($data[$pos + 3]);
6789: if ($_or_24 >= 128) {
6790:
6791: $_ord_24 = -abs((256 - $_or_24) << 24);
6792: } else {
6793: $_ord_24 = ($_or_24 & 127) << 24;
6794: }
6795: return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | $_ord_24;
6796: }
6797:
6798:
6799: 6800: 6801: 6802: 6803: 6804: 6805:
6806: private static function _readColor($color,$palette,$version)
6807: {
6808: if ($color <= 0x07 || $color >= 0x40) {
6809:
6810: return self::_mapBuiltInColor($color);
6811: } elseif (isset($palette) && isset($palette[$color - 8])) {
6812:
6813: return $palette[$color - 8];
6814: } else {
6815:
6816: if ($version == self::XLS_BIFF8) {
6817: return self::_mapColor($color);
6818: } else {
6819:
6820: return self::_mapColorBIFF5($color);
6821: }
6822: }
6823:
6824: return $color;
6825: }
6826:
6827:
6828: 6829: 6830: 6831: 6832: 6833: 6834:
6835: private static function _mapBorderStyle($index)
6836: {
6837: switch ($index) {
6838: case 0x00: return PHPExcel_Style_Border::BORDER_NONE;
6839: case 0x01: return PHPExcel_Style_Border::BORDER_THIN;
6840: case 0x02: return PHPExcel_Style_Border::BORDER_MEDIUM;
6841: case 0x03: return PHPExcel_Style_Border::BORDER_DASHED;
6842: case 0x04: return PHPExcel_Style_Border::BORDER_DOTTED;
6843: case 0x05: return PHPExcel_Style_Border::BORDER_THICK;
6844: case 0x06: return PHPExcel_Style_Border::BORDER_DOUBLE;
6845: case 0x07: return PHPExcel_Style_Border::BORDER_HAIR;
6846: case 0x08: return PHPExcel_Style_Border::BORDER_MEDIUMDASHED;
6847: case 0x09: return PHPExcel_Style_Border::BORDER_DASHDOT;
6848: case 0x0A: return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT;
6849: case 0x0B: return PHPExcel_Style_Border::BORDER_DASHDOTDOT;
6850: case 0x0C: return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT;
6851: case 0x0D: return PHPExcel_Style_Border::BORDER_SLANTDASHDOT;
6852: default: return PHPExcel_Style_Border::BORDER_NONE;
6853: }
6854: }
6855:
6856:
6857: 6858: 6859: 6860: 6861: 6862: 6863:
6864: private static function _mapFillPattern($index)
6865: {
6866: switch ($index) {
6867: case 0x00: return PHPExcel_Style_Fill::FILL_NONE;
6868: case 0x01: return PHPExcel_Style_Fill::FILL_SOLID;
6869: case 0x02: return PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY;
6870: case 0x03: return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY;
6871: case 0x04: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY;
6872: case 0x05: return PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL;
6873: case 0x06: return PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL;
6874: case 0x07: return PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN;
6875: case 0x08: return PHPExcel_Style_Fill::FILL_PATTERN_DARKUP;
6876: case 0x09: return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID;
6877: case 0x0A: return PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS;
6878: case 0x0B: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL;
6879: case 0x0C: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL;
6880: case 0x0D: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN;
6881: case 0x0E: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP;
6882: case 0x0F: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID;
6883: case 0x10: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS;
6884: case 0x11: return PHPExcel_Style_Fill::FILL_PATTERN_GRAY125;
6885: case 0x12: return PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625;
6886: default: return PHPExcel_Style_Fill::FILL_NONE;
6887: }
6888: }
6889:
6890:
6891: 6892: 6893: 6894: 6895: 6896:
6897: private static function _mapErrorCode($subData)
6898: {
6899: switch ($subData) {
6900: case 0x00: return '#NULL!'; break;
6901: case 0x07: return '#DIV/0!'; break;
6902: case 0x0F: return '#VALUE!'; break;
6903: case 0x17: return '#REF!'; break;
6904: case 0x1D: return '#NAME?'; break;
6905: case 0x24: return '#NUM!'; break;
6906: case 0x2A: return '#N/A'; break;
6907: default: return false;
6908: }
6909: }
6910:
6911:
6912: 6913: 6914: 6915: 6916: 6917:
6918: private static function _mapBuiltInColor($color)
6919: {
6920: switch ($color) {
6921: case 0x00: return array('rgb' => '000000');
6922: case 0x01: return array('rgb' => 'FFFFFF');
6923: case 0x02: return array('rgb' => 'FF0000');
6924: case 0x03: return array('rgb' => '00FF00');
6925: case 0x04: return array('rgb' => '0000FF');
6926: case 0x05: return array('rgb' => 'FFFF00');
6927: case 0x06: return array('rgb' => 'FF00FF');
6928: case 0x07: return array('rgb' => '00FFFF');
6929: case 0x40: return array('rgb' => '000000');
6930: case 0x41: return array('rgb' => 'FFFFFF');
6931: default: return array('rgb' => '000000');
6932: }
6933: }
6934:
6935:
6936: 6937: 6938: 6939: 6940: 6941:
6942: private static function _mapColorBIFF5($subData)
6943: {
6944: switch ($subData) {
6945: case 0x08: return array('rgb' => '000000');
6946: case 0x09: return array('rgb' => 'FFFFFF');
6947: case 0x0A: return array('rgb' => 'FF0000');
6948: case 0x0B: return array('rgb' => '00FF00');
6949: case 0x0C: return array('rgb' => '0000FF');
6950: case 0x0D: return array('rgb' => 'FFFF00');
6951: case 0x0E: return array('rgb' => 'FF00FF');
6952: case 0x0F: return array('rgb' => '00FFFF');
6953: case 0x10: return array('rgb' => '800000');
6954: case 0x11: return array('rgb' => '008000');
6955: case 0x12: return array('rgb' => '000080');
6956: case 0x13: return array('rgb' => '808000');
6957: case 0x14: return array('rgb' => '800080');
6958: case 0x15: return array('rgb' => '008080');
6959: case 0x16: return array('rgb' => 'C0C0C0');
6960: case 0x17: return array('rgb' => '808080');
6961: case 0x18: return array('rgb' => '8080FF');
6962: case 0x19: return array('rgb' => '802060');
6963: case 0x1A: return array('rgb' => 'FFFFC0');
6964: case 0x1B: return array('rgb' => 'A0E0F0');
6965: case 0x1C: return array('rgb' => '600080');
6966: case 0x1D: return array('rgb' => 'FF8080');
6967: case 0x1E: return array('rgb' => '0080C0');
6968: case 0x1F: return array('rgb' => 'C0C0FF');
6969: case 0x20: return array('rgb' => '000080');
6970: case 0x21: return array('rgb' => 'FF00FF');
6971: case 0x22: return array('rgb' => 'FFFF00');
6972: case 0x23: return array('rgb' => '00FFFF');
6973: case 0x24: return array('rgb' => '800080');
6974: case 0x25: return array('rgb' => '800000');
6975: case 0x26: return array('rgb' => '008080');
6976: case 0x27: return array('rgb' => '0000FF');
6977: case 0x28: return array('rgb' => '00CFFF');
6978: case 0x29: return array('rgb' => '69FFFF');
6979: case 0x2A: return array('rgb' => 'E0FFE0');
6980: case 0x2B: return array('rgb' => 'FFFF80');
6981: case 0x2C: return array('rgb' => 'A6CAF0');
6982: case 0x2D: return array('rgb' => 'DD9CB3');
6983: case 0x2E: return array('rgb' => 'B38FEE');
6984: case 0x2F: return array('rgb' => 'E3E3E3');
6985: case 0x30: return array('rgb' => '2A6FF9');
6986: case 0x31: return array('rgb' => '3FB8CD');
6987: case 0x32: return array('rgb' => '488436');
6988: case 0x33: return array('rgb' => '958C41');
6989: case 0x34: return array('rgb' => '8E5E42');
6990: case 0x35: return array('rgb' => 'A0627A');
6991: case 0x36: return array('rgb' => '624FAC');
6992: case 0x37: return array('rgb' => '969696');
6993: case 0x38: return array('rgb' => '1D2FBE');
6994: case 0x39: return array('rgb' => '286676');
6995: case 0x3A: return array('rgb' => '004500');
6996: case 0x3B: return array('rgb' => '453E01');
6997: case 0x3C: return array('rgb' => '6A2813');
6998: case 0x3D: return array('rgb' => '85396A');
6999: case 0x3E: return array('rgb' => '4A3285');
7000: case 0x3F: return array('rgb' => '424242');
7001: default: return array('rgb' => '000000');
7002: }
7003: }
7004:
7005:
7006: 7007: 7008: 7009: 7010: 7011:
7012: private static function _mapColor($subData)
7013: {
7014: switch ($subData) {
7015: case 0x08: return array('rgb' => '000000');
7016: case 0x09: return array('rgb' => 'FFFFFF');
7017: case 0x0A: return array('rgb' => 'FF0000');
7018: case 0x0B: return array('rgb' => '00FF00');
7019: case 0x0C: return array('rgb' => '0000FF');
7020: case 0x0D: return array('rgb' => 'FFFF00');
7021: case 0x0E: return array('rgb' => 'FF00FF');
7022: case 0x0F: return array('rgb' => '00FFFF');
7023: case 0x10: return array('rgb' => '800000');
7024: case 0x11: return array('rgb' => '008000');
7025: case 0x12: return array('rgb' => '000080');
7026: case 0x13: return array('rgb' => '808000');
7027: case 0x14: return array('rgb' => '800080');
7028: case 0x15: return array('rgb' => '008080');
7029: case 0x16: return array('rgb' => 'C0C0C0');
7030: case 0x17: return array('rgb' => '808080');
7031: case 0x18: return array('rgb' => '9999FF');
7032: case 0x19: return array('rgb' => '993366');
7033: case 0x1A: return array('rgb' => 'FFFFCC');
7034: case 0x1B: return array('rgb' => 'CCFFFF');
7035: case 0x1C: return array('rgb' => '660066');
7036: case 0x1D: return array('rgb' => 'FF8080');
7037: case 0x1E: return array('rgb' => '0066CC');
7038: case 0x1F: return array('rgb' => 'CCCCFF');
7039: case 0x20: return array('rgb' => '000080');
7040: case 0x21: return array('rgb' => 'FF00FF');
7041: case 0x22: return array('rgb' => 'FFFF00');
7042: case 0x23: return array('rgb' => '00FFFF');
7043: case 0x24: return array('rgb' => '800080');
7044: case 0x25: return array('rgb' => '800000');
7045: case 0x26: return array('rgb' => '008080');
7046: case 0x27: return array('rgb' => '0000FF');
7047: case 0x28: return array('rgb' => '00CCFF');
7048: case 0x29: return array('rgb' => 'CCFFFF');
7049: case 0x2A: return array('rgb' => 'CCFFCC');
7050: case 0x2B: return array('rgb' => 'FFFF99');
7051: case 0x2C: return array('rgb' => '99CCFF');
7052: case 0x2D: return array('rgb' => 'FF99CC');
7053: case 0x2E: return array('rgb' => 'CC99FF');
7054: case 0x2F: return array('rgb' => 'FFCC99');
7055: case 0x30: return array('rgb' => '3366FF');
7056: case 0x31: return array('rgb' => '33CCCC');
7057: case 0x32: return array('rgb' => '99CC00');
7058: case 0x33: return array('rgb' => 'FFCC00');
7059: case 0x34: return array('rgb' => 'FF9900');
7060: case 0x35: return array('rgb' => 'FF6600');
7061: case 0x36: return array('rgb' => '666699');
7062: case 0x37: return array('rgb' => '969696');
7063: case 0x38: return array('rgb' => '003366');
7064: case 0x39: return array('rgb' => '339966');
7065: case 0x3A: return array('rgb' => '003300');
7066: case 0x3B: return array('rgb' => '333300');
7067: case 0x3C: return array('rgb' => '993300');
7068: case 0x3D: return array('rgb' => '993366');
7069: case 0x3E: return array('rgb' => '333399');
7070: case 0x3F: return array('rgb' => '333333');
7071: default: return array('rgb' => '000000');
7072: }
7073: }
7074:
7075:
7076: private function _parseRichText($is = '') {
7077: $value = new PHPExcel_RichText();
7078:
7079: $value->createText($is);
7080:
7081: return $value;
7082: }
7083:
7084: }
7085: