diff --git a/Classes/PHPExcel/Reader/Excel5.php b/Classes/PHPExcel/Reader/Excel5.php index e7d0d973..8568271a 100644 --- a/Classes/PHPExcel/Reader/Excel5.php +++ b/Classes/PHPExcel/Reader/Excel5.php @@ -334,6 +334,20 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader */ private $_objs; + /** + * Text Objects. One TXO record corresponds with one entry. + * + * @var array + */ + private $_textObjects; + + /** + * Cell Annotations (BIFF8) + * + * @var array + */ + private $_cellNotes; + /** * The combined MSODRAWINGGROUP data * @@ -712,12 +726,18 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader // Initialize objs $this->_objs = array(); + // Initialize text objs + $this->_textObjects = array(); + // Initialize shared formula parts $this->_sharedFormulaParts = array(); // Initialize shared formulas $this->_sharedFormulas = array(); + // Initialize cell annotations + $this->_cellNotes = array(); + while ($this->_pos <= $this->_dataSize - 4) { $code = self::_GetInt2d($this->_data, $this->_pos); @@ -771,6 +791,7 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader case self::XLS_Type_RANGEPROTECTION: $this->_readRangeProtection(); break; case self::XLS_Type_NOTE: $this->_readNote(); break; //case self::XLS_Type_IMDATA: $this->_readImData(); break; + case self::XLS_Type_TXO: $this->_readTextObject(); break; case self::XLS_Type_CONTINUE: $this->_readContinue(); break; case self::XLS_Type_EOF: $this->_readDefault(); break 2; default: $this->_readDefault(); break; @@ -794,7 +815,9 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader // treat OBJ records foreach ($this->_objs as $n => $obj) { -// echo 'Object ID is ',$n,'
'; +// echo 'Object ID is ',$n,'
'; +// var_dump($obj); +// echo '
'; // // the first shape container never has a corresponding OBJ record, hence $n + 1 $spContainer = $allSpContainers[$n + 1]; @@ -825,6 +848,9 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader case 0x19: // Note // echo 'Cell Annotation Object
'; + $this->_objs[$n]['objTextData'] = $this->_textObjects[$obj['idObjID']-1]; + $text = $this->_textObjects[$obj['idObjID']-1]['text']; +// echo $text,'
'; break; case 0x08: @@ -884,6 +910,22 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader } } } + + if (count($this->_cellNotes) > 0) { + foreach($this->_cellNotes as $note => $noteDetails) { +// echo 'Cell annotation ',$note,'
'; +// var_dump($noteDetails); +// echo '
'; + if (isset($this->_objs[$noteDetails['objectID']-1])) { +// var_dump($this->_objs[$noteDetails['objectID']-1]); +// echo '
'; + $cellAddress = str_replace('$','',$noteDetails['cellRef']); + $this->_phpSheet->getComment( $cellAddress ) + ->setAuthor( $noteDetails['author'] ) + ->setText($this->_parseRichText($this->_objs[$noteDetails['objectID']-1]['objTextData']['text']) ); + } + } + } } // add the named ranges (defined names) @@ -1359,6 +1401,11 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader // echo 'Note Address=',$cellAddress,'
'; // echo 'Note Object ID=',$noteObjID,'
'; // echo 'Note Author=',$noteAuthor,'
'; +// + $this->_cellNotes[] = array('cellRef' => $cellAddress, + 'objectID' => $noteObjID, + 'author' => $noteAuthor + ); } else { $extension = false; if ($cellAddress == '$B$65536') { @@ -1378,10 +1425,12 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader // echo 'Note Text=',$noteText,'
'; if ($extension) { + // Concatenate this extension with the currently set comment for the cell $comment = $this->_phpSheet->getComment( $cellAddress ); $commentText = $comment->getText()->getPlainText(); $comment->setText($this->_parseRichText($commentText.$noteText) ); } else { + // Set comment for the cell $this->_phpSheet->getComment( $cellAddress ) // ->setAuthor( $author ) ->setText($this->_parseRichText($noteText) ); @@ -1390,6 +1439,41 @@ class PHPExcel_Reader_Excel5 implements PHPExcel_Reader_IReader } + /** + * The TEXT Object record contains the text associated with a cell annotation. + */ + private function _readTextObject() + { +// echo 'Read Text Object
'; + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = substr($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // recordData consists of an array of subrecords looking like this: + // grbit: 2 bytes; Option Flags + // rot: 2 bytes; rotation + // cchText: 2 bytes; length of the text (in the first continue record) + // cbRuns: 2 bytes; length of the formatting (in the second continue record) + + $grbitOpts = self::_GetInt2d($recordData, 0); + $rot = self::_GetInt2d($recordData, 2); + $cchText = self::_GetInt2d($recordData, 10); + $cbRuns = self::_GetInt2d($recordData, 12); + $text = $this->_getSplicedRecordData(); + + $this->_textObjects[] = array( 'text' => substr($text["recordData"],$text["spliceOffsets"][0]+1,$cchText), + 'format' => substr($text["recordData"],$text["spliceOffsets"][1],$cbRuns), + 'alignment' => $grbitOpts, + 'rotation' => $rot + ); + } + /** * Read BOF */ diff --git a/changelog.txt b/changelog.txt index 6961d4a4..e798455f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -33,7 +33,7 @@ Fixed in SVN: - Feature: (MBaker) Added new rangeToArray() and namedRangeToArray() methods to the PHPExcel_Worksheet object. Functionally, these are identical to the toArray() method, except that they take an additional first parameter of a Range (e.g. 'B2:C3') or a Named Range name. Modified the toArray() method so that it actually uses rangeToArray(). -- Feature: (MBaker) Added support for cell comments in the OOCalc, Gnumeric and Excel2003XML Readers, and in the Excel5 Reader (for BIFF5-7... BIFF8 Still outstanding) +- Feature: (MBaker) Added support for cell comments in the OOCalc, Gnumeric and Excel2003XML Readers, and in the Excel5 Reader - Bugfix: (MBaker) Work item 14888 - Simple =IF() formula disappears - Bugfix: (MBaker) Work item 14898 - PHP Warning: preg_match(): Compilation failed: PCRE does not support \\L, \\l, \\N, \\P, \\p, \\U, \\u, or \\X - Bugfix: (MBaker) Work item 14901 - VLOOKUP choking on parameters in PHPExcel.1.7.5/PHPExcel_Writer_Excel2007