mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-09-15 04:26:25 +00:00
Ods Comments With Newlines
Fix #4081. Ods Reader was not reading entire contents of comment. On further inspection, Ods Writer also was not handling comments completely correctly. Ods comments are recorded as `text:p` children of `office:annotation` elements. A newline is inserted between successive `text:p` elements. The `text:p` element itself can have as descendants (at least): - raw text - `text:span` elements - `text:line-break` elements, which also causes the insertion of a newline Ods Writer is changed to use a single `text:p` with multiple span/linebreak elements. Ods Reader is changed to process in their entirety either that form, or multiple `text:p` elements. Styling of the individual elements of the comment is permitted in Ods. That has not been supported till now by PhpSpreadsheet, and this PR will not address that situation - Ods Reader hast little style support, and this would hardly be the most urgent case where it is missing.
This commit is contained in:
@@ -436,14 +436,25 @@ class Ods extends BaseReader
|
||||
|
||||
if ($annotation->length > 0 && $annotation->item(0) !== null) {
|
||||
$textNode = $annotation->item(0)->getElementsByTagNameNS($textNs, 'p');
|
||||
$textNodeLength = $textNode->length;
|
||||
$newLineOwed = false;
|
||||
for ($textNodeIndex = 0; $textNodeIndex < $textNodeLength; ++$textNodeIndex) {
|
||||
$textNodeItem = $textNode->item($textNodeIndex);
|
||||
if ($textNodeItem !== null) {
|
||||
$text = $this->scanElementForText($textNodeItem);
|
||||
if ($newLineOwed) {
|
||||
$spreadsheet->getActiveSheet()
|
||||
->getComment($columnID . $rowID)
|
||||
->getText()
|
||||
->createText("\n");
|
||||
}
|
||||
$newLineOwed = true;
|
||||
|
||||
if ($textNode->length > 0 && $textNode->item(0) !== null) {
|
||||
$text = $this->scanElementForText($textNode->item(0));
|
||||
|
||||
$spreadsheet->getActiveSheet()
|
||||
->getComment($columnID . $rowID)
|
||||
->setText($this->parseRichText($text));
|
||||
// ->setAuthor( $author )
|
||||
$spreadsheet->getActiveSheet()
|
||||
->getComment($columnID . $rowID)
|
||||
->getText()
|
||||
->createText($this->parseRichText($text));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -731,6 +742,8 @@ class Ods extends BaseReader
|
||||
/** @var DOMNode $child */
|
||||
if ($child->nodeType == XML_TEXT_NODE) {
|
||||
$str .= $child->nodeValue;
|
||||
} elseif ($child->nodeType == XML_ELEMENT_NODE && $child->nodeName == 'text:line-break') {
|
||||
$str .= "\n";
|
||||
} elseif ($child->nodeType == XML_ELEMENT_NODE && $child->nodeName == 'text:s') {
|
||||
// It's a space
|
||||
|
||||
|
||||
@@ -24,7 +24,22 @@ class Comment
|
||||
$objWriter->writeAttribute('svg:x', $comment->getMarginLeft());
|
||||
$objWriter->writeAttribute('svg:y', $comment->getMarginTop());
|
||||
$objWriter->writeElement('dc:creator', $comment->getAuthor());
|
||||
$objWriter->writeElement('text:p', $comment->getText()->getPlainText());
|
||||
|
||||
$objWriter->startElement('text:p');
|
||||
$text = $comment->getText()->getPlainText();
|
||||
$textElements = explode("\n", $text);
|
||||
$newLineOwed = false;
|
||||
foreach ($textElements as $textSegment) {
|
||||
if ($newLineOwed) {
|
||||
$objWriter->writeElement('text:line-break');
|
||||
}
|
||||
$newLineOwed = true;
|
||||
if ($textSegment !== '') {
|
||||
$objWriter->writeElement('text:span', $textSegment);
|
||||
}
|
||||
}
|
||||
$objWriter->endElement(); // text:p
|
||||
|
||||
$objWriter->endElement();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Reader\Ods;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Ods;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
|
||||
|
||||
class MultiLineCommentTest extends AbstractFunctional
|
||||
{
|
||||
public function testMultipleParagraphs(): void
|
||||
{
|
||||
$filename = 'tests/data/Reader/Ods/issue.4081.ods';
|
||||
$reader = new Ods();
|
||||
$spreadsheet = $reader->load($filename);
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
self::assertSame("First line.\n\nSecond line.", $sheet->getComment('A1')->getText()->getPlainText());
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
}
|
||||
|
||||
public function testOneParagraphMultipleSpans(): void
|
||||
{
|
||||
$spreadsheetOld = new Spreadsheet();
|
||||
$sheetOld = $spreadsheetOld->getActiveSheet();
|
||||
$sheetOld->getCell('A1')->setValue('Hello');
|
||||
$text = $sheetOld->getComment('A1')->getText();
|
||||
$text->createText('First');
|
||||
$text->createText(' line.');
|
||||
$text->createText("\n");
|
||||
$text->createText("\n");
|
||||
$text->createText("Second line.\nThird line.");
|
||||
$spreadsheet = $this->writeAndReload($spreadsheetOld, 'Ods');
|
||||
$spreadsheetOld->disconnectWorksheets();
|
||||
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
self::assertSame("First line.\n\nSecond line.\nThird line.", $sheet->getComment('A1')->getText()->getPlainText());
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user