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

Documentation generated on Tue, 01 Jun 2010 17:05:00 +0200 by phpDocumentor 1.4.3