Source for file HTML.php
Documentation is available at HTML.php
* Copyright (c) 2006 - 2009 PHPExcel
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* @package PHPExcel_Writer
* @copyright Copyright (c) 2006 - 2009 PHPExcel (http://www.codeplex.com/PHPExcel)
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
* @version 1.6.7, 2009-04-22
require_once 'PHPExcel/Writer/IWriter.php';
require_once 'PHPExcel/Cell.php';
require_once 'PHPExcel/RichText.php';
/** PHPExcel_Shared_Drawing */
require_once 'PHPExcel/Shared/Drawing.php';
/** PHPExcel_Shared_String */
require_once 'PHPExcel/Shared/String.php';
/** PHPExcel_HashTable */
require_once 'PHPExcel/HashTable.php';
* @package PHPExcel_Writer
* @copyright Copyright (c) 2006 - 2009 PHPExcel (http://www.codeplex.com/PHPExcel)
* Array of column widths in points
* Create a new PHPExcel_Writer_HTML
* @param PHPExcel $phpExcel PHPExcel object
* @param string $pFileName
public function save($pFilename = null) {
$fileHandle = fopen($pFilename, 'w');
if ($fileHandle === false) {
throw new Exception("Could not open file $pFilename for writing.");
default: return ' baseline';
default: return '1px solid'; // map others to thin
* @param int $pValue Sheet index
* Write all sheets (resets sheetIndex to NULL)
* @param boolean $pIncludeStyles Include styles?
// PHPExcel object known?
throw new Exception('Internal PHPExcel object not set to an instance of an object.');
$html .= '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' . "\r\n";
$html .= '<!-- Generated by PHPExcel - http://www.phpexcel.net -->' . "\r\n";
$html .= '<html>' . "\r\n";
$html .= ' <head>' . "\r\n";
$html .= ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . "\r\n";
$html .= ' </head>' . "\r\n";
$html .= ' <body>' . "\r\n";
// PHPExcel object known?
throw new Exception('Internal PHPExcel object not set to an instance of an object.');
foreach ($sheets as $sheet) {
$cellCollection = $sheet->getCellCollection();
// Get worksheet dimension
$dimension = explode(':', $sheet->calculateWorksheetDimension());
for ($row = $dimension[0][1]; $row <= $dimension[1][1]; ++ $row) {
for ($column = $dimension[0][0]; $column <= $dimension[1][0]; ++ $column) {
if ($sheet->cellExistsByColumnAndRow($column, $row)) {
$rowData[$column] = $sheet->getCellByColumnAndRow($column, $row);
* Generate image tag in cell
* @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet
* @param string $coordinates Cell coordinates
foreach ($pSheet->getDrawingCollection() as $drawing) {
if ($drawing->getCoordinates() == $coordinates) {
$filename = $drawing->getPath();
// Strip off eventual '.'
if (substr($filename, 0, 1) == '.') {
$filename = substr($filename, 1);
// Strip off eventual '.'
if (substr($filename, 0, 1) == '.' && substr($filename, 0, 2) != './') {
$filename = substr($filename, 1);
// Convert UTF8 data to PCDATA
$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";
* @param boolean $generateSurroundingHTML Generate surrounding HTML tags? (<style> and </style>)
// PHPExcel object known?
throw new Exception('Internal PHPExcel object not set to an instance of an object.');
$css = $this->buildCSS($generateSurroundingHTML);
if ($generateSurroundingHTML) {
$html .= ' <style type="text/css">' . "\r\n";
$html .= ' html { ' . $css['html'] . ' }' . "\r\n";
// Write all other styles
foreach ($css as $styleName => $styleDefinition) {
if ($styleName != 'html') {
if (substr($styleName, 0, 5) == 'style') {
$styleName = '.' . $styleName;
$html .= ' ' . $styleName . ' { ' . $styleDefinition . ' }' . "\r\n";
if ($generateSurroundingHTML) {
$html .= ' </style>' . "\r\n";
* @param boolean $generateSurroundingHTML Generate surrounding HTML style? (html { })
public function buildCSS($generateSurroundingHTML = true) {
// PHPExcel object known?
throw new Exception('Internal PHPExcel object not set to an instance of an object.');
if ($generateSurroundingHTML) {
$css['html'] = 'font-family: Calibri, Arial, Helvetica, sans-serif; ';
$css['html'] .= 'font-size: 10pt; ';
$css['html'] .= 'background-color: white; ';
// Build styles per sheet
foreach ($sheets as $sheet) {
$hashCode = $sheet->getHashCode();
$css['table.sheet' . $hashCode] = '';
if ($sheet->getShowGridlines()) {
$css['table.sheet' . $hashCode] .= 'border: 1px dotted black; ';
$css['table.sheet' . $hashCode] .= 'page-break-after: always; ';
// table.sheetXXXXXX td { }
$css['table.sheet' . $hashCode . ' td'] = $css['table.sheet' . $hashCode];
// Calculate column widths
$sheet->calculateColumnWidths();
// col elements, initialize
for ($column = 0; $column <= $highestColumnIndex; ++ $column) {
$css['table.sheet' . $hashCode . ' col.col' . $column] = 'width: 42pt';
// col elements, loop through columnDimensions and set width
foreach ($sheet->getColumnDimensions() as $columnDimension) {
$css['table.sheet' . $hashCode . ' col.col' . $column] = 'width: ' . $width . 'pt; ';
if ($columnDimension->getVisible() === false) {
$css['table.sheet' . $hashCode . ' col.col' . $column] .= 'visibility: collapse; ';
$css['table.sheet' . $hashCode . ' col.col' . $column] .= '*display: none; '; // target IE6+7
$rowDimension = $sheet->getDefaultRowDimension();
// table.sheetXXXXXX tr { }
$css['table.sheet' . $hashCode . ' tr'] = '';
// height is disproportionately large
$css['table.sheet' . $hashCode . ' tr'] .= 'height: ' . $px_height . 'px; ';
if ($rowDimension->getVisible() === false) {
$css['table.sheet' . $hashCode . ' tr'] .= 'display: none; ';
$css['table.sheet' . $hashCode . ' tr'] .= 'visibility: hidden; ';
foreach ($sheet->getRowDimensions() as $rowDimension) {
// table.sheetXXXXXX tr.rowYYYYYY { }
$css['table.sheet' . $hashCode . ' tr.row' . ($rowDimension->getRowIndex() - 1)] = '';
// height is disproportionately large
$css['table.sheet' . $hashCode . ' tr.row' . ($rowDimension->getRowIndex() - 1)] .= 'height: ' . $px_height . 'px; ';
if ($rowDimension->getVisible() === false) {
$css['table.sheet' . $hashCode . ' tr.row' . ($rowDimension->getRowIndex() - 1)] .= 'display: none; ';
$css['table.sheet' . $hashCode . ' tr.row' . ($rowDimension->getRowIndex() - 1)] .= 'visibility: hidden; ';
$css['.b'] = 'text-align: center; '; // BOOL
$css['.e'] = 'text-align: center; '; // ERROR
$css['.f'] = 'text-align: right; '; // FORMULA
$css['.inlineStr'] = 'text-align: left; '; // INLINE
$css['.n'] = 'text-align: right; '; // NUMERIC
$css['.s'] = 'text-align: left; '; // STRING
// Calculate cell style hashes
$aStyles = $sheet->getStyles();
$cellStyleHashes->addFromSource( $aStyles );
foreach ($aStyles as $style) {
if(isset ($addedStyles[$style->getHashIndex()])) continue;
$addedStyles[$style->getHashIndex()] = true;
* @param PHPExcel_Style $pStyle PHPExcel_Style
* Create CSS style (PHPExcel_Style_Alignment)
* @param PHPExcel_Style_Alignment $pStyle PHPExcel_Style_Alignment
$css .= 'vertical-align: ' . $this->_mapVAlign($pStyle->getVertical()) . '; ';
if ($textAlign = $this->_mapHAlign($pStyle->getHorizontal())) {
$css .= 'text-align: ' . $textAlign . '; ';
* Create CSS style (PHPExcel_Style_Font)
* @param PHPExcel_Style_Font $pStyle PHPExcel_Style_Font
if ($pStyle->getBold()) {
$css .= 'font-weight: bold; ';
if ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE && $pStyle->getStrikethrough()) {
$css .= 'text-decoration: underline line-through; ';
$css .= 'text-decoration: underline; ';
} else if ($pStyle->getStrikethrough()) {
$css .= 'text-decoration: line-through; ';
if ($pStyle->getItalic()) {
$css .= 'font-style: italic; ';
$css .= 'color: ' . '#' . $pStyle->getColor()->getRGB() . '; ';
$css .= 'font-family: ' . $pStyle->getName() . '; ';
$css .= 'font-size: ' . $pStyle->getSize() . 'pt; ';
* Create CSS style (PHPExcel_Style_Borders)
* @param PHPExcel_Style_Borders $pStyle PHPExcel_Style_Borders
* Create CSS style (PHPExcel_Style_Border)
* @param PHPExcel_Style_Border $pStyle PHPExcel_Style_Border
$css .= $this->_mapBorderStyle($pStyle->getBorderStyle()) . ' #' . $pStyle->getColor()->getRGB();
* Create CSS style (PHPExcel_Style_Fill)
* @param PHPExcel_Style_Fill $pStyle PHPExcel_Style_Fill
'white' : '#' . $pStyle->getStartColor()->getRGB();
$css .= 'background-color: ' . $value . '; ';
$html .= ' </body>' . "\r\n";
$html .= '</html>' . "\r\n";
* @param PHPExcel_Worksheet $pSheet The worksheet for the table we are writing
$identifier = $pSheet->getHashCode();
$html .= ' <table border="0" cellpadding="0" cellspacing="0" class="sheet' . $identifier . '">' . "\r\n";
$style = isset ($this->_cssStyles['table.sheet' . $identifier]) ? $this->_cssStyles['table.sheet' . $identifier] : '';
$html .= ' <table border="0" cellpadding="0" cellspacing="0" style="' . $style . '">' . "\r\n";
for ($i = 0; $i <= $highestColumnIndex; ++ $i) {
$html .= ' <col class="col' . $i . '">' . "\r\n";
$style = isset ($this->_cssStyles['table.sheet' . $identifier]) ?
$this->_cssStyles['table.sheet' . $identifier . ' col.col' . $i] : '';
$html .= ' <col style="' . $style . '">' . "\r\n";
$html .= ' </table>' . "\r\n";
* @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet
* @param array $pValues Array containing cells in a row
* @param int $pRow Row number
private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow = 0) {
$sheetHash = $pSheet->getHashCode();
$html .= ' <tr class="row' . $pRow . '">' . "\r\n";
$style = isset ($this->_cssStyles['table.sheet' . $sheetHash . ' tr.row' . $pRow]) ? $this->_cssStyles['table.sheet' . $sheetHash . ' tr.row' . $pRow] : '';
$html .= ' <tr style="' . $style . '">' . "\r\n";
foreach ($pValues as $cell) {
$cssClass = 'column' . $colNum;
$cssClass = isset ($this->_cssStyles['table.sheet' . $sheetHash . ' td.column' . $colNum]) ? $this->_cssStyles['table.sheet' . $sheetHash . ' td.column' . $colNum] : '';
$writeCell = true; // Write cell
// Loop trough rich text elements
$elements = $cell->getValue()->getRichTextElements();
foreach ($elements as $element) {
$cellData .= '<span style="' .
if ($element->getFont()->getSuperScript()) {
} else if ($element->getFont()->getSubScript()) {
// Convert UTF8 data to PCDATA
$cellText = $element->getText();
if ($element->getFont()->getSuperScript()) {
} else if ($element->getFont()->getSubScript()) {
$cell->getCalculatedValue(),
$pSheet->getstyle( $cell->getCoordinate() )->getNumberFormat()->getFormatCode()
$pSheet->getstyle( $cell->getCoordinate() )->getNumberFormat()->getFormatCode()
// Convert UTF8 data to PCDATA
$cssClass .= ' style' . $pSheet->getStyle($cell->getCoordinate())->getHashIndex();
$cssClass .= ' ' . $cell->getDataType();
$cssClass .= isset ($this->_cssStyles['style' . $pSheet->getStyle($cell->getCoordinate())->getHashIndex()]) ?
$this->_cssStyles['style' . $pSheet->getStyle($cell->getCoordinate())->getHashIndex()] : '';
// General horizontal alignment: Actual horizontal alignment depends on dataType
if ($pSheet->getStyle($cell->getCoordinate())->getAlignment()->getHorizontal() == PHPExcel_Style_Alignment::HORIZONTAL_GENERAL
&& isset ($this->_cssStyles['.' . $cell->getDataType()]))
if (preg_match('/text-align: [^;]*;/', $cssClass)) {
$cssClass .= $this->_cssStyles['.' . $cell->getDataType()];
if ($cell->hasHyperlink() && !$cell->getHyperlink()->isInternal()) {
$cellData = '<a href="' . htmlspecialchars($cell->getHyperlink()->getUrl()) . '" title="' . htmlspecialchars($cell->getHyperlink()->getTooltip()) . '">' . $cellData . '</a>';
foreach ($pSheet->getMergeCells() as $cells) {
if ($cell->isInRange($cells)) {
if ($first[0] == $cell->getCoordinate()) {
$html .= ' class="' . $cssClass . '"';
//** Necessary redundant code for the sake of PHPExcel_Writer_PDF **
// We must explicitly write the width of the <td> element because TCPDF
// does not recognize e.g. <col style="width:42pt">;
for ($i = $columnIndex; $i < $columnIndex + $colSpan; ++ $i) {
$cssClass .= 'width: ' . $width . 'pt; ';
//** end of redundant code **
$html .= ' style="' . $cssClass . '"';
$html .= ' colspan="' . $colSpan . '"';
$html .= ' rowspan="' . $rowSpan . '"';
$html .= '</td>' . "\r\n";
$html .= ' </tr>' . "\r\n";
throw new Exception("Invalid parameters passed.");
* Get Pre-Calculate Formulas
* Set Pre-Calculate Formulas
* @param boolean $pValue Pre-Calculate Formulas?
|