Skip to content

Html reader render comment in cell value #2234

Closed
@Naghal

Description

This is:

- [ X ] a bug report

What is the expected behavior?

When creating a spreadsheet from html, we can insert comments by adding a tag with the class comment. It should add a comment to the cell, without also adding the comment in the cell value.

What is the current behavior?

A comment is created and the comment is also copied in the cell.

What are the steps to reproduce?

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Html();
$spreadsheet = $reader->loadFromString($htmlString);

$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xls');
$writer->save('write.xls'); 

htmlString:

<table>
    <thead>
    <tr>
        @foreach($headings as $heading)
            <th>{{$heading}}</th>
        @endforeach
    </tr>
    </thead>
    <tbody>
    @foreach($failures as $rowKey => $failure)
        <tr>
            @foreach($failure as $key => $value)
                @php
                $style = '';
                $comment = '';
                if (isset($failingAttributes[$rowKey])) {
                    if ($failingAttributes[$rowKey]->contains($key)) {
                        $style = 'background-color:#FC4140;';
                        $comment = $failuresMessages[$rowKey][$key];
                    }
                }
                @endphp
                <td style="{{$style}}">
                    @if($comment) <i class="comment" style="visibility:hidden;display:none;" hidden>{{$comment}}</i> @endif
                    {{ $value }}
                </td>
            @endforeach
        </tr>
    @endforeach
    </tbody>
</table>

Additionnal info

We can modify processDomElementSpanEtc function to solve this problem.

private function processDomElementSpanEtc(Worksheet $sheet, int &$row, string &$column, string &$cellContent, DOMElement $child, array &$attributeArray): void
    {
        if (in_array((string) $child->nodeName, self::SPAN_ETC, true)) {
            if (isset($attributeArray['class']) && $attributeArray['class'] === 'comment') {
                $sheet->getComment($column . $row)
                    ->getText()
                    ->createTextRun($child->textContent);
            }
            
            if (!isset($attributeArray['class']) && !$attributeArray['class'] === 'comment') { // Adding this conditional fixes the issue. A comment should not be rendered inside the cell.
                $this->processDomElement($child, $sheet, $row, $column, $cellContent);
            }

            if (isset($this->formats[$child->nodeName])) {
                $sheet->getStyle($column . $row)->applyFromArray($this->formats[$child->nodeName]);
            }
        } else {
            $this->processDomElementHr($sheet, $row, $column, $cellContent, $child, $attributeArray);
        }
    }

Also, here is a link to my SO question, which includes screenshots of actual result and expected result.
https://stackoverflow.com/questions/68502358/how-to-not-write-comment-in-cell-value-with-phpspreadsheet-html-reader

Which versions of PhpSpreadsheet and PHP are affected?

PHP 8.0.7
PhpSpreadsheet 1.18.0

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions