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

Documentation generated on Thu, 26 Aug 2010 17:43:21 +0200 by phpDocumentor 1.4.3