From 41199626d8799a15bc36c126009b072d8d6596da Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Mon, 27 Feb 2012 22:05:21 +0000 Subject: [PATCH] FIXED : Work item 8916 - Support for Rich-Text in PHPExcel_Writer_Excel5 git-svn-id: https://phpexcel.svn.codeplex.com/svn/trunk@87070 2327b42d-5241-43d6-9e2a-de5ac946f064 --- Classes/PHPExcel/Shared/String.php | 26 +++++--- Classes/PHPExcel/Writer/Excel5.php | 17 ++++++ Classes/PHPExcel/Writer/Excel5/Workbook.php | 44 +++++++------- Classes/PHPExcel/Writer/Excel5/Worksheet.php | 62 +++++++++++++++++--- changelog.txt | 1 + 5 files changed, 114 insertions(+), 36 deletions(-) diff --git a/Classes/PHPExcel/Shared/String.php b/Classes/PHPExcel/Shared/String.php index 9616aa4e..3af54614 100644 --- a/Classes/PHPExcel/Shared/String.php +++ b/Classes/PHPExcel/Shared/String.php @@ -430,19 +430,29 @@ class PHPExcel_Shared_String * @param string $value UTF-8 encoded string * @return string */ - public static function UTF8toBIFF8UnicodeShort($value) + public static function UTF8toBIFF8UnicodeShort($value, $arrcRuns = array()) { // character count $ln = self::CountCharacters($value, 'UTF-8'); // option flags - $opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ? - 0x0001 : 0x0000; - - // characters - $chars = self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); - - $data = pack('CC', $ln, $opt) . $chars; + if(empty($arrcRuns)){ + $opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ? + 0x0001 : 0x0000; + $data = pack('CC', $ln, $opt); + // characters + $data .= self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); + } + else { + $data = pack('vC', $ln, 0x08); + $data .= pack('v', count($arrcRuns)); + // characters + $data .= $value; + foreach ($arrcRuns as $cRun){ + $data .= pack('v', $cRun['strlen']); + $data .= pack('v', $cRun['fontidx']); + } + } return $data; } diff --git a/Classes/PHPExcel/Writer/Excel5.php b/Classes/PHPExcel/Writer/Excel5.php index 945d8f4b..7c29a83e 100644 --- a/Classes/PHPExcel/Writer/Excel5.php +++ b/Classes/PHPExcel/Writer/Excel5.php @@ -156,6 +156,23 @@ class PHPExcel_Writer_Excel5 implements PHPExcel_Writer_IWriter $this->_writerWorkbook->addXfWriter($style, false); } + // add fonts from rich text eleemnts + for ($i = 0; $i < $countSheets; ++$i) { + foreach ($this->_writerWorksheets[$i]->_phpSheet->getCellCollection() as $cellID) { + $cell = $this->_writerWorksheets[$i]->_phpSheet->getCell($cellID); + $cVal = $cell->getValue(); + if ($cVal instanceof PHPExcel_RichText) { + $elements = $cVal->getRichTextElements(); + foreach ($elements as $element) { + if ($element instanceof PHPExcel_RichText_Run) { + $font = $element->getFont(); + $this->_writerWorksheets[$i]->_fntHashIndex[$font->getHashCode()] = $this->_writerWorkbook->_addFont($font); + } + } + } + } + } + // initialize OLE file $workbookStreamName = 'Workbook'; $OLE = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs($workbookStreamName)); diff --git a/Classes/PHPExcel/Writer/Excel5/Workbook.php b/Classes/PHPExcel/Writer/Excel5/Workbook.php index f8599d58..2c1dc810 100644 --- a/Classes/PHPExcel/Writer/Excel5/Workbook.php +++ b/Classes/PHPExcel/Writer/Excel5/Workbook.php @@ -255,20 +255,7 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter $xfWriter->setIsStyleXf($isStyleXf); // Add the font if not already added - $fontHashCode = $style->getFont()->getHashCode(); - - if (isset($this->_addedFonts[$fontHashCode])) { - $fontIndex = $this->_addedFonts[$fontHashCode]; - } else { - $countFonts = count($this->_fontWriters); - $fontIndex = ($countFonts < 4) ? $countFonts : $countFonts + 1; - - $fontWriter = new PHPExcel_Writer_Excel5_Font($style->getFont()); - $fontWriter->setColorIndex($this->_addColor($style->getFont()->getColor()->getRGB())); - $this->_fontWriters[] = $fontWriter; - - $this->_addedFonts[$fontHashCode] = $fontIndex; - } + $fontIndex = $this->_addFont($style->getFont()); // Assign the font index to the xf record $xfWriter->setFontIndex($fontIndex); @@ -306,6 +293,29 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter return $xfIndex; } + /** + * Add a font to added fonts + * + * @param PHPExcel_Style_Font $font + * @return int Index to FONT record + */ + public function _addFont(PHPExcel_Style_Font $font) + { + $fontHashCode = $font->getHashCode(); + if(isset($this->_addedFonts[$fontHashCode])){ + $fontIndex = $this->_addedFonts[$fontHashCode]; + } else { + $countFonts = count($this->_fontWriters); + $fontIndex = ($countFonts < 4) ? $countFonts : $countFonts + 1; + + $fontWriter = new PHPExcel_Writer_Excel5_Font($font); + $fontWriter->setColorIndex($this->_addColor($font->getColor()->getRGB())); + $this->_fontWriters[] = $fontWriter; + + $this->_addedFonts[$fontHashCode] = $fontIndex; + } + return $fontIndex; + } /** * Alter color palette adding a custom color * @@ -633,7 +643,6 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter } } - /** * Writes all the DEFINEDNAME records (BIFF8). * So far this is only used for repeating rows/columns (print titles) and print areas @@ -937,7 +946,6 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter $this->_append($header . $data); } - /** * Writes Excel FORMAT record for non "built-in" numerical formats. * @@ -973,7 +981,6 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter $this->_append($header . $data); } - /** * Write BIFF record EXTERNCOUNT to indicate the number of external sheet * references in the workbook. @@ -996,7 +1003,6 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter $this->_append($header . $data); } - /** * Writes the Excel BIFF EXTERNSHEET record. These references are used by * formulas. NAME record is required to define the print area and the repeat @@ -1019,7 +1025,6 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter $this->_append($header . $data . $sheetname); } - /** * Store the NAME record in the short format that is used for storing the print * area, repeat rows only and repeat columns only. @@ -1082,7 +1087,6 @@ class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter $this->_append($header . $data); } - /** * Store the NAME record in the long format that is used for storing the repeat * rows and columns when both are specified. This shares a lot of code with diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php index b938fa1c..1d44beb2 100644 --- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php @@ -176,7 +176,7 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter * Sheet object * @var PHPExcel_Worksheet */ - private $_phpSheet; + public $_phpSheet; /** * Count cell style Xfs @@ -192,6 +192,13 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter */ private $_escher; + /** + * Array of font hashes associated to FONT records index + * + * @var array + */ + public $_fntHashIndex; + /** * Constructor * @@ -234,6 +241,8 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter $this->_outline_below = 1; $this->_outline_right = 1; $this->_outline_on = 1; + + $this->_fntHashIndex = array(); // calculate values for DIMENSIONS record $minR = 1; @@ -406,7 +415,24 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter $cVal = $cell->getValue(); if ($cVal instanceof PHPExcel_RichText) { - $this->_writeString($row, $column, $cVal->getPlainText(), $xfIndex); + // $this->_writeString($row, $column, $cVal->getPlainText(), $xfIndex); + $arrcRun = array(); + $str_len = strlen($cVal->getPlainText()); + $str_pos = 0; + $elements = $cVal->getRichTextElements(); + foreach ($elements as $element) { + // FONT Index + if ($element instanceof PHPExcel_RichText_Run) { + $str_fontidx = $this->_fntHashIndex[$element->getFont()->getHashCode()]; + } + else { + $str_fontidx = 0; + } + $arrcRun[] = array('strlen' => $str_pos, 'fontidx' => $str_fontidx); + // Position FROM + $str_pos += strlen($element->getText()); + } + $this->_writeRichTextString($row, $column, $cVal->getPlainText(), $xfIndex, $arrcRun); } else { switch ($cell->getDatatype()) { case PHPExcel_Cell_DataType::TYPE_STRING: @@ -609,7 +635,32 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter { $this->_writeLabelSst($row, $col, $str, $xfIndex); } - + /** + * Write a LABELSST record or a LABEL record. Which one depends on BIFF version + * It differs from _writeString by the writing of rich text strings. + * @param int $row Row index (0-based) + * @param int $col Column index (0-based) + * @param string $str The string + * @param mixed $format The XF format for the cell + * @param array $arrcRun Index to Font record and characters beginning + */ + private function _writeRichTextString($row, $col, $str, $xfIndex, $arrcRun){ + $record = 0x00FD; // Record identifier + $length = 0x000A; // Bytes to follow + + $str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($str, $arrcRun); + + /* check if string is already present */ + if (!isset($this->_str_table[$str])) { + $this->_str_table[$str] = $this->_str_unique++; + } + $this->_str_total++; + + $header = pack('vv', $record, $length); + $data = pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]); + $this->_append($header.$data); + } + /** * Write a string to the specified row and column (zero indexed). * NOTE: there is an Excel 5 defined limit of 255 characters. @@ -906,10 +957,8 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter * @param string $url URL string * @return integer */ - function _writeUrlRange($row1, $col1, $row2, $col2, $url) { - // Check for internal/external sheet links or default to web link if (preg_match('[^internal:]', $url)) { return($this->_writeUrlInternal($row1, $col1, $row2, $col2, $url)); @@ -920,7 +969,6 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter return($this->_writeUrlWeb($row1, $col1, $row2, $col2, $url)); } - /** * Used to write http, ftp and mailto hyperlinks. * The link type ($options) is 0x03 is the same as absolute dir ref without @@ -2034,7 +2082,6 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter $this->_append($header.$data); } - /** * Write the WSBOOL BIFF record, mainly for fit-to-page. Used in conjunction * with the SETUP record. @@ -2246,7 +2293,6 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter $this->_append($header . $data); } - /** * Insert a 24bit bitmap image in a worksheet. * diff --git a/changelog.txt b/changelog.txt index d63cad98..54c002dc 100644 --- a/changelog.txt +++ b/changelog.txt @@ -38,6 +38,7 @@ configuration settings, allowing more flexibility. Fixed in SVN: +- Bugfix: (Progi1984) Work item 8916 - Support for Rich-Text in PHPExcel_Writer_Excel5 - Feature: (MBaker) Options for cell caching using Igbinary and SQLite/SQlite3. - Feature: (MBaker) Additional row iterator options: allow a start row to be defined in the constructor; seek(), and prev() methods added. - Feature: (Progi1984) Work item 9759 - Implement document properties in Excel5 writer