| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612 | <?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     * @throws    PHPExcel_Writer_Exception     */    private function writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates)    {        // Construct HTML        $html = '';        // Write images        foreach ($pSheet->getDrawingCollection() as $drawing) {            if ($drawing instanceof PHPExcel_Worksheet_Drawing) {                if ($drawing->getCoordinates() == $coordinates) {                    $filename = $drawing->getPath();                    // Strip off eventual '.'                    if (substr($filename, 0, 1) == '.') {                        $filename = substr($filename, 1);                    }                    // Prepend images root                    $filename = $this->getImagesRoot() . $filename;                    // Strip off eventual '.'                    if (substr($filename, 0, 1) == '.' && substr($filename, 0, 2) != './') {                        $filename = substr($filename, 1);                    }                    // Convert UTF8 data to PCDATA                    $filename = htmlspecialchars($filename);                    $html .= PHP_EOL;                    if ((!$this->embedImages) || ($this->isPdf)) {                        $imageData = $filename;                    } else {                        $imageDetails = getimagesize($filename);                        if ($fp = fopen($filename, "rb", 0)) {                            $picture = fread($fp, filesize($filename));                            fclose($fp);                            // base64 encode the binary data, then break it                            // into chunks according to RFC 2045 semantics                            $base64 = chunk_split(base64_encode($picture));                            $imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64;                        } else {                            $imageData = $filename;                        }                    }                    $html .= '<div style="position: relative;">';                    $html .= '<img style="position: absolute; z-index: 1; left: ' .                        $drawing->getOffsetX() . 'px; top: ' . $drawing->getOffsetY() . 'px; width: ' .                        $drawing->getWidth() . 'px; height: ' . $drawing->getHeight() . 'px;" src="' .                        $imageData . '" border="0" />';                    $html .= '</div>';                }            } elseif ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) {                if ($drawing->getCoordinates() != $coordinates) {                    continue;                }                ob_start();                                //  Let's start output buffering.                imagepng($drawing->getImageResource());    //  This will normally output the image, but because of ob_start(), it won't.                $contents = ob_get_contents();             //  Instead, output above is saved to $contents                ob_end_clean();                            //  End the output buffer.                $dataUri = "data:image/jpeg;base64," . base64_encode($contents);                //  Because of the nature of tables, width is more important than height.                //  max-width: 100% ensures that image doesnt overflow containing cell                //  width: X sets width of supplied image.                //  As a result, images bigger than cell will be contained and images smaller will not get stretched                $html .= '<img src="'.$dataUri.'" style="max-width:100%;width:'.$drawing->getWidth().'px;" />';            }        }        return $html;    }    /**     * Generate chart tag in cell     *     * @param    PHPExcel_Worksheet    $pSheet            PHPExcel_Worksheet     * @param    string                $coordinates    Cell coordinates     * @return    string     * @throws    PHPExcel_Writer_Exception     */    private function writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates)    {        // Construct HTML        $html = '';        // Write charts        foreach ($pSheet->getChartCollection() as $chart) {            if ($chart instanceof PHPExcel_Chart) {                $chartCoordinates = $chart->getTopLeftPosition();                if ($chartCoordinates['cell'] == $coordinates) {                    $chartFileName = PHPExcel_Shared_File::sys_get_temp_dir().'/'.uniqid().'.png';                    if (!$chart->render($chartFileName)) {                        return;                    }                    $html .= PHP_EOL;                    $imageDetails = getimagesize($chartFileName);                    if ($fp = fopen($chartFileName, "rb", 0)) {                        $picture = fread($fp, filesize($chartFileName));                        fclose($fp);                        // base64 encode the binary data, then break it                        // into chunks according to RFC 2045 semantics                        $base64 = chunk_split(base64_encode($picture));                        $imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64;                        $html .= '<div style="position: relative;">';                        $html .= '<img style="position: absolute; z-index: 1; left: ' . $chartCoordinates['xOffset'] . 'px; top: ' . $chartCoordinates['yOffset'] . 'px; width: ' . $imageDetails[0] . 'px; height: ' . $imageDetails[1] . 'px;" src="' . $imageData . '" border="0" />' . PHP_EOL;                        $html .= '</div>';                        unlink($chartFileName);                    }                }            }        }        // Return        return $html;    }    /**     * Generate CSS styles     *     * @param    boolean    $generateSurroundingHTML    Generate surrounding HTML tags? (<style> and </style>)     * @return    string     * @throws    PHPExcel_Writer_Exception     */    public function generateStyles($generateSurroundingHTML = true)    {        // PHPExcel object known?        if (is_null($this->phpExcel)) {            throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.');        }        // Build CSS        $css = $this->buildCSS($generateSurroundingHTML);        // Construct HTML        $html = '';        // Start styles        if ($generateSurroundingHTML) {            $html .= '    <style type="text/css">' . PHP_EOL;            $html .= '      html { ' . $this->assembleCSS($css['html']) . ' }' . PHP_EOL;        }        // Write all other styles        foreach ($css as $styleName => $styleDefinition) {            if ($styleName != 'html') {                $html .= '      ' . $styleName . ' { ' . $this->assembleCSS($styleDefinition) . ' }' . PHP_EOL;            }        }        // End styles        if ($generateSurroundingHTML) {            $html .= '    </style>' . PHP_EOL;        }        // Return        return $html;    }    /**     * Build CSS styles     *     * @param    boolean    $generateSurroundingHTML    Generate surrounding HTML style? (html { })     * @return    array     * @throws    PHPExcel_Writer_Exception     */    public function buildCSS($generateSurroundingHTML = true)    {        // PHPExcel object known?        if (is_null($this->phpExcel)) {            throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.');        }        // Cached?        if (!is_null($this->cssStyles)) {            return $this->cssStyles;        }        // Ensure that spans have been calculated        if (!$this->spansAreCalculated) {            $this->calculateSpans();        }        // Construct CSS        $css = array();        // Start styles        if ($generateSurroundingHTML) {            // html { }            $css['html']['font-family']      = 'Calibri, Arial, Helvetica, sans-serif';            $css['html']['font-size']        = '11pt';            $css['html']['background-color'] = 'white';        }        // table { }        $css['table']['border-collapse']  = 'collapse';        if (!$this->isPdf) {            $css['table']['page-break-after'] = 'always';        }        // .gridlines td { }        $css['.gridlines td']['border'] = '1px dotted black';        $css['.gridlines th']['border'] = '1px dotted black';        // .b {}        $css['.b']['text-align'] = 'center'; // BOOL        // .e {}        $css['.e']['text-align'] = 'center'; // ERROR        // .f {}        $css['.f']['text-align'] = 'right'; // FORMULA        // .inlineStr {}        $css['.inlineStr']['text-align'] = 'left'; // INLINE        // .n {}        $css['.n']['text-align'] = 'right'; // NUMERIC        // .s {}        $css['.s']['text-align'] = 'left'; // STRING        // Calculate cell style hashes        foreach ($this->phpExcel->getCellXfCollection() as $index => $style) {            $css['td.style' . $index] = $this->createCSSStyle($style);            $css['th.style' . $index] = $this->createCSSStyle($style);        }        // Fetch sheets        $sheets = array();        if (is_null($this->sheetIndex)) {            $sheets = $this->phpExcel->getAllSheets();        } else {            $sheets[] = $this->phpExcel->getSheet($this->sheetIndex);        }        // Build styles per sheet        foreach ($sheets as $sheet) {            // Calculate hash code            $sheetIndex = $sheet->getParent()->getIndex($sheet);            // Build styles            // Calculate column widths            $sheet->calculateColumnWidths();            // col elements, initialize            $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()) - 1;            $column = -1;            while ($column++ < $highestColumnIndex) {                $this->columnWidths[$sheetIndex][$column] = 42; // approximation                $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = '42pt';            }            // col elements, loop through columnDimensions and set width            foreach ($sheet->getColumnDimensions() as $columnDimension) {                if (($width = PHPExcel_Shared_Drawing::cellDimensionToPixels($columnDimension->getWidth(), $this->defaultFont)) >= 0) {                    $width = PHPExcel_Shared_Drawing::pixelsToPoints($width);                    $column = PHPExcel_Cell::columnIndexFromString($columnDimension->getColumnIndex()) - 1;                    $this->columnWidths[$sheetIndex][$column] = $width;                    $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = $width . 'pt';                    if ($columnDimension->getVisible() === false) {                        $css['table.sheet' . $sheetIndex . ' col.col' . $column]['visibility'] = 'collapse';                        $css['table.sheet' . $sheetIndex . ' col.col' . $column]['*display'] = 'none'; // target IE6+7                    }                }            }            // Default row height            $rowDimension = $sheet->getDefaultRowDimension();            // table.sheetN tr { }            $css['table.sheet' . $sheetIndex . ' tr'] = array();            if ($rowDimension->getRowHeight() == -1) {                $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->phpExcel->getDefaultStyle()->getFont());            } else {                $pt_height = $rowDimension->getRowHeight();            }            $css['table.sheet' . $sheetIndex . ' tr']['height'] = $pt_height . 'pt';            if ($rowDimension->getVisible() === false) {                $css['table.sheet' . $sheetIndex . ' tr']['display']    = 'none';                $css['table.sheet' . $sheetIndex . ' tr']['visibility'] = 'hidden';            }            // Calculate row heights            foreach ($sheet->getRowDimensions() as $rowDimension) {                $row = $rowDimension->getRowIndex() - 1;                // table.sheetN tr.rowYYYYYY { }                $css['table.sheet' . $sheetIndex . ' tr.row' . $row] = array();                if ($rowDimension->getRowHeight() == -1) {                    $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->phpExcel->getDefaultStyle()->getFont());                } else {                    $pt_height = $rowDimension->getRowHeight();                }                $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['height'] = $pt_height . 'pt';                if ($rowDimension->getVisible() === false) {                    $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['display'] = 'none';                    $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['visibility'] = 'hidden';                }            }        }        // Cache        if (is_null($this->cssStyles)) {            $this->cssStyles = $css;        }        // Return        return $css;    }    /**     * Create CSS style     *     * @param    PHPExcel_Style        $pStyle            PHPExcel_Style     * @return    array     */    private function createCSSStyle(PHPExcel_Style $pStyle)    {        // Construct CSS        $css = '';        // Create CSS        $css = array_merge(            $this->createCSSStyleAlignment($pStyle->getAlignment()),            $this->createCSSStyleBorders($pStyle->getBorders()),            $this->createCSSStyleFont($pStyle->getFont()),            $this->createCSSStyleFill($pStyle->getFill())        );        // Return        return $css;    }    /**     * Create CSS style (PHPExcel_Style_Alignment)     *     * @param    PHPExcel_Style_Alignment        $pStyle            PHPExcel_Style_Alignment     * @return    array     */    private function createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle)    {        // Construct CSS        $css = array();        // Create CSS        $css['vertical-align'] = $this->mapVAlign($pStyle->getVertical());        if ($textAlign = $this->mapHAlign($pStyle->getHorizontal())) {            $css['text-align'] = $textAlign;            if (in_array($textAlign, array('left', 'right'))) {                $css['padding-'.$textAlign] = (string)((int)$pStyle->getIndent() * 9).'px';            }        }        return $css;    }    /**     * Create CSS style (PHPExcel_Style_Font)     *     * @param    PHPExcel_Style_Font        $pStyle            PHPExcel_Style_Font     * @return    array     */    private function createCSSStyleFont(PHPExcel_Style_Font $pStyle)    {        // Construct CSS        $css = array();        // Create CSS        if ($pStyle->getBold()) {            $css['font-weight'] = 'bold';        }        if ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE && $pStyle->getStrikethrough()) {            $css['text-decoration'] = 'underline line-through';        } elseif ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE) {            $css['text-decoration'] = 'underline';        } elseif ($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';        return $css;    }    /**     * Create CSS style (PHPExcel_Style_Borders)     *     * @param    PHPExcel_Style_Borders        $pStyle            PHPExcel_Style_Borders     * @return    array     */    private function createCSSStyleBorders(PHPExcel_Style_Borders $pStyle)    {        // Construct CSS        $css = array();        // Create CSS        $css['border-bottom'] = $this->createCSSStyleBorder($pStyle->getBottom());        $css['border-top']    = $this->createCSSStyleBorder($pStyle->getTop());        $css['border-left']   = $this->createCSSStyleBorder($pStyle->getLeft());        $css['border-right']  = $this->createCSSStyleBorder($pStyle->getRight());        return $css;    }    /**     * Create CSS style (PHPExcel_Style_Border)     *     * @param    PHPExcel_Style_Border        $pStyle            PHPExcel_Style_Border     * @return    string     */    private function createCSSStyleBorder(PHPExcel_Style_Border $pStyle)    {        // Create CSS//        $css = $this->mapBorderStyle($pStyle->getBorderStyle()) . ' #' . $pStyle->getColor()->getRGB();        //    Create CSS - add !important to non-none border styles for merged cells        $borderStyle = $this->mapBorderStyle($pStyle->getBorderStyle());        $css = $borderStyle . ' #' . $pStyle->getColor()->getRGB() . (($borderStyle == 'none') ? '' : ' !important');        return $css;    }    /**     * Create CSS style (PHPExcel_Style_Fill)     *     * @param    PHPExcel_Style_Fill        $pStyle            PHPExcel_Style_Fill     * @return    array     */    private function createCSSStyleFill(PHPExcel_Style_Fill $pStyle)    {        // Construct HTML        $css = array();        // Create CSS        $value = $pStyle->getFillType() == PHPExcel_Style_Fill::FILL_NONE ?            'white' : '#' . $pStyle->getStartColor()->getRGB();        $css['background-color'] = $value;        return $css;    }    /**     * Generate HTML footer     */    public function generateHTMLFooter()    {        // Construct HTML        $html = '';        $html .= '  </body>' . PHP_EOL;        $html .= '</html>' . PHP_EOL;        return $html;    }    /**     * Generate table header     *     * @param    PHPExcel_Worksheet    $pSheet        The worksheet for the table we are writing     * @return    string     * @throws    PHPExcel_Writer_Exception     */    private function generateTableHeader($pSheet)    {        $sheetIndex = $pSheet->getParent()->getIndex($pSheet);        // Construct HTML        $html = '';        $html .= $this->setMargins($pSheet);                    if (!$this->useInlineCss) {            $gridlines = $pSheet->getShowGridlines() ? ' gridlines' : '';            $html .= '    <table border="0" cellpadding="0" cellspacing="0" id="sheet' . $sheetIndex . '" class="sheet' . $sheetIndex . $gridlines . '">' . PHP_EOL;        } else {            $style = isset($this->cssStyles['table']) ?                $this->assembleCSS($this->cssStyles['table']) : '';            if ($this->isPdf && $pSheet->getShowGridlines()) {                $html .= '    <table border="1" cellpadding="1" id="sheet' . $sheetIndex . '" cellspacing="1" style="' . $style . '">' . PHP_EOL;            } else {                $html .= '    <table border="0" cellpadding="1" id="sheet' . $sheetIndex . '" cellspacing="0" style="' . $style . '">' . PHP_EOL;            }        }        // Write <col> elements        $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()) - 1;        $i = -1;        while ($i++ < $highestColumnIndex) {            if (!$this->isPdf) {                if (!$this->useInlineCss) {                    $html .= '        <col class="col' . $i . '">' . PHP_EOL;                } else {                    $style = isset($this->cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) ?                        $this->assembleCSS($this->cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) : '';                    $html .= '        <col style="' . $style . '">' . PHP_EOL;                }            }        }        return $html;    }    /**     * Generate table footer     *     * @throws    PHPExcel_Writer_Exception     */    private function generateTableFooter()    {        $html = '    </table>' . PHP_EOL;        return $html;    }    /**     * Generate row     *     * @param    PHPExcel_Worksheet    $pSheet            PHPExcel_Worksheet     * @param    array                $pValues        Array containing cells in a row     * @param    int                    $pRow            Row number (0-based)     * @return    string     * @throws    PHPExcel_Writer_Exception     */    private function generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow = 0, $cellType = 'td')    {        if (is_array($pValues)) {            // Construct HTML            $html = '';            // Sheet index            $sheetIndex = $pSheet->getParent()->getIndex($pSheet);            // DomPDF and breaks            if ($this->isPdf && count($pSheet->getBreaks()) > 0) {                $breaks = $pSheet->getBreaks();                // check if a break is needed before this row                if (isset($breaks['A' . $pRow])) {                    // close table: </table>                    $html .= $this->generateTableFooter();                    // insert page break                    $html .= '<div style="page-break-before:always" />';                    // open table again: <table> + <col> etc.                    $html .= $this->generateTableHeader($pSheet);                }            }            // Write row start            if (!$this->useInlineCss) {                $html .= '          <tr class="row' . $pRow . '">' . PHP_EOL;            } else {                $style = isset($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow])                    ? $this->assembleCSS($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) : '';                $html .= '          <tr style="' . $style . '">' . PHP_EOL;            }            // Write cells            $colNum = 0;            foreach ($pValues as $cellAddress) {                $cell = ($cellAddress > '') ? $pSheet->getCell($cellAddress) : '';                $coordinate = PHPExcel_Cell::stringFromColumnIndex($colNum) . ($pRow + 1);                if (!$this->useInlineCss) {                    $cssClass = '';                    $cssClass = 'column' . $colNum;                } else {                    $cssClass = array();                    if ($cellType == 'th') {                        if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum])) {                            $this->cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum];                        }                    } else {                        if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum])) {                            $this->cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum];                        }                    }                }                $colSpan = 1;                $rowSpan = 1;                // initialize                $cellData = ' ';                // PHPExcel_Cell                if ($cell instanceof PHPExcel_Cell) {                    $cellData = '';                    if (is_null($cell->getParent())) {                        $cell->attach($pSheet);                    }                    // Value                    if ($cell->getValue() instanceof PHPExcel_RichText) {                        // Loop through rich text elements                        $elements = $cell->getValue()->getRichTextElements();                        foreach ($elements as $element) {                            // Rich text start?                            if ($element instanceof PHPExcel_RichText_Run) {                                $cellData .= '<span style="' . $this->assembleCSS($this->createCSSStyleFont($element->getFont())) . '">';                                if ($element->getFont()->getSuperScript()) {                                    $cellData .= '<sup>';                                } elseif ($element->getFont()->getSubScript()) {                                    $cellData .= '<sub>';                                }                            }                            // Convert UTF8 data to PCDATA                            $cellText = $element->getText();                            $cellData .= htmlspecialchars($cellText);                            if ($element instanceof PHPExcel_RichText_Run) {                                if ($element->getFont()->getSuperScript()) {                                    $cellData .= '</sup>';                                } elseif ($element->getFont()->getSubScript()) {                                    $cellData .= '</sub>';                                }                                $cellData .= '</span>';                            }                        }                    } else {                        if ($this->preCalculateFormulas) {                            $cellData = PHPExcel_Style_NumberFormat::toFormattedString(                                $cell->getCalculatedValue(),                                $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode(),                                array($this, 'formatColor')                            );                        } else {                            $cellData = PHPExcel_Style_NumberFormat::toFormattedString(                                $cell->getValue(),                                $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode(),                                array($this, 'formatColor')                            );                        }                        $cellData = htmlspecialchars($cellData);                        if ($pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont()->getSuperScript()) {                            $cellData = '<sup>'.$cellData.'</sup>';                        } elseif ($pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont()->getSubScript()) {                            $cellData = '<sub>'.$cellData.'</sub>';                        }                    }                    // Converts the cell content so that spaces occuring at beginning of each new line are replaced by                      // Example: "  Hello\n to the world" is converted to "  Hello\n to the world"                    $cellData = preg_replace("/(?m)(?:^|\\G) /", ' ', $cellData);                    // convert newline "\n" to '<br>'                    $cellData = nl2br($cellData);                    // Extend CSS class?                    if (!$this->useInlineCss) {                        $cssClass .= ' style' . $cell->getXfIndex();                        $cssClass .= ' ' . $cell->getDataType();                    } else {                        if ($cellType == 'th') {                            if (isset($this->cssStyles['th.style' . $cell->getXfIndex()])) {                                $cssClass = array_merge($cssClass, $this->cssStyles['th.style' . $cell->getXfIndex()]);                            }                        } else {                            if (isset($this->cssStyles['td.style' . $cell->getXfIndex()])) {                                $cssClass = array_merge($cssClass, $this->cssStyles['td.style' . $cell->getXfIndex()]);                            }                        }                        // General horizontal alignment: Actual horizontal alignment depends on dataType                        $sharedStyle = $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex());                        if ($sharedStyle->getAlignment()->getHorizontal() == PHPExcel_Style_Alignment::HORIZONTAL_GENERAL                            && isset($this->cssStyles['.' . $cell->getDataType()]['text-align'])) {                            $cssClass['text-align'] = $this->cssStyles['.' . $cell->getDataType()]['text-align'];                        }                    }                }                // Hyperlink?                if ($pSheet->hyperlinkExists($coordinate) && !$pSheet->getHyperlink($coordinate)->isInternal()) {                    $cellData = '<a href="' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getUrl()) . '" title="' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getTooltip()) . '">' . $cellData . '</a>';                }                // Should the cell be written or is it swallowed by a rowspan or colspan?                $writeCell = !(isset($this->isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum])                            && $this->isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]);                // Colspan and Rowspan                $colspan = 1;                $rowspan = 1;                if (isset($this->isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum])) {                    $spans = $this->isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum];                    $rowSpan = $spans['rowspan'];                    $colSpan = $spans['colspan'];                    //    Also apply style from last cell in merge to fix borders -                    //        relies on !important for non-none border declarations in createCSSStyleBorder                    $endCellCoord = PHPExcel_Cell::stringFromColumnIndex($colNum + $colSpan - 1) . ($pRow + $rowSpan);                    if (!$this->useInlineCss) {                        $cssClass .= ' style' . $pSheet->getCell($endCellCoord)->getXfIndex();                    }                }                // Write                if ($writeCell) {                    // Column start                    $html .= '            <' . $cellType;                    if (!$this->useInlineCss) {                        $html .= ' class="' . $cssClass . '"';                    } else {                        //** 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">                        $width = 0;                        $i = $colNum - 1;                        $e = $colNum + $colSpan - 1;                        while ($i++ < $e) {                            if (isset($this->columnWidths[$sheetIndex][$i])) {                                $width += $this->columnWidths[$sheetIndex][$i];                            }                        }                        $cssClass['width'] = $width . 'pt';                        // We must also explicitly write the height of the <td> element because TCPDF                        // does not recognize e.g. <tr style="height:50pt">                        if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'])) {                            $height = $this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'];                            $cssClass['height'] = $height;                        }                        //** end of redundant code **                        $html .= ' style="' . $this->assembleCSS($cssClass) . '"';                    }                    if ($colSpan > 1) {                        $html .= ' colspan="' . $colSpan . '"';                    }                    if ($rowSpan > 1) {                        $html .= ' rowspan="' . $rowSpan . '"';                    }                    $html .= '>';                    // Image?                    $html .= $this->writeImageInCell($pSheet, $coordinate);                    // Chart?                    if ($this->includeCharts) {                        $html .= $this->writeChartInCell($pSheet, $coordinate);                    }                    // Cell data                    $html .= $cellData;                    // Column end                    $html .= '</'.$cellType.'>' . PHP_EOL;                }                // Next column                ++$colNum;            }            // Write row end            $html .= '          </tr>' . PHP_EOL;            // Return            return $html;        } else {            throw new PHPExcel_Writer_Exception("Invalid parameters passed.");        }    }    /**     * Takes array where of CSS properties / values and converts to CSS string     *     * @param array     * @return string     */    private function assembleCSS($pValue = array())    {        $pairs = array();        foreach ($pValue as $property => $value) {            $pairs[] = $property . ':' . $value;        }        $string = implode('; ', $pairs);        return $string;    }    /**     * Get images root     *     * @return string     */    public function getImagesRoot()    {        return $this->imagesRoot;    }    /**     * Set images root     *     * @param string $pValue     * @return PHPExcel_Writer_HTML     */    public function setImagesRoot($pValue = '.')    {        $this->imagesRoot = $pValue;        return $this;    }    /**     * Get embed images     *     * @return boolean     */    public function getEmbedImages()    {        return $this->embedImages;    }    /**     * Set embed images     *     * @param boolean $pValue     * @return PHPExcel_Writer_HTML     */    public function setEmbedImages($pValue = '.')    {        $this->embedImages = $pValue;        return $this;    }    /**     * Get use inline CSS?     *     * @return boolean     */    public function getUseInlineCss()    {        return $this->useInlineCss;    }    /**     * Set use inline CSS?     *     * @param boolean $pValue     * @return PHPExcel_Writer_HTML     */    public function setUseInlineCss($pValue = false)    {        $this->useInlineCss = $pValue;        return $this;    }    /**     * Add color to formatted string as inline style     *     * @param string $pValue Plain formatted value without color     * @param string $pFormat Format code     * @return string     */    public function formatColor($pValue, $pFormat)    {        // Color information, e.g. [Red] is always at the beginning        $color = null; // initialize        $matches = array();        $color_regex = '/^\\[[a-zA-Z]+\\]/';        if (preg_match($color_regex, $pFormat, $matches)) {            $color = str_replace('[', '', $matches[0]);            $color = str_replace(']', '', $color);            $color = strtolower($color);        }        // convert to PCDATA        $value = htmlspecialchars($pValue);        // color span tag        if ($color !== null) {            $value = '<span style="color:' . $color . '">' . $value . '</span>';        }        return $value;    }    /**     * Calculate information about HTML colspan and rowspan which is not always the same as Excel's     */    private function calculateSpans()    {        // Identify all cells that should be omitted in HTML due to cell merge.        // In HTML only the upper-left cell should be written and it should have        //   appropriate rowspan / colspan attribute        $sheetIndexes = $this->sheetIndex !== null ?            array($this->sheetIndex) : range(0, $this->phpExcel->getSheetCount() - 1);        foreach ($sheetIndexes as $sheetIndex) {            $sheet = $this->phpExcel->getSheet($sheetIndex);            $candidateSpannedRow  = array();            // loop through all Excel merged cells            foreach ($sheet->getMergeCells() as $cells) {                list($cells,) = PHPExcel_Cell::splitRange($cells);                $first = $cells[0];                $last  = $cells[1];                list($fc, $fr) = PHPExcel_Cell::coordinateFromString($first);                $fc = PHPExcel_Cell::columnIndexFromString($fc) - 1;                list($lc, $lr) = PHPExcel_Cell::coordinateFromString($last);                $lc = PHPExcel_Cell::columnIndexFromString($lc) - 1;                // loop through the individual cells in the individual merge                $r = $fr - 1;                while ($r++ < $lr) {                    // also, flag this row as a HTML row that is candidate to be omitted                    $candidateSpannedRow[$r] = $r;                    $c = $fc - 1;                    while ($c++ < $lc) {                        if (!($c == $fc && $r == $fr)) {                            // not the upper-left cell (should not be written in HTML)                            $this->isSpannedCell[$sheetIndex][$r][$c] = array(                                'baseCell' => array($fr, $fc),                            );                        } else {                            // upper-left is the base cell that should hold the colspan/rowspan attribute                            $this->isBaseCell[$sheetIndex][$r][$c] = array(                                'xlrowspan' => $lr - $fr + 1, // Excel rowspan                                'rowspan'   => $lr - $fr + 1, // HTML rowspan, value may change                                'xlcolspan' => $lc - $fc + 1, // Excel colspan                                'colspan'   => $lc - $fc + 1, // HTML colspan, value may change                            );                        }                    }                }            }            // Identify which rows should be omitted in HTML. These are the rows where all the cells            //   participate in a merge and the where base cells are somewhere above.            $countColumns = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn());            foreach ($candidateSpannedRow as $rowIndex) {                if (isset($this->isSpannedCell[$sheetIndex][$rowIndex])) {                    if (count($this->isSpannedCell[$sheetIndex][$rowIndex]) == $countColumns) {                        $this->isSpannedRow[$sheetIndex][$rowIndex] = $rowIndex;                    };                }            }            // For each of the omitted rows we found above, the affected rowspans should be subtracted by 1            if (isset($this->isSpannedRow[$sheetIndex])) {                foreach ($this->isSpannedRow[$sheetIndex] as $rowIndex) {                    $adjustedBaseCells = array();                    $c = -1;                    $e = $countColumns - 1;                    while ($c++ < $e) {                        $baseCell = $this->isSpannedCell[$sheetIndex][$rowIndex][$c]['baseCell'];                        if (!in_array($baseCell, $adjustedBaseCells)) {                            // subtract rowspan by 1                            --$this->isBaseCell[$sheetIndex][ $baseCell[0] ][ $baseCell[1] ]['rowspan'];                            $adjustedBaseCells[] = $baseCell;                        }                    }                }            }            // TODO: Same for columns        }        // We have calculated the spans        $this->spansAreCalculated = true;    }    private function setMargins(PHPExcel_Worksheet $pSheet)    {        $htmlPage = '@page { ';        $htmlBody = 'body { ';        $left = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft()) . 'in; ';        $htmlPage .= 'margin-left: ' . $left;        $htmlBody .= 'margin-left: ' . $left;        $right = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight()) . 'in; ';        $htmlPage .= 'margin-right: ' . $right;        $htmlBody .= 'margin-right: ' . $right;        $top = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop()) . 'in; ';        $htmlPage .= 'margin-top: ' . $top;        $htmlBody .= 'margin-top: ' . $top;        $bottom = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom()) . 'in; ';        $htmlPage .= 'margin-bottom: ' . $bottom;        $htmlBody .= 'margin-bottom: ' . $bottom;        $htmlPage .= "}\n";        $htmlBody .= "}\n";        return "<style>\n" . $htmlPage . $htmlBody . "</style>\n";    }}
 |