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:
Christoph "criztovyl" Schulz 2018-01-01 12:39:59 +01:00 committed by Adrien Crivelli
parent 98e0a97139
commit cdbf3347cb
No known key found for this signature in database
GPG Key ID: B182FD79DC6DE92E
5 changed files with 126 additions and 5 deletions

View File

@ -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)

View File

@ -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

View File

@ -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 .= ' ';

View File

@ -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;
}
}

View File

@ -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);
}
}