PHPExcel_Writer
[ class tree: PHPExcel_Writer ] [ index: PHPExcel_Writer ] [ all elements ]

Source for file HTML.php

Documentation is available at HTML.php

  1. <?php
  2. /**
  3.  * PHPExcel
  4.  *
  5.  * Copyright (c) 2006 - 2011 PHPExcel
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  20.  *
  21.  * @category   PHPExcel
  22.  * @package    PHPExcel_Writer
  23.  * @copyright  Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
  24.  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  25.  * @version    1.7.6, 2011-02-27
  26.  */
  27.  
  28.  
  29. /**
  30.  * PHPExcel_Writer_HTML
  31.  *
  32.  * @category   PHPExcel
  33.  * @package    PHPExcel_Writer
  34.  * @copyright  Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
  35.  */
  36. class PHPExcel_Writer_HTML implements PHPExcel_Writer_IWriter {
  37.     /**
  38.      * PHPExcel object
  39.      *
  40.      * @var PHPExcel 
  41.      */
  42.     protected $_phpExcel;
  43.  
  44.     /**
  45.      * Sheet index to write
  46.      *
  47.      * @var int 
  48.      */
  49.     private $_sheetIndex    0;
  50.  
  51.     /**
  52.      * Pre-calculate formulas
  53.      *
  54.      * @var boolean 
  55.      */
  56.     private $_preCalculateFormulas true;
  57.  
  58.     /**
  59.      * Images root
  60.      *
  61.      * @var string 
  62.      */
  63.     private $_imagesRoot    '.';
  64.  
  65.     /**
  66.      * Use inline CSS?
  67.      *
  68.      * @var boolean 
  69.      */
  70.     private $_useInlineCss false;
  71.  
  72.     /**
  73.      * Array of CSS styles
  74.      *
  75.      * @var array 
  76.      */
  77.     private $_cssStyles null;
  78.  
  79.     /**
  80.      * Array of column widths in points
  81.      *
  82.      * @var array 
  83.      */
  84.     private $_columnWidths null;
  85.  
  86.     /**
  87.      * Default font
  88.      *
  89.      * @var PHPExcel_Style_Font 
  90.      */
  91.     private $_defaultFont;
  92.  
  93.     /**
  94.      * Flag whether spans have been calculated
  95.      *
  96.      * @var boolean 
  97.      */
  98.     private $_spansAreCalculated    false;
  99.  
  100.     /**
  101.      * Excel cells that should not be written as HTML cells
  102.      *
  103.      * @var array 
  104.      */
  105.     private $_isSpannedCell    array();
  106.  
  107.     /**
  108.      * Excel cells that are upper-left corner in a cell merge
  109.      *
  110.      * @var array 
  111.      */
  112.     private $_isBaseCell    array();
  113.  
  114.     /**
  115.      * Excel rows that should not be written as HTML rows
  116.      *
  117.      * @var array 
  118.      */
  119.     private $_isSpannedRow    array();
  120.  
  121.     /**
  122.      * Is the current writer creating PDF?
  123.      *
  124.      * @var boolean 
  125.      */
  126.     protected $_isPdf = false;
  127.  
  128.     /**
  129.      * Generate the Navigation block
  130.      *
  131.      * @var boolean 
  132.      */
  133.     private $_generateSheetNavigationBlock true;
  134.  
  135.     /**
  136.      * Create a new PHPExcel_Writer_HTML
  137.      *
  138.      * @param    PHPExcel    $phpExcel    PHPExcel object
  139.      */
  140.     public function __construct(PHPExcel $phpExcel{
  141.         $this->_phpExcel = $phpExcel;
  142.         $this->_defaultFont $this->_phpExcel->getDefaultStyle()->getFont();
  143.     }
  144.  
  145.     /**
  146.      * Save PHPExcel to file
  147.      *
  148.      * @param    string        $pFileName 
  149.      * @throws    Exception
  150.      */
  151.     public function save($pFilename null{
  152.         // garbage collect
  153.         $this->_phpExcel->garbageCollect();
  154.  
  155.         $saveDebugLog PHPExcel_Calculation::getInstance()->writeDebugLog;
  156.         PHPExcel_Calculation::getInstance()->writeDebugLog false;
  157.         $saveArrayReturnType PHPExcel_Calculation::getArrayReturnType();
  158.         PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE);
  159.  
  160.         // Build CSS
  161.         $this->buildCSS(!$this->_useInlineCss);
  162.  
  163.         // Open file
  164.         $fileHandle fopen($pFilename'wb+');
  165.         if ($fileHandle === false{
  166.             throw new Exception("Could not open file $pFilename for writing.");
  167.         }
  168.  
  169.         // Write headers
  170.         fwrite($fileHandle$this->generateHTMLHeader(!$this->_useInlineCss));
  171.  
  172.         // Write navigation (tabs)
  173.         if ((!$this->_isPdf&& ($this->_generateSheetNavigationBlock)) {
  174.             fwrite($fileHandle$this->generateNavigation());
  175.         }
  176.  
  177.         // Write data
  178.         fwrite($fileHandle$this->generateSheetData());
  179.  
  180.         // Write footer
  181.         fwrite($fileHandle$this->generateHTMLFooter());
  182.  
  183.         // Close file
  184.         fclose($fileHandle);
  185.  
  186.         PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType);
  187.         PHPExcel_Calculation::getInstance()->writeDebugLog $saveDebugLog;
  188.     }
  189.  
  190.     /**
  191.      * Map VAlign
  192.      */
  193.     private function _mapVAlign($vAlign{
  194.         switch ($vAlign{
  195.             case PHPExcel_Style_Alignment::VERTICAL_BOTTOM:        return 'bottom';
  196.             case PHPExcel_Style_Alignment::VERTICAL_TOP:        return 'top';
  197.             case PHPExcel_Style_Alignment::VERTICAL_CENTER:
  198.             case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY:    return 'middle';
  199.             defaultreturn 'baseline';
  200.         }
  201.     }
  202.  
  203.     /**
  204.      * Map HAlign
  205.      *
  206.      * @return string|false
  207.      */
  208.     private function _mapHAlign($hAlign{
  209.         switch ($hAlign{
  210.             case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL:                return false;
  211.             case PHPExcel_Style_Alignment::HORIZONTAL_LEFT:                    return 'left';
  212.             case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT:                return 'right';
  213.             case PHPExcel_Style_Alignment::HORIZONTAL_CENTER:
  214.             case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS:    return 'center';
  215.             case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY:                return 'justify';
  216.             defaultreturn false;
  217.         }
  218.     }
  219.  
  220.     /**
  221.      * Map border style
  222.      */
  223.     private function _mapBorderStyle($borderStyle{
  224.         switch ($borderStyle{
  225.             case PHPExcel_Style_Border::BORDER_NONE:                return '0px';
  226.             case PHPExcel_Style_Border::BORDER_DASHDOT:                return '1px dashed';
  227.             case PHPExcel_Style_Border::BORDER_DASHDOTDOT:            return '1px dotted';
  228.             case PHPExcel_Style_Border::BORDER_DASHED:                return '1px dashed';
  229.             case PHPExcel_Style_Border::BORDER_DOTTED:                return '1px dotted';
  230.             case PHPExcel_Style_Border::BORDER_DOUBLE:                return '3px double';
  231.             case PHPExcel_Style_Border::BORDER_HAIR:                return '1px solid';
  232.             case PHPExcel_Style_Border::BORDER_MEDIUM:                return '2px solid';
  233.             case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT:        return '2px dashed';
  234.             case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT:    return '2px dotted';
  235.             case PHPExcel_Style_Border::BORDER_MEDIUMDASHED:        return '2px dashed';
  236.             case PHPExcel_Style_Border::BORDER_SLANTDASHDOT:        return '2px dashed';
  237.             case PHPExcel_Style_Border::BORDER_THICK:                return '3px solid';
  238.             case PHPExcel_Style_Border::BORDER_THIN:                return '1px solid';
  239.             defaultreturn '1px solid'// map others to thin
  240.         }
  241.     }
  242.  
  243.     /**
  244.      * Get sheet index
  245.      *
  246.      * @return int 
  247.      */
  248.     public function getSheetIndex({
  249.         return $this->_sheetIndex;
  250.     }
  251.  
  252.     /**
  253.      * Set sheet index
  254.      *
  255.      * @param    int        $pValue        Sheet index
  256.      * @return PHPExcel_Writer_HTML 
  257.      */
  258.     public function setSheetIndex($pValue 0{
  259.         $this->_sheetIndex $pValue;
  260.         return $this;
  261.     }
  262.  
  263.     /**
  264.      * Get sheet index
  265.      *
  266.      * @return boolean 
  267.      */
  268.     public function getGenerateSheetNavigationBlock({
  269.         return $this->_generateSheetNavigationBlock;
  270.     }
  271.  
  272.     /**
  273.      * Set sheet index
  274.      *
  275.      * @param    boolean        $pValue        Flag indicating whether the sheet navigation block should be generated or not
  276.      * @return PHPExcel_Writer_HTML 
  277.      */
  278.     public function setGenerateSheetNavigationBlock($pValue true{
  279.         $this->_generateSheetNavigationBlock = (bool) $pValue;
  280.         return $this;
  281.     }
  282.  
  283.     /**
  284.      * Write all sheets (resets sheetIndex to NULL)
  285.      */
  286.     public function writeAllSheets({
  287.         $this->_sheetIndex null;
  288.         return $this;
  289.     }
  290.  
  291.     /**
  292.      * Generate HTML header
  293.      *
  294.      * @param    boolean        $pIncludeStyles        Include styles?
  295.      * @return    string 
  296.      * @throws Exception
  297.      */
  298.     public function generateHTMLHeader($pIncludeStyles false{
  299.         // PHPExcel object known?
  300.         if (is_null($this->_phpExcel)) {
  301.             throw new Exception('Internal PHPExcel object not set to an instance of an object.');
  302.         }
  303.  
  304.         // Construct HTML
  305.         $html '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' PHP_EOL;
  306.         $html .= '<!-- Generated by PHPExcel - http://www.phpexcel.net -->' PHP_EOL;
  307.         $html .= '<html>' PHP_EOL;
  308.         $html .= '  <head>' PHP_EOL;
  309.         $html .= '    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">' PHP_EOL;
  310.         $html .= '    <title>' htmlspecialchars($this->_phpExcel->getProperties()->getTitle()) '</title>' PHP_EOL;
  311.         if ($pIncludeStyles{
  312.             $html .= $this->generateStyles(true);
  313.         }
  314.         $html .= '  </head>' PHP_EOL;
  315.         $html .= '' PHP_EOL;
  316.         $html .= '  <body>' PHP_EOL;
  317.  
  318.         // Return
  319.         return $html;
  320.     }
  321.  
  322.     /**
  323.      * Generate sheet data
  324.      *
  325.      * @return    string 
  326.      * @throws Exception
  327.      */
  328.     public function generateSheetData({
  329.         // PHPExcel object known?
  330.         if (is_null($this->_phpExcel)) {
  331.             throw new Exception('Internal PHPExcel object not set to an instance of an object.');
  332.         }
  333.  
  334.         // Ensure that Spans have been calculated?
  335.         if (!$this->_spansAreCalculated{
  336.             $this->_calculateSpans();
  337.         }
  338.  
  339.         // Fetch sheets
  340.         $sheets array();
  341.         if (is_null($this->_sheetIndex)) {
  342.             $sheets $this->_phpExcel->getAllSheets();
  343.         else {
  344.             $sheets[$this->_phpExcel->getSheet($this->_sheetIndex);
  345.         }
  346.  
  347.         // Construct HTML
  348.         $html '';
  349.  
  350.         // Loop all sheets
  351.         $sheetId 0;
  352.         foreach ($sheets as $sheet{
  353.             // Write table header
  354.             $html .= $this->_generateTableHeader($sheet);
  355.  
  356.             // Get worksheet dimension
  357.             $dimension explode(':'$sheet->calculateWorksheetDimension());
  358.             $dimension[0PHPExcel_Cell::coordinateFromString($dimension[0]);
  359.             $dimension[0][0PHPExcel_Cell::columnIndexFromString($dimension[0][0]1;
  360.             $dimension[1PHPExcel_Cell::coordinateFromString($dimension[1]);
  361.             $dimension[1][0PHPExcel_Cell::columnIndexFromString($dimension[1][0]1;
  362.  
  363.             // row min,max
  364.             $rowMin $dimension[0][1];
  365.             $rowMax $dimension[1][1];
  366.  
  367.             // calculate start of <tbody>, <thead>
  368.             $tbodyStart $rowMin;
  369.             $tbodyEnd   $rowMax;
  370.             $theadStart $theadEnd   0// default: no <thead>    no </thead>
  371.             if ($sheet->getPageSetup()->isRowsToRepeatAtTopSet()) {
  372.                 $rowsToRepeatAtTop $sheet->getPageSetup()->getRowsToRepeatAtTop();
  373.  
  374.                 // we can only support repeating rows that start at top row
  375.                 if ($rowsToRepeatAtTop[0== 1{
  376.                     $theadStart $rowsToRepeatAtTop[0];
  377.                     $theadEnd   $rowsToRepeatAtTop[1];
  378.                     $tbodyStart $rowsToRepeatAtTop[11;
  379.                 }
  380.             }
  381.  
  382.             // Loop through cells
  383.             $row $rowMin-1;
  384.             while($row++ < $rowMax{
  385.                 // <thead> ?
  386.                 if ($row == $theadStart{
  387.                     $html .= '        <thead>' PHP_EOL;
  388.                 }
  389.  
  390.                 // <tbody> ?
  391.                 if ($row == $tbodyStart{
  392.                     $html .= '        <tbody>' PHP_EOL;
  393.                 }
  394.  
  395.                 // Write row if there are HTML table cells in it
  396.                 if !isset($this->_isSpannedRow[$sheet->getParent()->getIndex($sheet)][$row]) ) {
  397.                     // Start a new rowData
  398.                     $rowData array();
  399.                     // Loop through columns
  400.                     $column $dimension[0][01;
  401.                     while($column++ < $dimension[1][0]{
  402.                         // Cell exists?
  403.                         if ($sheet->cellExistsByColumnAndRow($column$row)) {
  404.                             $rowData[$column$sheet->getCellByColumnAndRow($column$row);
  405.                         else {
  406.                             $rowData[$column'';
  407.                         }
  408.                     }
  409.                     $html .= $this->_generateRow($sheet$rowData$row 1);
  410.                 }
  411.  
  412.                 // </thead> ?
  413.                 if ($row == $theadEnd{
  414.                     $html .= '        </thead>' PHP_EOL;
  415.                 }
  416.  
  417.                 // </tbody> ?
  418.                 if ($row == $tbodyEnd{
  419.                     $html .= '        </tbody>' PHP_EOL;
  420.                 }
  421.             }
  422.  
  423.             // Write table footer
  424.             $html .= $this->_generateTableFooter();
  425.  
  426.             // Writing PDF?
  427.             if ($this->_isPdf{
  428.                 if (is_null($this->_sheetIndex&& $sheetId $this->_phpExcel->getSheetCount()) {
  429.                     $html .= '<div style="page-break-before:always" />';
  430.                 }
  431.             }
  432.  
  433.             // Next sheet
  434.             ++$sheetId;
  435.         }
  436.  
  437.         // Return
  438.         return $html;
  439.     }
  440.  
  441.     /**
  442.      * Generate sheet tabs
  443.      *
  444.      * @return    string 
  445.      * @throws Exception
  446.      */
  447.     public function generateNavigation()
  448.     {
  449.         // PHPExcel object known?
  450.         if (is_null($this->_phpExcel)) {
  451.             throw new Exception('Internal PHPExcel object not set to an instance of an object.');
  452.         }
  453.  
  454.         // Fetch sheets
  455.         $sheets array();
  456.         if (is_null($this->_sheetIndex)) {
  457.             $sheets $this->_phpExcel->getAllSheets();
  458.         else {
  459.             $sheets[$this->_phpExcel->getSheet($this->_sheetIndex);
  460.         }
  461.  
  462.         // Construct HTML
  463.         $html '';
  464.  
  465.         // Only if there are more than 1 sheets
  466.         if (count($sheets1{
  467.             // Loop all sheets
  468.             $sheetId 0;
  469.  
  470.             $html .= '<ul class="navigation">' PHP_EOL;
  471.  
  472.             foreach ($sheets as $sheet{
  473.                 $html .= '  <li class="sheet' $sheetId '"><a href="#sheet' $sheetId '">' $sheet->getTitle('</a></li>' PHP_EOL;
  474.                 ++$sheetId;
  475.             }
  476.  
  477.             $html .= '</ul>' PHP_EOL;
  478.         }
  479.  
  480.         return $html;
  481.     }
  482.  
  483.     /**
  484.      * Generate image tag in cell
  485.      *
  486.      * @param    PHPExcel_Worksheet    $pSheet            PHPExcel_Worksheet
  487.      * @param    string                $coordinates    Cell coordinates
  488.      * @return    string 
  489.      * @throws    Exception
  490.      */
  491.     private function _writeImageTagInCell(PHPExcel_Worksheet $pSheet$coordinates{
  492.         // Construct HTML
  493.         $html '';
  494.  
  495.         // Write images
  496.         foreach ($pSheet->getDrawingCollection(as $drawing{
  497.             if ($drawing instanceof PHPExcel_Worksheet_Drawing{
  498.                 if ($drawing->getCoordinates(== $coordinates{
  499.                     $filename $drawing->getPath();
  500.  
  501.                     // Strip off eventual '.'
  502.                     if (substr($filename01== '.'{
  503.                         $filename substr($filename1);
  504.                     }
  505.  
  506.                     // Prepend images root
  507.                     $filename $this->getImagesRoot($filename;
  508.  
  509.                     // Strip off eventual '.'
  510.                     if (substr($filename01== '.' && substr($filename02!= './'{
  511.                         $filename substr($filename1);
  512.                     }
  513.  
  514.                     // Convert UTF8 data to PCDATA
  515.                     $filename htmlspecialchars($filename);
  516.  
  517.                     $html .= PHP_EOL;
  518.                     $html .= '        <img style="position: relative; left: ' $drawing->getOffsetX('px; top: ' $drawing->getOffsetY('px; width: ' $drawing->getWidth('px; height: ' $drawing->getHeight('px;" src="' $filename '" border="0" width="' $drawing->getWidth('" height="' $drawing->getHeight('" />' PHP_EOL;
  519.                 }
  520.             }
  521.         }
  522.  
  523.         // Return
  524.         return $html;
  525.     }
  526.  
  527.     /**
  528.      * Generate CSS styles
  529.      *
  530.      * @param    boolean    $generateSurroundingHTML    Generate surrounding HTML tags? (<style> and </style>)
  531.      * @return    string 
  532.      * @throws    Exception
  533.      */
  534.     public function generateStyles($generateSurroundingHTML true{
  535.         // PHPExcel object known?
  536.         if (is_null($this->_phpExcel)) {
  537.             throw new Exception('Internal PHPExcel object not set to an instance of an object.');
  538.         }
  539.  
  540.         // Build CSS
  541.         $css $this->buildCSS($generateSurroundingHTML);
  542.  
  543.         // Construct HTML
  544.         $html '';
  545.  
  546.         // Start styles
  547.         if ($generateSurroundingHTML{
  548.             $html .= '    <style type="text/css">' PHP_EOL;
  549.             $html .= '      html { ' $this->_assembleCSS($css['html']' }' PHP_EOL;
  550.         }
  551.  
  552.         // Write all other styles
  553.         foreach ($css as $styleName => $styleDefinition{
  554.             if ($styleName != 'html'{
  555.                 $html .= '      ' $styleName ' { ' $this->_assembleCSS($styleDefinition' }' PHP_EOL;
  556.             }
  557.         }
  558.  
  559.         // End styles
  560.         if ($generateSurroundingHTML{
  561.             $html .= '    </style>' PHP_EOL;
  562.         }
  563.  
  564.         // Return
  565.         return $html;
  566.     }
  567.  
  568.     /**
  569.      * Build CSS styles
  570.      *
  571.      * @param    boolean    $generateSurroundingHTML    Generate surrounding HTML style? (html { })
  572.      * @return    array 
  573.      * @throws    Exception
  574.      */
  575.     public function buildCSS($generateSurroundingHTML true{
  576.         // PHPExcel object known?
  577.         if (is_null($this->_phpExcel)) {
  578.             throw new Exception('Internal PHPExcel object not set to an instance of an object.');
  579.         }
  580.  
  581.         // Cached?
  582.         if (!is_null($this->_cssStyles)) {
  583.             return $this->_cssStyles;
  584.         }
  585.  
  586.         // Ensure that spans have been calculated
  587.         if (!$this->_spansAreCalculated{
  588.             $this->_calculateSpans();
  589.         }
  590.  
  591.         // Construct CSS
  592.         $css array();
  593.  
  594.         // Start styles
  595.         if ($generateSurroundingHTML{
  596.             // html { }
  597.             $css['html']['font-family']      'Calibri, Arial, Helvetica, sans-serif';
  598.             $css['html']['font-size']        '11pt';
  599.             $css['html']['background-color''white';
  600.         }
  601.  
  602.  
  603.         // table { }
  604.         $css['table']['border-collapse']  'collapse';
  605.         $css['table']['page-break-after''always';
  606.  
  607.         // .gridlines td { }
  608.         $css['.gridlines td']['border''1px dotted black';
  609.  
  610.         // .b {}
  611.         $css['.b']['text-align''center'// BOOL
  612.  
  613.         // .e {}
  614.         $css['.e']['text-align''center'// ERROR
  615.  
  616.         // .f {}
  617.         $css['.f']['text-align''right'// FORMULA
  618.  
  619.         // .inlineStr {}
  620.         $css['.inlineStr']['text-align''left'// INLINE
  621.  
  622.         // .n {}
  623.         $css['.n']['text-align''right'// NUMERIC
  624.  
  625.         // .s {}
  626.         $css['.s']['text-align''left'// STRING
  627.  
  628.         // Calculate cell style hashes
  629.         foreach ($this->_phpExcel->getCellXfCollection(as $index => $style{
  630.             $css['td.style' $index$this->_createCSSStyle$style );
  631.         }
  632.  
  633.         // Fetch sheets
  634.         $sheets array();
  635.         if (is_null($this->_sheetIndex)) {
  636.             $sheets $this->_phpExcel->getAllSheets();
  637.         else {
  638.             $sheets[$this->_phpExcel->getSheet($this->_sheetIndex);
  639.         }
  640.  
  641.         // Build styles per sheet
  642.         foreach ($sheets as $sheet{
  643.             // Calculate hash code
  644.             $sheetIndex $sheet->getParent()->getIndex($sheet);
  645.  
  646.             // Build styles
  647.             // Calculate column widths
  648.             $sheet->calculateColumnWidths();
  649.  
  650.             // col elements, initialize
  651.             $highestColumnIndex PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()) 1;
  652.             $column = -1;
  653.             while($column++ < $highestColumnIndex{
  654.                 $this->_columnWidths[$sheetIndex][$column42// approximation
  655.                 $css['table.sheet' $sheetIndex ' col.col' $column]['width''42pt';
  656.             }
  657.  
  658.             // col elements, loop through columnDimensions and set width
  659.             foreach ($sheet->getColumnDimensions(as $columnDimension{
  660.                 if (($width PHPExcel_Shared_Drawing::cellDimensionToPixels($columnDimension->getWidth()$this->_defaultFont)) >= 0{
  661.                     $width PHPExcel_Shared_Drawing::pixelsToPoints($width);
  662.                     $column PHPExcel_Cell::columnIndexFromString($columnDimension->getColumnIndex()) 1;
  663.                     $this->_columnWidths[$sheetIndex][$column$width;
  664.                     $css['table.sheet' $sheetIndex ' col.col' $column]['width'$width 'pt';
  665.  
  666.                     if ($columnDimension->getVisible(=== false{
  667.                         $css['table.sheet' $sheetIndex ' col.col' $column]['visibility''collapse';
  668.                         $css['table.sheet' $sheetIndex ' col.col' $column]['*display''none'// target IE6+7
  669.                     }
  670.                 }
  671.             }
  672.  
  673.             // Default row height
  674.             $rowDimension $sheet->getDefaultRowDimension();
  675.  
  676.             // table.sheetN tr { }
  677.             $css['table.sheet' $sheetIndex ' tr'array();
  678.  
  679.             if ($rowDimension->getRowHeight(== -1{
  680.                 $pt_height PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->_phpExcel->getDefaultStyle()->getFont());
  681.             else {
  682.                 $pt_height $rowDimension->getRowHeight();
  683.             }
  684.             $css['table.sheet' $sheetIndex ' tr']['height'$pt_height 'pt';
  685.             if ($rowDimension->getVisible(=== false{
  686.                 $css['table.sheet' $sheetIndex ' tr']['display']    'none';
  687.                 $css['table.sheet' $sheetIndex ' tr']['visibility''hidden';
  688.             }
  689.  
  690.             // Calculate row heights
  691.             foreach ($sheet->getRowDimensions(as $rowDimension{
  692.                 $row $rowDimension->getRowIndex(1;
  693.  
  694.                 // table.sheetN tr.rowYYYYYY { }
  695.                 $css['table.sheet' $sheetIndex ' tr.row' $rowarray();
  696.  
  697.                 if ($rowDimension->getRowHeight(== -1{
  698.                     $pt_height PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->_phpExcel->getDefaultStyle()->getFont());
  699.                 else {
  700.                     $pt_height $rowDimension->getRowHeight();
  701.                 }
  702.                 $css['table.sheet' $sheetIndex ' tr.row' $row]['height'$pt_height 'pt';
  703.                 if ($rowDimension->getVisible(=== false{
  704.                     $css['table.sheet' $sheetIndex ' tr.row' $row]['display''none';
  705.                     $css['table.sheet' $sheetIndex ' tr.row' $row]['visibility''hidden';
  706.                 }
  707.             }
  708.         }
  709.  
  710.         // Cache
  711.         if (is_null($this->_cssStyles)) {
  712.             $this->_cssStyles $css;
  713.         }
  714.  
  715.         // Return
  716.         return $css;
  717.     }
  718.  
  719.     /**
  720.      * Create CSS style
  721.      *
  722.      * @param    PHPExcel_Style        $pStyle            PHPExcel_Style
  723.      * @return    array 
  724.      */
  725.     private function _createCSSStyle(PHPExcel_Style $pStyle{
  726.         // Construct CSS
  727.         $css '';
  728.  
  729.         // Create CSS
  730.         $css array_merge(
  731.             $this->_createCSSStyleAlignment($pStyle->getAlignment())
  732.             $this->_createCSSStyleBorders($pStyle->getBorders())
  733.             $this->_createCSSStyleFont($pStyle->getFont())
  734.             $this->_createCSSStyleFill($pStyle->getFill())
  735.         );
  736.  
  737.         // Return
  738.         return $css;
  739.     }
  740.  
  741.     /**
  742.      * Create CSS style (PHPExcel_Style_Alignment)
  743.      *
  744.      * @param    PHPExcel_Style_Alignment        $pStyle            PHPExcel_Style_Alignment
  745.      * @return    array 
  746.      */
  747.     private function _createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle{
  748.         // Construct CSS
  749.         $css array();
  750.  
  751.         // Create CSS
  752.         $css['vertical-align'$this->_mapVAlign($pStyle->getVertical());
  753.         if ($textAlign $this->_mapHAlign($pStyle->getHorizontal())) {
  754.             $css['text-align'$textAlign;
  755.         }
  756.  
  757.         // Return
  758.         return $css;
  759.     }
  760.  
  761.     /**
  762.      * Create CSS style (PHPExcel_Style_Font)
  763.      *
  764.      * @param    PHPExcel_Style_Font        $pStyle            PHPExcel_Style_Font
  765.      * @return    array 
  766.      */
  767.     private function _createCSSStyleFont(PHPExcel_Style_Font $pStyle{
  768.         // Construct CSS
  769.         $css array();
  770.  
  771.         // Create CSS
  772.         if ($pStyle->getBold()) {
  773.             $css['font-weight''bold';
  774.         }
  775.         if ($pStyle->getUnderline(!= PHPExcel_Style_Font::UNDERLINE_NONE && $pStyle->getStrikethrough()) {
  776.             $css['text-decoration''underline line-through';
  777.         else if ($pStyle->getUnderline(!= PHPExcel_Style_Font::UNDERLINE_NONE{
  778.             $css['text-decoration''underline';
  779.         else if ($pStyle->getStrikethrough()) {
  780.             $css['text-decoration''line-through';
  781.         }
  782.         if ($pStyle->getItalic()) {
  783.             $css['font-style''italic';
  784.         }
  785.  
  786.         $css['color']        '#' $pStyle->getColor()->getRGB();
  787.         $css['font-family']    '\'' $pStyle->getName('\'';
  788.         $css['font-size']    $pStyle->getSize('pt';
  789.  
  790.         // Return
  791.         return $css;
  792.     }
  793.  
  794.     /**
  795.      * Create CSS style (PHPExcel_Style_Borders)
  796.      *
  797.      * @param    PHPExcel_Style_Borders        $pStyle            PHPExcel_Style_Borders
  798.      * @return    array 
  799.      */
  800.     private function _createCSSStyleBorders(PHPExcel_Style_Borders $pStyle{
  801.         // Construct CSS
  802.         $css array();
  803.  
  804.         // Create CSS
  805.         $css['border-bottom']    $this->_createCSSStyleBorder($pStyle->getBottom());
  806.         $css['border-top']        $this->_createCSSStyleBorder($pStyle->getTop());
  807.         $css['border-left']        $this->_createCSSStyleBorder($pStyle->getLeft());
  808.         $css['border-right']    $this->_createCSSStyleBorder($pStyle->getRight());
  809.  
  810.         // Return
  811.         return $css;
  812.     }
  813.  
  814.     /**
  815.      * Create CSS style (PHPExcel_Style_Border)
  816.      *
  817.      * @param    PHPExcel_Style_Border        $pStyle            PHPExcel_Style_Border
  818.      * @return    string 
  819.      */
  820.     private function _createCSSStyleBorder(PHPExcel_Style_Border $pStyle{
  821.         // Construct HTML
  822.         $css '';
  823.  
  824.         // Create CSS
  825.         $css .= $this->_mapBorderStyle($pStyle->getBorderStyle()) ' #' $pStyle->getColor()->getRGB();
  826.  
  827.         // Return
  828.         return $css;
  829.     }
  830.  
  831.     /**
  832.      * Create CSS style (PHPExcel_Style_Fill)
  833.      *
  834.      * @param    PHPExcel_Style_Fill        $pStyle            PHPExcel_Style_Fill
  835.      * @return    array 
  836.      */
  837.     private function _createCSSStyleFill(PHPExcel_Style_Fill $pStyle{
  838.         // Construct HTML
  839.         $css array();
  840.  
  841.         // Create CSS
  842.         $value $pStyle->getFillType(== PHPExcel_Style_Fill::FILL_NONE ?
  843.             'white' '#' $pStyle->getStartColor()->getRGB();
  844.         $css['background-color'$value;
  845.  
  846.         // Return
  847.         return $css;
  848.     }
  849.  
  850.     /**
  851.      * Generate HTML footer
  852.      */
  853.     public function generateHTMLFooter({
  854.         // Construct HTML
  855.         $html '';
  856.         $html .= '  </body>' PHP_EOL;
  857.         $html .= '</html>' PHP_EOL;
  858.  
  859.         // Return
  860.         return $html;
  861.     }
  862.  
  863.     /**
  864.      * Generate table header
  865.      *
  866.      * @param    PHPExcel_Worksheet    $pSheet        The worksheet for the table we are writing
  867.      * @return    string 
  868.      * @throws    Exception
  869.      */
  870.     private function _generateTableHeader($pSheet{
  871.         $sheetIndex $pSheet->getParent()->getIndex($pSheet);
  872.  
  873.         // Construct HTML
  874.         $html '';
  875.  
  876.         if (!$this->_useInlineCss{
  877.             $gridlines $pSheet->getShowGridLines(' gridlines' '';
  878.             $html .= '    <table border="0" cellpadding="0" cellspacing="0" id="sheet' $sheetIndex '" class="sheet' $sheetIndex $gridlines '">' PHP_EOL;
  879.         else {
  880.             $style = isset($this->_cssStyles['table']?
  881.                 $this->_assembleCSS($this->_cssStyles['table']'';
  882.  
  883.             if ($this->_isPdf && $pSheet->getShowGridLines()) {
  884.                 $html .= '    <table border="1" cellpadding="1" id="sheet' $sheetIndex '" cellspacing="4" style="' $style '">' PHP_EOL;
  885.             else {
  886.                 $html .= '    <table border="0" cellpadding="1" id="sheet' $sheetIndex '" cellspacing="4" style="' $style '">' PHP_EOL;
  887.             }
  888.         }
  889.  
  890.         // Write <col> elements
  891.         $highestColumnIndex PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()) 1;
  892.         $i = -1;
  893.         while($i++ < $highestColumnIndex{
  894.             if (!$this->_useInlineCss{
  895.                 $html .= '        <col class="col' $i '">' PHP_EOL;
  896.             else {
  897.                 $style = isset($this->_cssStyles['table.sheet' $sheetIndex ' col.col' $i]?
  898.                     $this->_assembleCSS($this->_cssStyles['table.sheet' $sheetIndex ' col.col' $i]'';
  899.                 $html .= '        <col style="' $style '">' PHP_EOL;
  900.             }
  901.         }
  902.  
  903.         // Return
  904.         return $html;
  905.     }
  906.  
  907.     /**
  908.      * Generate table footer
  909.      *
  910.      * @throws    Exception
  911.      */
  912.     private function _generateTableFooter({
  913.         // Construct HTML
  914.         $html '';
  915.         $html .= '    </table>' PHP_EOL;
  916.  
  917.         // Return
  918.         return $html;
  919.     }
  920.  
  921.     /**
  922.      * Generate row
  923.      *
  924.      * @param    PHPExcel_Worksheet    $pSheet            PHPExcel_Worksheet
  925.      * @param    array                $pValues        Array containing cells in a row
  926.      * @param    int                    $pRow            Row number (0-based)
  927.      * @return    string 
  928.      * @throws    Exception
  929.      */
  930.     private function _generateRow(PHPExcel_Worksheet $pSheet$pValues null$pRow 0{
  931.         if (is_array($pValues)) {
  932.             // Construct HTML
  933.             $html '';
  934.  
  935.             // Sheet index
  936.             $sheetIndex $pSheet->getParent()->getIndex($pSheet);
  937.  
  938.             // DomPDF and breaks
  939.             if ($this->_isPdf && count($pSheet->getBreaks()) 0{
  940.                 $breaks $pSheet->getBreaks();
  941.  
  942.                 // check if a break is needed before this row
  943.                 if (isset($breaks['A' $pRow])) {
  944.                     // close table: </table>
  945.                     $html .= $this->_generateTableFooter();
  946.  
  947.                     // insert page break
  948.                     $html .= '<div style="page-break-before:always" />';
  949.  
  950.                     // open table again: <table> + <col> etc.
  951.                     $html .= $this->_generateTableHeader($pSheet);
  952.                 }
  953.             }
  954.  
  955.             // Write row start
  956.             if (!$this->_useInlineCss{
  957.                 $html .= '          <tr class="row' $pRow '">' PHP_EOL;
  958.             else {
  959.                 $style = isset($this->_cssStyles['table.sheet' $sheetIndex ' tr.row' $pRow])
  960.                     ? $this->_assembleCSS($this->_cssStyles['table.sheet' $sheetIndex ' tr.row' $pRow]'';
  961.  
  962.                 $html .= '          <tr style="' $style '">' PHP_EOL;
  963.             }
  964.  
  965.             // Write cells
  966.             $colNum 0;
  967.             foreach ($pValues as $cell{
  968.                 $coordinate PHPExcel_Cell::stringFromColumnIndex($colNum($pRow 1);
  969.  
  970.                 if (!$this->_useInlineCss{
  971.                     $cssClass '';
  972.                     $cssClass 'column' $colNum;
  973.                 else {
  974.                     $cssClass array();
  975.                     if (isset($this->_cssStyles['table.sheet' $sheetIndex ' td.column' $colNum])) {
  976.                         $this->_cssStyles['table.sheet' $sheetIndex ' td.column' $colNum];
  977.                     }
  978.                 }
  979.                 $colSpan 1;
  980.                 $rowSpan 1;
  981.  
  982.                 // initialize
  983.                 $cellData '';
  984.  
  985.                 // PHPExcel_Cell
  986.                 if ($cell instanceof PHPExcel_Cell{
  987.                     if (is_null($cell->getParent())) {
  988.                         $cell->attach($pSheet);
  989.                     }
  990.                     // Value
  991.                     if ($cell->getValue(instanceof PHPExcel_RichText{
  992.                         // Loop through rich text elements
  993.                         $elements $cell->getValue()->getRichTextElements();
  994.                         foreach ($elements as $element{
  995.                             // Rich text start?
  996.                             if ($element instanceof PHPExcel_RichText_Run{
  997.                                 $cellData .= '<span style="' $this->_assembleCSS($this->_createCSSStyleFont($element->getFont())) '">';
  998.  
  999.                                 if ($element->getFont()->getSuperScript()) {
  1000.                                     $cellData .= '<sup>';
  1001.                                 else if ($element->getFont()->getSubScript()) {
  1002.                                     $cellData .= '<sub>';
  1003.                                 }
  1004.                             }
  1005.  
  1006.                             // Convert UTF8 data to PCDATA
  1007.                             $cellText $element->getText();
  1008.                             $cellData .= htmlspecialchars($cellText);
  1009.  
  1010.                             if ($element instanceof PHPExcel_RichText_Run{
  1011.                                 if ($element->getFont()->getSuperScript()) {
  1012.                                     $cellData .= '</sup>';
  1013.                                 else if ($element->getFont()->getSubScript()) {
  1014.                                     $cellData .= '</sub>';
  1015.                                 }
  1016.  
  1017.                                 $cellData .= '</span>';
  1018.                             }
  1019.                         }
  1020.                     else {
  1021.                         if ($this->_preCalculateFormulas{
  1022.                             $cellData PHPExcel_Style_NumberFormat::toFormattedString(
  1023.                                 $cell->getCalculatedValue(),
  1024.                                 $pSheet->getParent()->getCellXfByIndex$cell->getXfIndex() )->getNumberFormat()->getFormatCode(),
  1025.                                 array($this'formatColor')
  1026.                             );
  1027.                         else {
  1028.                             $cellData PHPExcel_Style_NumberFormat::ToFormattedString(
  1029.                                 $cell->getValue(),
  1030.                                 $pSheet->getParent()->getCellXfByIndex$cell->getXfIndex() )->getNumberFormat()->getFormatCode(),
  1031.                                 array($this'formatColor')
  1032.                             );
  1033.                         }
  1034.                         if ($pSheet->getParent()->getCellXfByIndex$cell->getXfIndex() )->getFont()->getSuperScript()) {
  1035.                             $cellData '<sup>'.$cellData.'</sup>';
  1036.                         elseif ($pSheet->getParent()->getCellXfByIndex$cell->getXfIndex() )->getFont()->getSubScript()) {
  1037.                             $cellData '<sub>'.$cellData.'</sub>';
  1038.                         }
  1039.                     }
  1040.  
  1041.                     // Converts the cell content so that spaces occuring at beginning of each new line are replaced by &nbsp;
  1042.                     // Example: "  Hello\n to the world" is converted to "&nbsp;&nbsp;Hello\n&nbsp;to the world"
  1043.                     $cellData preg_replace("/(?m)(?:^|\\G) /"'&nbsp;'$cellData);
  1044.  
  1045.                     // convert newline "\n" to '<br>'
  1046.                     $cellData nl2br($cellData);
  1047.  
  1048.                     // Extend CSS class?
  1049.                     if (!$this->_useInlineCss{
  1050.                         $cssClass .= ' style' $cell->getXfIndex();
  1051.                         $cssClass .= ' ' $cell->getDataType();
  1052.                     else {
  1053.                         if (isset($this->_cssStyles['td.style' $cell->getXfIndex()])) {
  1054.                             $cssClass array_merge($cssClass$this->_cssStyles['td.style' $cell->getXfIndex()]);
  1055.                         }
  1056.  
  1057.                         // General horizontal alignment: Actual horizontal alignment depends on dataType
  1058.                         $sharedStyle $pSheet->getParent()->getCellXfByIndex$cell->getXfIndex() );
  1059.                         if ($sharedStyle->getAlignment()->getHorizontal(== PHPExcel_Style_Alignment::HORIZONTAL_GENERAL
  1060.                             && isset($this->_cssStyles['.' $cell->getDataType()]['text-align']))
  1061.                         {
  1062.                             $cssClass['text-align'$this->_cssStyles['.' $cell->getDataType()]['text-align'];
  1063.                         }
  1064.                     }
  1065.                 }
  1066.  
  1067.                 // Hyperlink?
  1068.                 if ($pSheet->hyperlinkExists($coordinate&& !$pSheet->getHyperlink($coordinate)->isInternal()) {
  1069.                     $cellData '<a href="' htmlspecialchars($pSheet->getHyperlink($coordinate)->getUrl()) '" title="' htmlspecialchars($pSheet->getHyperlink($coordinate)->getTooltip()) '">' $cellData '</a>';
  1070.                 }
  1071.  
  1072.                 // Should the cell be written or is it swallowed by a rowspan or colspan?
  1073.                 $writeCell isset($this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow 1][$colNum])
  1074.                             && $this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow 1][$colNum);
  1075.  
  1076.                 // Colspan and Rowspan
  1077.                 $colspan 1;
  1078.                 $rowspan 1;
  1079.                 if (isset($this->_isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow 1][$colNum])) {
  1080.                     $spans $this->_isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow 1][$colNum];
  1081.                     $rowSpan $spans['rowspan'];
  1082.                     $colSpan $spans['colspan'];
  1083.                 }
  1084.  
  1085.                 // Write
  1086.                 if ($writeCell{
  1087.                     // Column start
  1088.                     $html .= '            <td';
  1089.                         if (!$this->_useInlineCss{
  1090.                             $html .= ' class="' $cssClass '"';
  1091.                         else {
  1092.                             //** Necessary redundant code for the sake of PHPExcel_Writer_PDF **
  1093.                             // We must explicitly write the width of the <td> element because TCPDF
  1094.                             // does not recognize e.g. <col style="width:42pt">
  1095.                             $width 0;
  1096.                             $i $colNum 1;
  1097.                             $e $colNum $colSpan 1;
  1098.                             while($i++ < $e{
  1099.                                 if (isset($this->_columnWidths[$sheetIndex][$i])) {
  1100.                                     $width += $this->_columnWidths[$sheetIndex][$i];
  1101.                                 }
  1102.                             }
  1103.                             $cssClass['width'$width 'pt';
  1104.  
  1105.                             // We must also explicitly write the height of the <td> element because TCPDF
  1106.                             // does not recognize e.g. <tr style="height:50pt">
  1107.                             if (isset($this->_cssStyles['table.sheet' $sheetIndex ' tr.row' $pRow]['height'])) {
  1108.                                 $height $this->_cssStyles['table.sheet' $sheetIndex ' tr.row' $pRow]['height'];
  1109.                                 $cssClass['height'$height;
  1110.                             }
  1111.                             //** end of redundant code **
  1112.  
  1113.                             $html .= ' style="' $this->_assembleCSS($cssClass'"';
  1114.                         }
  1115.                         if ($colSpan 1{
  1116.                             $html .= ' colspan="' $colSpan '"';
  1117.                         }
  1118.                         if ($rowSpan 1{
  1119.                             $html .= ' rowspan="' $rowSpan '"';
  1120.                         }
  1121.                     $html .= '>';
  1122.  
  1123.                     // Image?
  1124.                     $html .= $this->_writeImageTagInCell($pSheet$coordinate);
  1125.  
  1126.                     // Cell data
  1127.                     $html .= $cellData;
  1128.  
  1129.                     // Column end
  1130.                     $html .= '</td>' PHP_EOL;
  1131.                 }
  1132.  
  1133.                 // Next column
  1134.                 ++$colNum;
  1135.             }
  1136.  
  1137.             // Write row end
  1138.             $html .= '          </tr>' PHP_EOL;
  1139.  
  1140.             // Return
  1141.             return $html;
  1142.         else {
  1143.             throw new Exception("Invalid parameters passed.");
  1144.         }
  1145.     }
  1146.  
  1147.     /**
  1148.      * Takes array where of CSS properties / values and converts to CSS string
  1149.      *
  1150.      * @param array 
  1151.      * @return string 
  1152.      */
  1153.     private function _assembleCSS($pValue array())
  1154.     {
  1155.         $pairs array();
  1156.         foreach ($pValue as $property => $value{
  1157.             $pairs[$property ':' $value;
  1158.         }
  1159.         $string implode('; '$pairs);
  1160.  
  1161.         return $string;
  1162.     }
  1163.  
  1164.     /**
  1165.      * Get Pre-Calculate Formulas
  1166.      *
  1167.      * @return boolean 
  1168.      */
  1169.     public function getPreCalculateFormulas({
  1170.         return $this->_preCalculateFormulas;
  1171.     }
  1172.  
  1173.     /**
  1174.      * Set Pre-Calculate Formulas
  1175.      *
  1176.      * @param boolean $pValue    Pre-Calculate Formulas?
  1177.      * @return PHPExcel_Writer_HTML 
  1178.      */
  1179.     public function setPreCalculateFormulas($pValue true{
  1180.         $this->_preCalculateFormulas $pValue;
  1181.         return $this;
  1182.     }
  1183.  
  1184.     /**
  1185.      * Get images root
  1186.      *
  1187.      * @return string 
  1188.      */
  1189.     public function getImagesRoot({
  1190.         return $this->_imagesRoot;
  1191.     }
  1192.  
  1193.     /**
  1194.      * Set images root
  1195.      *
  1196.      * @param string $pValue 
  1197.      * @return PHPExcel_Writer_HTML 
  1198.      */
  1199.     public function setImagesRoot($pValue '.'{
  1200.         $this->_imagesRoot $pValue;
  1201.         return $this;
  1202.     }
  1203.  
  1204.     /**
  1205.      * Get use inline CSS?
  1206.      *
  1207.      * @return boolean 
  1208.      */
  1209.     public function getUseInlineCss({
  1210.         return $this->_useInlineCss;
  1211.     }
  1212.  
  1213.     /**
  1214.      * Set use inline CSS?
  1215.      *
  1216.      * @param boolean $pValue 
  1217.      * @return PHPExcel_Writer_HTML 
  1218.      */
  1219.     public function setUseInlineCss($pValue false{
  1220.         $this->_useInlineCss $pValue;
  1221.         return $this;
  1222.     }
  1223.  
  1224.     /**
  1225.      * Add color to formatted string as inline style
  1226.      *
  1227.      * @param string $pValue Plain formatted value without color
  1228.      * @param string $pFormat Format code
  1229.      * @return string 
  1230.      */
  1231.     public function formatColor($pValue$pFormat)
  1232.     {
  1233.         // Color information, e.g. [Red] is always at the beginning
  1234.         $color null// initialize
  1235.         $matches array();
  1236.  
  1237.         $color_regex '/^\\[[a-zA-Z]+\\]/';
  1238.         if (preg_match($color_regex$pFormat$matches)) {
  1239.             $color str_replace('['''$matches[0]);
  1240.             $color str_replace(']'''$color);
  1241.             $color strtolower($color);
  1242.         }
  1243.  
  1244.         // convert to PCDATA
  1245.         $value htmlspecialchars($pValue);
  1246.  
  1247.         // color span tag
  1248.         if ($color !== null{
  1249.             $value '<span style="color:' $color '">' $value '</span>';
  1250.         }
  1251.  
  1252.         return $value;
  1253.     }
  1254.  
  1255.     /**
  1256.      * Calculate information about HTML colspan and rowspan which is not always the same as Excel's
  1257.      */
  1258.     private function _calculateSpans()
  1259.     {
  1260.         // Identify all cells that should be omitted in HTML due to cell merge.
  1261.         // In HTML only the upper-left cell should be written and it should have
  1262.         //   appropriate rowspan / colspan attribute
  1263.         $sheetIndexes $this->_sheetIndex !== null ?
  1264.             array($this->_sheetIndexrange(0$this->_phpExcel->getSheetCount(1);
  1265.  
  1266.         foreach ($sheetIndexes as $sheetIndex{
  1267.             $sheet $this->_phpExcel->getSheet($sheetIndex);
  1268.  
  1269.             $candidateSpannedRow  array();
  1270.  
  1271.             // loop through all Excel merged cells
  1272.             foreach ($sheet->getMergeCells(as $cells{
  1273.                 list($cellsPHPExcel_Cell::splitRange($cells);
  1274.                 $first $cells[0];
  1275.                 $last  $cells[1];
  1276.  
  1277.                 list($fc$frPHPExcel_Cell::coordinateFromString($first);
  1278.                 $fc PHPExcel_Cell::columnIndexFromString($fc1;
  1279.  
  1280.                 list($lc$lrPHPExcel_Cell::coordinateFromString($last);
  1281.                 $lc PHPExcel_Cell::columnIndexFromString($lc1;
  1282.  
  1283.                 // loop through the individual cells in the individual merge
  1284.                 $r $fr 1;
  1285.                 while($r++ < $lr{
  1286.                     // also, flag this row as a HTML row that is candidate to be omitted
  1287.                     $candidateSpannedRow[$r$r;
  1288.  
  1289.                     $c $fc 1;
  1290.                     while($c++ < $lc{
  1291.                         if !($c == $fc && $r == $fr) ) {
  1292.                             // not the upper-left cell (should not be written in HTML)
  1293.                             $this->_isSpannedCell[$sheetIndex][$r][$carray(
  1294.                                 'baseCell' => array($fr$fc),
  1295.                             );
  1296.                         else {
  1297.                             // upper-left is the base cell that should hold the colspan/rowspan attribute
  1298.                             $this->_isBaseCell[$sheetIndex][$r][$carray(
  1299.                                 'xlrowspan' => $lr $fr 1// Excel rowspan
  1300.                                 'rowspan'   => $lr $fr 1// HTML rowspan, value may change
  1301.                                 'xlcolspan' => $lc $fc 1// Excel colspan
  1302.                                 'colspan'   => $lc $fc 1// HTML colspan, value may change
  1303.                             );
  1304.                         }
  1305.                     }
  1306.                 }
  1307.             }
  1308.  
  1309.             // Identify which rows should be omitted in HTML. These are the rows where all the cells
  1310.             //   participate in a merge and the where base cells are somewhere above.
  1311.             $countColumns PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn());
  1312.             foreach ($candidateSpannedRow as $rowIndex{
  1313.                 if (isset($this->_isSpannedCell[$sheetIndex][$rowIndex])) {
  1314.                     if (count($this->_isSpannedCell[$sheetIndex][$rowIndex]== $countColumns{
  1315.                         $this->_isSpannedRow[$sheetIndex][$rowIndex$rowIndex;
  1316.                     };
  1317.                 }
  1318.             }
  1319.  
  1320.             // For each of the omitted rows we found above, the affected rowspans should be subtracted by 1
  1321.             if isset($this->_isSpannedRow[$sheetIndex]) ) {
  1322.                 foreach ($this->_isSpannedRow[$sheetIndexas $rowIndex{
  1323.                     $adjustedBaseCells array();
  1324.                     $c = -1;
  1325.                     $e $countColumns 1;
  1326.                     while($c++ < $e{
  1327.                         $baseCell $this->_isSpannedCell[$sheetIndex][$rowIndex][$c]['baseCell'];
  1328.  
  1329.                         if !in_array($baseCell$adjustedBaseCells) ) {
  1330.                             // subtract rowspan by 1
  1331.                             --$this->_isBaseCell[$sheetIndex]$baseCell[0] ]$baseCell[1] ]['rowspan'];
  1332.                             $adjustedBaseCells[$baseCell;
  1333.                         }
  1334.                     }
  1335.                 }
  1336.             }
  1337.  
  1338.             // TODO: Same for columns
  1339.         }
  1340.  
  1341.         // We have calculated the spans
  1342.         $this->_spansAreCalculated true;
  1343.     }
  1344.  
  1345. }

Documentation generated on Sun, 27 Feb 2011 16:32:22 -0800 by phpDocumentor 1.4.3