vr-shopxo-source/extend/phpexcel/PHPExcel/Writer/HTML.php

1613 lines
58 KiB
PHP
Raw Normal View History

2018-12-28 10:58:37 +00:00
<?php
/**
* PHPExcel_Writer_HTML
*
* Copyright (c) 2006 - 2015 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
*
* @category PHPExcel
* @package PHPExcel_Writer_HTML
* @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
* @version ##VERSION##, ##DATE##
*/
class PHPExcel_Writer_HTML extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter
{
/**
* PHPExcel object
*
* @var PHPExcel
*/
protected $phpExcel;
/**
* Sheet index to write
*
* @var int
*/
private $sheetIndex = 0;
/**
* Images root
*
* @var string
*/
private $imagesRoot = '.';
/**
* embed images, or link to images
*
* @var boolean
*/
private $embedImages = false;
/**
* Use inline CSS?
*
* @var boolean
*/
private $useInlineCss = false;
/**
* Array of CSS styles
*
* @var array
*/
private $cssStyles;
/**
* Array of column widths in points
*
* @var array
*/
private $columnWidths;
/**
* Default font
*
* @var PHPExcel_Style_Font
*/
private $defaultFont;
/**
* Flag whether spans have been calculated
*
* @var boolean
*/
private $spansAreCalculated = false;
/**
* Excel cells that should not be written as HTML cells
*
* @var array
*/
private $isSpannedCell = array();
/**
* Excel cells that are upper-left corner in a cell merge
*
* @var array
*/
private $isBaseCell = array();
/**
* Excel rows that should not be written as HTML rows
*
* @var array
*/
private $isSpannedRow = array();
/**
* Is the current writer creating PDF?
*
* @var boolean
*/
protected $isPdf = false;
/**
* Generate the Navigation block
*
* @var boolean
*/
private $generateSheetNavigationBlock = true;
/**
* Create a new PHPExcel_Writer_HTML
*
* @param PHPExcel $phpExcel PHPExcel object
*/
public function __construct(PHPExcel $phpExcel)
{
$this->phpExcel = $phpExcel;
$this->defaultFont = $this->phpExcel->getDefaultStyle()->getFont();
}
/**
* Save PHPExcel to file
*
* @param string $pFilename
* @throws PHPExcel_Writer_Exception
*/
public function save($pFilename = null)
{
// garbage collect
$this->phpExcel->garbageCollect();
$saveDebugLog = PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->getWriteDebugLog();
PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog(false);
$saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType();
PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE);
// Build CSS
$this->buildCSS(!$this->useInlineCss);
// Open file
$fileHandle = fopen($pFilename, 'wb+');
if ($fileHandle === false) {
throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing.");
}
// Write headers
fwrite($fileHandle, $this->generateHTMLHeader(!$this->useInlineCss));
// Write navigation (tabs)
if ((!$this->isPdf) && ($this->generateSheetNavigationBlock)) {
fwrite($fileHandle, $this->generateNavigation());
}
// Write data
fwrite($fileHandle, $this->generateSheetData());
// Write footer
fwrite($fileHandle, $this->generateHTMLFooter());
// Close file
fclose($fileHandle);
PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType);
PHPExcel_Calculation::getInstance($this->phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog);
}
/**
* Map VAlign
*
* @param string $vAlign Vertical alignment
* @return string
*/
private function mapVAlign($vAlign)
{
switch ($vAlign) {
case PHPExcel_Style_Alignment::VERTICAL_BOTTOM:
return 'bottom';
case PHPExcel_Style_Alignment::VERTICAL_TOP:
return 'top';
case PHPExcel_Style_Alignment::VERTICAL_CENTER:
case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY:
return 'middle';
default:
return 'baseline';
}
}
/**
* Map HAlign
*
* @param string $hAlign Horizontal alignment
* @return string|false
*/
private function mapHAlign($hAlign)
{
switch ($hAlign) {
case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL:
return false;
case PHPExcel_Style_Alignment::HORIZONTAL_LEFT:
return 'left';
case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT:
return 'right';
case PHPExcel_Style_Alignment::HORIZONTAL_CENTER:
case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS:
return 'center';
case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY:
return 'justify';
default:
return false;
}
}
/**
* Map border style
*
* @param int $borderStyle Sheet index
* @return string
*/
private function mapBorderStyle($borderStyle)
{
switch ($borderStyle) {
case PHPExcel_Style_Border::BORDER_NONE:
return 'none';
case PHPExcel_Style_Border::BORDER_DASHDOT:
return '1px dashed';
case PHPExcel_Style_Border::BORDER_DASHDOTDOT:
return '1px dotted';
case PHPExcel_Style_Border::BORDER_DASHED:
return '1px dashed';
case PHPExcel_Style_Border::BORDER_DOTTED:
return '1px dotted';
case PHPExcel_Style_Border::BORDER_DOUBLE:
return '3px double';
case PHPExcel_Style_Border::BORDER_HAIR:
return '1px solid';
case PHPExcel_Style_Border::BORDER_MEDIUM:
return '2px solid';
case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT:
return '2px dashed';
case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT:
return '2px dotted';
case PHPExcel_Style_Border::BORDER_MEDIUMDASHED:
return '2px dashed';
case PHPExcel_Style_Border::BORDER_SLANTDASHDOT:
return '2px dashed';
case PHPExcel_Style_Border::BORDER_THICK:
return '3px solid';
case PHPExcel_Style_Border::BORDER_THIN:
return '1px solid';
default:
// map others to thin
return '1px solid';
}
}
/**
* Get sheet index
*
* @return int
*/
public function getSheetIndex()
{
return $this->sheetIndex;
}
/**
* Set sheet index
*
* @param int $pValue Sheet index
* @return PHPExcel_Writer_HTML
*/
public function setSheetIndex($pValue = 0)
{
$this->sheetIndex = $pValue;
return $this;
}
/**
* Get sheet index
*
* @return boolean
*/
public function getGenerateSheetNavigationBlock()
{
return $this->generateSheetNavigationBlock;
}
/**
* Set sheet index
*
* @param boolean $pValue Flag indicating whether the sheet navigation block should be generated or not
* @return PHPExcel_Writer_HTML
*/
public function setGenerateSheetNavigationBlock($pValue = true)
{
$this->generateSheetNavigationBlock = (bool) $pValue;
return $this;
}
/**
* Write all sheets (resets sheetIndex to NULL)
*/
public function writeAllSheets()
{
$this->sheetIndex = null;
return $this;
}
/**
* Generate HTML header
*
* @param boolean $pIncludeStyles Include styles?
* @return string
* @throws PHPExcel_Writer_Exception
*/
public function generateHTMLHeader($pIncludeStyles = false)
{
// PHPExcel object known?
if (is_null($this->phpExcel)) {
throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.');
}
// Construct HTML
$properties = $this->phpExcel->getProperties();
$html = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' . PHP_EOL;
$html .= '<!-- Generated by PHPExcel - http://www.phpexcel.net -->' . PHP_EOL;
$html .= '<html>' . PHP_EOL;
$html .= ' <head>' . PHP_EOL;
$html .= ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . PHP_EOL;
if ($properties->getTitle() > '') {
$html .= ' <title>' . htmlspecialchars($properties->getTitle()) . '</title>' . PHP_EOL;
}
if ($properties->getCreator() > '') {
$html .= ' <meta name="author" content="' . htmlspecialchars($properties->getCreator()) . '" />' . PHP_EOL;
}
if ($properties->getTitle() > '') {
$html .= ' <meta name="title" content="' . htmlspecialchars($properties->getTitle()) . '" />' . PHP_EOL;
}
if ($properties->getDescription() > '') {
$html .= ' <meta name="description" content="' . htmlspecialchars($properties->getDescription()) . '" />' . PHP_EOL;
}
if ($properties->getSubject() > '') {
$html .= ' <meta name="subject" content="' . htmlspecialchars($properties->getSubject()) . '" />' . PHP_EOL;
}
if ($properties->getKeywords() > '') {
$html .= ' <meta name="keywords" content="' . htmlspecialchars($properties->getKeywords()) . '" />' . PHP_EOL;
}
if ($properties->getCategory() > '') {
$html .= ' <meta name="category" content="' . htmlspecialchars($properties->getCategory()) . '" />' . PHP_EOL;
}
if ($properties->getCompany() > '') {
$html .= ' <meta name="company" content="' . htmlspecialchars($properties->getCompany()) . '" />' . PHP_EOL;
}
if ($properties->getManager() > '') {
$html .= ' <meta name="manager" content="' . htmlspecialchars($properties->getManager()) . '" />' . PHP_EOL;
}
if ($pIncludeStyles) {
$html .= $this->generateStyles(true);
}
$html .= ' </head>' . PHP_EOL;
$html .= '' . PHP_EOL;
$html .= ' <body>' . PHP_EOL;
return $html;
}
/**
* Generate sheet data
*
* @return string
* @throws PHPExcel_Writer_Exception
*/
public function generateSheetData()
{
// PHPExcel object known?
if (is_null($this->phpExcel)) {
throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.');
}
// Ensure that Spans have been calculated?
if ($this->sheetIndex !== null || !$this->spansAreCalculated) {
$this->calculateSpans();
}
// Fetch sheets
$sheets = array();
if (is_null($this->sheetIndex)) {
$sheets = $this->phpExcel->getAllSheets();
} else {
$sheets[] = $this->phpExcel->getSheet($this->sheetIndex);
}
// Construct HTML
$html = '';
// Loop all sheets
$sheetId = 0;
foreach ($sheets as $sheet) {
// Write table header
$html .= $this->generateTableHeader($sheet);
// Get worksheet dimension
$dimension = explode(':', $sheet->calculateWorksheetDimension());
$dimension[0] = PHPExcel_Cell::coordinateFromString($dimension[0]);
$dimension[0][0] = PHPExcel_Cell::columnIndexFromString($dimension[0][0]) - 1;
$dimension[1] = PHPExcel_Cell::coordinateFromString($dimension[1]);
$dimension[1][0] = PHPExcel_Cell::columnIndexFromString($dimension[1][0]) - 1;
// row min,max
$rowMin = $dimension[0][1];
$rowMax = $dimension[1][1];
// calculate start of <tbody>, <thead>
$tbodyStart = $rowMin;
$theadStart = $theadEnd = 0; // default: no <thead> no </thead>
if ($sheet->getPageSetup()->isRowsToRepeatAtTopSet()) {
$rowsToRepeatAtTop = $sheet->getPageSetup()->getRowsToRepeatAtTop();
// we can only support repeating rows that start at top row
if ($rowsToRepeatAtTop[0] == 1) {
$theadStart = $rowsToRepeatAtTop[0];
$theadEnd = $rowsToRepeatAtTop[1];
$tbodyStart = $rowsToRepeatAtTop[1] + 1;
}
}
// Loop through cells
$row = $rowMin-1;
while ($row++ < $rowMax) {
// <thead> ?
if ($row == $theadStart) {
$html .= ' <thead>' . PHP_EOL;
$cellType = 'th';
}
// <tbody> ?
if ($row == $tbodyStart) {
$html .= ' <tbody>' . PHP_EOL;
$cellType = 'td';
}
// Write row if there are HTML table cells in it
if (!isset($this->isSpannedRow[$sheet->getParent()->getIndex($sheet)][$row])) {
// Start a new rowData
$rowData = array();
// Loop through columns
$column = $dimension[0][0] - 1;
while ($column++ < $dimension[1][0]) {
// Cell exists?
if ($sheet->cellExistsByColumnAndRow($column, $row)) {
$rowData[$column] = PHPExcel_Cell::stringFromColumnIndex($column) . $row;
} else {
$rowData[$column] = '';
}
}
$html .= $this->generateRow($sheet, $rowData, $row - 1, $cellType);
}
// </thead> ?
if ($row == $theadEnd) {
$html .= ' </thead>' . PHP_EOL;
}
}
$html .= $this->extendRowsForChartsAndImages($sheet, $row);
// Close table body.
$html .= ' </tbody>' . PHP_EOL;
// Write table footer
$html .= $this->generateTableFooter();
// Writing PDF?
if ($this->isPdf) {
if (is_null($this->sheetIndex) && $sheetId + 1 < $this->phpExcel->getSheetCount()) {
$html .= '<div style="page-break-before:always" />';
}
}
// Next sheet
++$sheetId;
}
return $html;
}
/**
* Generate sheet tabs
*
* @return string
* @throws PHPExcel_Writer_Exception
*/
public function generateNavigation()
{
// PHPExcel object known?
if (is_null($this->phpExcel)) {
throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.');
}
// Fetch sheets
$sheets = array();
if (is_null($this->sheetIndex)) {
$sheets = $this->phpExcel->getAllSheets();
} else {
$sheets[] = $this->phpExcel->getSheet($this->sheetIndex);
}
// Construct HTML
$html = '';
// Only if there are more than 1 sheets
if (count($sheets) > 1) {
// Loop all sheets
$sheetId = 0;
$html .= '<ul class="navigation">' . PHP_EOL;
foreach ($sheets as $sheet) {
$html .= ' <li class="sheet' . $sheetId . '"><a href="#sheet' . $sheetId . '">' . $sheet->getTitle() . '</a></li>' . PHP_EOL;
++$sheetId;
}
$html .= '</ul>' . PHP_EOL;
}
return $html;
}
private function extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row)
{
$rowMax = $row;
$colMax = 'A';
if ($this->includeCharts) {
foreach ($pSheet->getChartCollection() as $chart) {
if ($chart instanceof PHPExcel_Chart) {
$chartCoordinates = $chart->getTopLeftPosition();
$chartTL = PHPExcel_Cell::coordinateFromString($chartCoordinates['cell']);
$chartCol = PHPExcel_Cell::columnIndexFromString($chartTL[0]);
if ($chartTL[1] > $rowMax) {
$rowMax = $chartTL[1];
if ($chartCol > PHPExcel_Cell::columnIndexFromString($colMax)) {
$colMax = $chartTL[0];
}
}
}
}
}
foreach ($pSheet->getDrawingCollection() as $drawing) {
if ($drawing instanceof PHPExcel_Worksheet_Drawing) {
$imageTL = PHPExcel_Cell::coordinateFromString($drawing->getCoordinates());
$imageCol = PHPExcel_Cell::columnIndexFromString($imageTL[0]);
if ($imageTL[1] > $rowMax) {
$rowMax = $imageTL[1];
if ($imageCol > PHPExcel_Cell::columnIndexFromString($colMax)) {
$colMax = $imageTL[0];
}
}
}
}
$html = '';
$colMax++;
while ($row <= $rowMax) {
$html .= '<tr>';
for ($col = 'A'; $col != $colMax; ++$col) {
$html .= '<td>';
$html .= $this->writeImageInCell($pSheet, $col.$row);
if ($this->includeCharts) {
$html .= $this->writeChartInCell($pSheet, $col.$row);
}
$html .= '</td>';
}
++$row;
$html .= '</tr>';
}
return $html;
}
/**
* Generate image tag in cell
*
* @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet
* @param string $coordinates Cell coordinates
* @return string