96                    'borderStyle' => Border::BORDER_THIN,
 
  132        parent::__construct();
 
  157        fclose($this->fileHandle);
 
  159        return $startWithTag && $containsTags && $endsWithTag;
 
  164        fseek($this->fileHandle, 0);
 
  166        return fread($this->fileHandle, self::TEST_SAMPLE_SIZE);
 
  171        $meta = stream_get_meta_data($this->fileHandle);
 
  180        if (
$size < $blockSize) {
 
  184        fseek($this->fileHandle, 
$size - $blockSize);
 
  186        return fread($this->fileHandle, $blockSize);
 
  191        return '<' === substr(trim(
$data), 0, 1);
 
  196        return '>' === substr(trim(
$data), -1, 1);
 
  201        return strlen(
$data) !== strlen(strip_tags(
$data));
 
  211    public function load($pFilename)
 
  233        $this->inputEncoding = $pValue;
 
  261        if ($this->tableLevel == 0) {
 
  279        return array_pop($this->nestedColumn);
 
  284        if (is_string($cellContent)) {
 
  286            if (trim($cellContent) > 
'') {
 
  290                $sheet->setCellValue($column . 
$row, $cellContent);
 
  291                $this->dataArray[
$row][$column] = $cellContent;
 
  296            $this->dataArray[
$row][$column] = 
'RICH TEXT: ' . $cellContent;
 
  298        $cellContent = (string) 
'';
 
  303        $attributeArray = [];
 
  304        foreach ($child->attributes as $attribute) {
 
  305            $attributeArray[$attribute->name] = $attribute->value;
 
  308        if ($child->nodeName === 
'body') {
 
  312            $this->tableLevel = 0;
 
  321        if ($child->nodeName === 
'title') {
 
  323            $sheet->setTitle($cellContent, 
true, 
true);
 
  330    private static $spanEtc = [
'span', 
'div', 
'font', 
'i', 
'em', 
'strong', 
'b'];
 
  334        if (in_array($child->nodeName, self::$spanEtc)) {
 
  335            if (isset($attributeArray[
'class']) && $attributeArray[
'class'] === 
'comment') {
 
  336                $sheet->getComment($column . 
$row)
 
  338                    ->createTextRun($child->textContent);
 
  342            if (isset($this->formats[$child->nodeName])) {
 
  343                $sheet->getStyle($column . 
$row)->applyFromArray($this->formats[$child->nodeName]);
 
  352        if ($child->nodeName === 
'hr') {
 
  355            if (isset($this->formats[$child->nodeName])) {
 
  356                $sheet->getStyle($column . 
$row)->applyFromArray($this->formats[$child->nodeName]);
 
  366        if ($child->nodeName === 
'br' || $child->nodeName === 
'hr') {
 
  367            if ($this->tableLevel > 0) {
 
  369                $cellContent .= 
"\n";
 
  370                $sheet->getStyle($column . 
$row)->getAlignment()->setWrapText(
true);
 
  383        if ($child->nodeName === 
'a') {
 
  384            foreach ($attributeArray as $attributeName => $attributeValue) {
 
  385                switch ($attributeName) {
 
  387                        $sheet->getCell($column . 
$row)->getHyperlink()->setUrl($attributeValue);
 
  388                        if (isset($this->formats[$child->nodeName])) {
 
  389                            $sheet->getStyle($column . 
$row)->applyFromArray($this->formats[$child->nodeName]);
 
  394                        if ($attributeValue === 
'comment-indicator') {
 
  407    private static $h1Etc = [
'h1', 
'h2', 
'h3', 
'h4', 
'h5', 
'h6', 
'ol', 
'ul', 
'p'];
 
  411        if (in_array($child->nodeName, self::$h1Etc)) {
 
  412            if ($this->tableLevel > 0) {
 
  414                $cellContent .= $cellContent ? 
"\n" : 
'';
 
  415                $sheet->getStyle($column . 
$row)->getAlignment()->setWrapText(
true);
 
  418                if ($cellContent > 
'') {
 
  425                if (isset($this->formats[$child->nodeName])) {
 
  426                    $sheet->getStyle($column . 
$row)->applyFromArray($this->formats[$child->nodeName]);
 
  439        if ($child->nodeName === 
'li') {
 
  440            if ($this->tableLevel > 0) {
 
  442                $cellContent .= $cellContent ? 
"\n" : 
'';
 
  445                if ($cellContent > 
'') {
 
  460        if ($child->nodeName === 
'img') {
 
  469        if ($child->nodeName === 
'table') {
 
  472            if ($this->tableLevel > 1 && 
$row > 1) {
 
  477            if ($this->tableLevel > 1) {
 
  489        if ($child->nodeName === 
'tr') {
 
  494            if (isset($attributeArray[
'height'])) {
 
  495                $sheet->getRowDimension(
$row)->setRowHeight($attributeArray[
'height']);
 
  506        if ($child->nodeName !== 
'td' && $child->nodeName !== 
'th') {
 
  515        if (isset($attributeArray[
'bgcolor'])) {
 
  516            $sheet->getStyle(
"$column$row")->applyFromArray(
 
  519                        'fillType' => Fill::FILL_SOLID,
 
  520                        'color' => [
'rgb' => $this->
getStyleColor($attributeArray[
'bgcolor'])],
 
  529        if (isset($attributeArray[
'width'])) {
 
  530            $sheet->getColumnDimension($column)->setWidth($attributeArray[
'width']);
 
  536        if (isset($attributeArray[
'height'])) {
 
  537            $sheet->getRowDimension(
$row)->setRowHeight($attributeArray[
'height']);
 
  543        if (isset($attributeArray[
'align'])) {
 
  544            $sheet->getStyle($column . 
$row)->getAlignment()->setHorizontal($attributeArray[
'align']);
 
  550        if (isset($attributeArray[
'valign'])) {
 
  551            $sheet->getStyle($column . 
$row)->getAlignment()->setVertical($attributeArray[
'valign']);
 
  557        if (isset($attributeArray[
'data-format'])) {
 
  558            $sheet->getStyle($column . 
$row)->getNumberFormat()->setFormatCode($attributeArray[
'data-format']);
 
  564        while (isset($this->rowspan[$column . 
$row])) {
 
  581        if (isset($attributeArray[
'rowspan'], $attributeArray[
'colspan'])) {
 
  584            for (
$i = 0; 
$i < (int) $attributeArray[
'colspan'] - 1; ++
$i) {
 
  587            $range = $column . 
$row . 
':' . $columnTo . (
$row + (int) $attributeArray[
'rowspan'] - 1);
 
  589                $this->rowspan[$value] = 
true;
 
  591            $sheet->mergeCells($range);
 
  593        } elseif (isset($attributeArray[
'rowspan'])) {
 
  595            $range = $column . 
$row . 
':' . $column . (
$row + (int) $attributeArray[
'rowspan'] - 1);
 
  597                $this->rowspan[$value] = 
true;
 
  599            $sheet->mergeCells($range);
 
  600        } elseif (isset($attributeArray[
'colspan'])) {
 
  603            for (
$i = 0; 
$i < (int) $attributeArray[
'colspan'] - 1; ++
$i) {
 
  606            $sheet->mergeCells($column . 
$row . 
':' . $columnTo . 
$row);
 
  615        foreach ($element->childNodes as $child) {
 
  616            if ($child instanceof DOMText) {
 
  617                $domText = preg_replace(
'/\s+/u', 
' ', trim($child->nodeValue));
 
  618                if (is_string($cellContent)) {
 
  620                    $cellContent .= $domText;
 
  624            } elseif ($child instanceof DOMElement) {
 
  640        if (!$this->
canRead($pFilename)) {
 
  641            throw new Exception($pFilename . 
' is an Invalid HTML file.');
 
  645        $dom = 
new DOMDocument();
 
  648            $loaded = $dom->loadHTML(mb_convert_encoding($this->securityScanner->scanFile($pFilename), 
'HTML-ENTITIES', 
'UTF-8'));
 
  649        } 
catch (Throwable $e) {
 
  652        if ($loaded === 
false) {
 
  653            throw new Exception(
'Failed to load ' . $pFilename . 
' as a DOM Document', 0, $e ?? 
null);
 
  667        $dom = 
new DOMDocument();
 
  670            $loaded = $dom->loadHTML(mb_convert_encoding($this->securityScanner->scan($content), 
'HTML-ENTITIES', 
'UTF-8'));
 
  671        } 
catch (Throwable $e) {
 
  674        if ($loaded === 
false) {
 
  675            throw new Exception(
'Failed to load content as a DOM Document', 0, $e ?? 
null);
 
  692        $document->preserveWhiteSpace = 
false;
 
  723        $this->sheetIndex = $pValue;
 
  745        if (!isset($attributeArray[
'style'])) {
 
  749        if (isset($attributeArray[
'rowspan'], $attributeArray[
'colspan'])) {
 
  751            for (
$i = 0; 
$i < (int) $attributeArray[
'colspan'] - 1; ++
$i) {
 
  754            $range = $column . 
$row . 
':' . $columnTo . (
$row + (int) $attributeArray[
'rowspan'] - 1);
 
  755            $cellStyle = $sheet->getStyle($range);
 
  756        } elseif (isset($attributeArray[
'rowspan'])) {
 
  757            $range = $column . 
$row . 
':' . $column . (
$row + (int) $attributeArray[
'rowspan'] - 1);
 
  758            $cellStyle = $sheet->getStyle($range);
 
  759        } elseif (isset($attributeArray[
'colspan'])) {
 
  761            for (
$i = 0; 
$i < (int) $attributeArray[
'colspan'] - 1; ++
$i) {
 
  764            $range = $column . 
$row . 
':' . $columnTo . 
$row;
 
  765            $cellStyle = $sheet->getStyle($range);
 
  767            $cellStyle = $sheet->getStyle($column . 
$row);
 
  771        $styles = explode(
';', $attributeArray[
'style']);
 
  772        foreach ($styles as $st) {
 
  773            $value = explode(
':', $st);
 
  774            $styleName = isset($value[0]) ? trim($value[0]) : 
null;
 
  775            $styleValue = isset($value[1]) ? trim($value[1]) : 
null;
 
  781            switch ($styleName) {
 
  783                case 'background-color':
 
  790                    $cellStyle->applyFromArray([
'fill' => [
'fillType' => Fill::FILL_SOLID, 
'color' => [
'rgb' => $styleColor]]]);
 
  800                    $cellStyle->applyFromArray([
'font' => [
'color' => [
'rgb' => $styleColor]]]);
 
  814                case 'border-bottom':
 
  830                    $cellStyle->getFont()->setSize(
 
  837                    if ($styleValue === 
'bold' || $styleValue >= 500) {
 
  838                        $cellStyle->getFont()->setBold(
true);
 
  844                    if ($styleValue === 
'italic') {
 
  845                        $cellStyle->getFont()->setItalic(
true);
 
  851                    $cellStyle->getFont()->setName(str_replace(
'\'', 
'', $styleValue));
 
  855                case 'text-decoration':
 
  856                    switch ($styleValue) {
 
  858                            $cellStyle->getFont()->setUnderline(Font::UNDERLINE_SINGLE);
 
  862                            $cellStyle->getFont()->setStrikethrough(
true);
 
  870                    $cellStyle->getAlignment()->setHorizontal($styleValue);
 
  874                case 'vertical-align':
 
  875                    $cellStyle->getAlignment()->setVertical($styleValue);
 
  880                    $sheet->getColumnDimension($column)->setWidth(
 
  881                        (
float) str_replace([
'px', 
'pt'], 
'', $styleValue)
 
  887                    $sheet->getRowDimension(
$row)->setRowHeight(
 
  888                        (
float) str_replace([
'px', 
'pt'], 
'', $styleValue)
 
  894                    $cellStyle->getAlignment()->setWrapText(
 
  895                        $styleValue === 
'break-word' 
  901                    $cellStyle->getAlignment()->setIndent(
 
  902                        (
int) str_replace([
'px'], 
'', $styleValue)
 
  917        if (strpos($value, 
'#') === 0) {
 
  918            return substr($value, 1);
 
  921        return \PhpOffice\PhpSpreadsheet\Helper\Html::colourNameLookup((
string) $value);
 
  940        $drawing->setPath($src);
 
  941        $drawing->setWorksheet($sheet);
 
  942        $drawing->setCoordinates($column . 
$row);
 
  943        $drawing->setOffsetX(0);
 
  944        $drawing->setOffsetY(10);
 
  945        $drawing->setResizeProportional(
true);
 
  948            $drawing->setName(
$name);
 
  952            $drawing->setWidth((
int) $width);
 
  956            $drawing->setHeight((
int) $height);
 
  959        $sheet->getColumnDimension($column)->setWidth(
 
  960            $drawing->getWidth() / 6
 
  963        $sheet->getRowDimension(
$row)->setRowHeight(
 
  964            $drawing->getHeight() * 0.9
 
  969        'dash-dot' => Border::BORDER_DASHDOT,
 
  970        'dash-dot-dot' => Border::BORDER_DASHDOTDOT,
 
  971        'dashed' => Border::BORDER_DASHED,
 
  972        'dotted' => Border::BORDER_DOTTED,
 
  973        'double' => Border::BORDER_DOUBLE,
 
  974        'hair' => Border::BORDER_HAIR,
 
  975        'medium' => Border::BORDER_MEDIUM,
 
  976        'medium-dashed' => Border::BORDER_MEDIUMDASHED,
 
  977        'medium-dash-dot' => Border::BORDER_MEDIUMDASHDOT,
 
  978        'medium-dash-dot-dot' => Border::BORDER_MEDIUMDASHDOTDOT,
 
  979        'none' => Border::BORDER_NONE,
 
  980        'slant-dash-dot' => Border::BORDER_SLANTDASHDOT,
 
  981        'solid' => Border::BORDER_THIN,
 
  982        'thick' => Border::BORDER_THICK,
 
  999        return (array_key_exists(
$style, self::$borderMappings)) ? self::$borderMappings[
$style] : 
null;
 
 1008        if (trim($styleValue) === Border::BORDER_NONE) {
 
 1009            $borderStyle = Border::BORDER_NONE;
 
 1012            $borderArray = explode(
' ', $styleValue);
 
 1013            $borderCount = count($borderArray);
 
 1014            if ($borderCount >= 3) {
 
 1015                $borderStyle = $borderArray[1];
 
 1016                $color = $borderArray[2];
 
 1018                $borderStyle = $borderArray[0];
 
 1019                $color = $borderArray[1] ?? 
null;
 
 1023        $cellStyle->applyFromArray([
 
An exception for terminatinating execution or to throw for unit testing.
Helper class to manipulate cell coordinates.
static extractAllCellReferencesInRange($cellRange)
Extract all cell references in range, which may be comprised of multiple cell ranges.
openFile($pFilename)
Open file for reading.
PhpSpreadsheet root directory.
const TEST_SAMPLE_SIZE
Sample size to read to determine if it's HTML or not.
processDomElement(DOMNode $element, Worksheet $sheet, int &$row, string &$column, string &$cellContent)
processDomElementTitle(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray)
processDomElementAlign(Worksheet $sheet, int $row, string $column, array $attributeArray)
processDomElementBody(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child)
static endsWithTag($data)
loadDocument(DOMDocument $document, Spreadsheet $spreadsheet)
Loads PhpSpreadsheet from DOMDocument into PhpSpreadsheet instance.
static startsWithTag($data)
processDomElementSpanEtc(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray)
load($pFilename)
Loads Spreadsheet from file.
processDomElementHeight(Worksheet $sheet, int $row, array $attributeArray)
flushCell(Worksheet $sheet, $column, $row, &$cellContent)
getSheetIndex()
Get sheet index.
getInputEncoding()
Get input encoding.
__construct()
Create a new HTML Reader instance.
getStyleColor($value)
Check if has #, so we can get clean hex.
processDomElementH1Etc(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray)
processDomElementTr(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray)
processDomElementTable(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray)
setSheetIndex($pValue)
Set sheet index.
canRead($pFilename)
Validate that the current file is an HTML file.
applyInlineStyle(&$sheet, $row, $column, $attributeArray)
Apply inline css inline style.
insertImage(Worksheet $sheet, $column, $row, array $attributes)
processDomElementDataFormat(Worksheet $sheet, int $row, string $column, array $attributeArray)
getBorderStyle($style)
Map html border style to PhpSpreadsheet border style.
processDomElementLi(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray)
processDomElementImg(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray)
setTableStartColumn($column)
processDomElementBr(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray)
processDomElementWidth(Worksheet $sheet, string $column, array $attributeArray)
processDomElementThTd(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray)
processDomElementVAlign(Worksheet $sheet, int $row, string $column, array $attributeArray)
setBorderStyle(Style $cellStyle, $styleValue, $type)
releaseTableStartColumn()
processDomElementA(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray)
loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
Loads PhpSpreadsheet from file into PhpSpreadsheet instance.
static containsTags($data)
setInputEncoding($pValue)
Set input encoding.
loadFromString($content, ?Spreadsheet $spreadsheet=null)
Spreadsheet from content.
processDomElementBgcolor(Worksheet $sheet, int $row, string $column, array $attributeArray)
static getBorderMappings()
processDomElementHr(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray)
processDomElementThTdOther(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray)
static getInstance(Reader\IReader $reader)
createSheet($sheetIndex=null)
Create sheet and add it to this workbook.
setActiveSheetIndex($pIndex)
Set active sheet index.
getSheetCount()
Get sheet count.
getActiveSheet()
Get active sheet.
if(array_key_exists('yes', $_REQUEST)) $attributes