Support for cell comments in HTML writer and reader
The behavior is similar to what is done in LibreOffice. That means if there is a comment it will be shown with a small indicator and the actual comment will be revealed when mouse hover over the indicator. Fixes #308 Closes #310
This commit is contained in:
parent
98e0a97139
commit
cdbf3347cb
|
@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||
|
||||
### Added
|
||||
|
||||
- Support cell comments in HTML writer and reader- [#308](https://github.com/PHPOffice/PhpSpreadsheet/issues/308)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Better auto-detection of CSV separators - [#305](https://github.com/PHPOffice/PhpSpreadsheet/issues/305)
|
||||
|
|
|
@ -1231,14 +1231,14 @@
|
|||
<td style="text-align: center; color: orange;">●</td>
|
||||
<td style="text-align: center; color: orange;">●</td>
|
||||
<td style="text-align: center;">N/A</td>
|
||||
<td></td>
|
||||
<td style="text-align: center; color: orange;">● <sup>1</sup></td>
|
||||
<td style="text-align: center;">N/A</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-left: 1em;">Rich Text</td>
|
||||
<td style="text-align: center; color: red;">✖ <sup>1</sup></td>
|
||||
<td style="text-align: center; color: red;">✖ <sup>2</sup></td>
|
||||
<td style="text-align: center; color: green;">✔</td>
|
||||
<td style="text-align: center; color: red;">✖</td>
|
||||
<td style="text-align: center; color: red;">✖</td>
|
||||
|
@ -1256,7 +1256,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td style="padding-left: 1em;">Alignment</td>
|
||||
<td style="text-align: center; color: red;">✖ <sup>2</sup></td>
|
||||
<td style="text-align: center; color: red;">✖ <sup>3</sup></td>
|
||||
<td style="text-align: center; color: red;">✖</td>
|
||||
<td style="text-align: center; color: red;">✖</td>
|
||||
<td style="text-align: center; color: red;">✖</td>
|
||||
|
@ -1568,5 +1568,6 @@
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
1. Only BIFF8 files support Rich Text. Prior to that, comments could only be plain text
|
||||
2. Only BIFF8 files support alignment and rotation. Prior to that, comments could only be unformatted text
|
||||
1. Only text contents
|
||||
2. Only BIFF8 files support Rich Text. Prior to that, comments could only be plain text
|
||||
3. Only BIFF8 files support alignment and rotation. Prior to that, comments could only be unformatted text
|
||||
|
|
|
@ -312,6 +312,14 @@ class Html extends BaseReader
|
|||
case 'em':
|
||||
case 'strong':
|
||||
case 'b':
|
||||
if (isset($attributeArray['class']) && $attributeArray['class'] === 'comment') {
|
||||
$sheet->getComment($column . $row)
|
||||
->getText()
|
||||
->createTextRun($child->textContent);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ($cellContent > '') {
|
||||
$cellContent .= ' ';
|
||||
}
|
||||
|
@ -354,6 +362,10 @@ class Html extends BaseReader
|
|||
}
|
||||
|
||||
break;
|
||||
case 'class':
|
||||
if ($attributeValue === 'comment-indicator') {
|
||||
break; // Ignore - it's just a red square.
|
||||
}
|
||||
}
|
||||
}
|
||||
$cellContent .= ' ';
|
||||
|
|
|
@ -830,6 +830,25 @@ class Html extends BaseWriter
|
|||
$css['html']['background-color'] = 'white';
|
||||
}
|
||||
|
||||
// CSS for comments as found in LibreOffice
|
||||
$css['a.comment-indicator:hover + div.comment'] = [
|
||||
'background' => '#ffd',
|
||||
'position' => 'absolute',
|
||||
'display' => 'block',
|
||||
'border' => '1px solid black',
|
||||
'padding' => '0.5em',
|
||||
];
|
||||
|
||||
$css['a.comment-indicator'] = [
|
||||
'background' => 'red',
|
||||
'display' => 'inline-block',
|
||||
'border' => '1px solid black',
|
||||
'width' => '0.5em',
|
||||
'height' => '0.5em',
|
||||
];
|
||||
|
||||
$css['div.comment']['display'] = 'none';
|
||||
|
||||
// table { }
|
||||
$css['table']['border-collapse'] = 'collapse';
|
||||
if (!$this->isPdf) {
|
||||
|
@ -1385,6 +1404,8 @@ class Html extends BaseWriter
|
|||
}
|
||||
$html .= '>';
|
||||
|
||||
$html .= $this->writeComment($pSheet, $coordinate);
|
||||
|
||||
// Image?
|
||||
$html .= $this->writeImageInCell($pSheet, $coordinate);
|
||||
|
||||
|
@ -1646,4 +1667,26 @@ class Html extends BaseWriter
|
|||
|
||||
return "<style>\n" . $htmlPage . $htmlBody . "</style>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a comment in the same format as LibreOffice.
|
||||
*
|
||||
* @see https://github.com/LibreOffice/core/blob/9fc9bf3240f8c62ad7859947ab8a033ac1fe93fa/sc/source/filter/html/htmlexp.cxx#L1073-L1092
|
||||
*
|
||||
* @param Worksheet $pSheet
|
||||
* @param string $coordinate
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function writeComment(Worksheet $pSheet, $coordinate)
|
||||
{
|
||||
$result = '';
|
||||
if (!$this->isPdf && isset($pSheet->getComments()[$coordinate])) {
|
||||
$result .= '<a class="comment-indicator"></a>';
|
||||
$result .= '<div class="comment">' . nl2br($pSheet->getComment($coordinate)->getText()->getPlainText()) . '</div>';
|
||||
$result .= PHP_EOL;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Functional;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\RichText\RichText;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
|
||||
class HtmlCommentsTest extends AbstractFunctional
|
||||
{
|
||||
private $spreadsheet;
|
||||
|
||||
public function providerCommentRichText()
|
||||
{
|
||||
$valueSingle = 'I am comment.';
|
||||
$valueMulti = 'I am ' . PHP_EOL . 'multi-line' . PHP_EOL . 'comment.';
|
||||
|
||||
$plainSingle = new RichText();
|
||||
$plainSingle->createText($valueSingle);
|
||||
|
||||
$plainMulti = new RichText();
|
||||
$plainMulti->createText($valueMulti);
|
||||
|
||||
$richSingle = new RichText();
|
||||
$richSingle->createTextRun($valueSingle)->getFont()->setBold(true);
|
||||
|
||||
$richMultiSimple = new RichText();
|
||||
$richMultiSimple->createTextRun($valueMulti)->getFont()->setBold(true);
|
||||
|
||||
$richMultiMixed = new RichText();
|
||||
$richMultiMixed->createText('I am' . PHP_EOL);
|
||||
$richMultiMixed->createTextRun('multi-line')->getFont()->setBold(true);
|
||||
$richMultiMixed->createText(PHP_EOL . 'comment!');
|
||||
|
||||
return [
|
||||
'single line plain text' => [$plainSingle],
|
||||
'multi-line plain text' => [$plainMulti],
|
||||
'single line simple rich text' => [$richSingle],
|
||||
'multi-line simple rich text' => [$richMultiSimple],
|
||||
'multi-line mixed rich text' => [$richMultiMixed],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCommentRichText
|
||||
*
|
||||
* @param mixed $richText
|
||||
*/
|
||||
public function testComments($richText)
|
||||
{
|
||||
$this->spreadsheet = new Spreadsheet();
|
||||
|
||||
$this->spreadsheet->getActiveSheet()->getCell('A1')->setValue('Comment');
|
||||
|
||||
$this->spreadsheet->getActiveSheet()
|
||||
->getComment('A1')
|
||||
->setText($richText);
|
||||
|
||||
$reloadedSpreadsheet = $this->writeAndReload($this->spreadsheet, 'Html');
|
||||
|
||||
$actual = $reloadedSpreadsheet->getActiveSheet()->getComment('A1')->getText()->getPlainText();
|
||||
self::assertSame($richText->getPlainText(), $actual);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue