Skip to content

Commit ca41de3

Browse files
authored
Merge pull request #4086 from oleibman/issue4081
Ods Comments With Newlines
2 parents 6d2d99a + 96f0944 commit ca41de3

File tree

5 files changed

+78
-8
lines changed

5 files changed

+78
-8
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
3535
- Mpdf and Tcpdf Borders on Merged Cells. [Issue #3557](https://github.com/PHPOffice/PhpSpreadsheet/issues/3557) [PR #4047](https://github.com/PHPOffice/PhpSpreadsheet/pull/4047)
3636
- Xls Conditional Format Improvements. [PR #4030](https://github.com/PHPOffice/PhpSpreadsheet/pull/4030) [PR #4033](https://github.com/PHPOffice/PhpSpreadsheet/pull/4033)
3737
- Conditional Range Unions and Intersections [Issue #4039](https://github.com/PHPOffice/PhpSpreadsheet/issues/4039) [PR #4042](https://github.com/PHPOffice/PhpSpreadsheet/pull/4042)
38+
- Ods comments with newlines. [Issue #4081](https://github.com/PHPOffice/PhpSpreadsheet/issues/4081) [PR #4086](https://github.com/PHPOffice/PhpSpreadsheet/pull/4086)
3839
- Propagate errors in Text functions. [Issue #2581](https://github.com/PHPOffice/PhpSpreadsheet/issues/2581) [PR #4080](https://github.com/PHPOffice/PhpSpreadsheet/pull/4080)
3940
- Csv Reader allow use of html mimetype. [Issue #4036](https://github.com/PHPOffice/PhpSpreadsheet/issues/4036) [PR #4040](https://github.com/PHPOffice/PhpSpreadsheet/pull/4040)
4041
- Problem rendering line chart with missing plot label. [PR #4074](https://github.com/PHPOffice/PhpSpreadsheet/pull/4074)

src/PhpSpreadsheet/Reader/Ods.php

+20-7
Original file line numberDiff line numberDiff line change
@@ -436,14 +436,25 @@ public function loadIntoExisting(string $filename, Spreadsheet $spreadsheet): Sp
436436

437437
if ($annotation->length > 0 && $annotation->item(0) !== null) {
438438
$textNode = $annotation->item(0)->getElementsByTagNameNS($textNs, 'p');
439+
$textNodeLength = $textNode->length;
440+
$newLineOwed = false;
441+
for ($textNodeIndex = 0; $textNodeIndex < $textNodeLength; ++$textNodeIndex) {
442+
$textNodeItem = $textNode->item($textNodeIndex);
443+
if ($textNodeItem !== null) {
444+
$text = $this->scanElementForText($textNodeItem);
445+
if ($newLineOwed) {
446+
$spreadsheet->getActiveSheet()
447+
->getComment($columnID . $rowID)
448+
->getText()
449+
->createText("\n");
450+
}
451+
$newLineOwed = true;
439452

440-
if ($textNode->length > 0 && $textNode->item(0) !== null) {
441-
$text = $this->scanElementForText($textNode->item(0));
442-
443-
$spreadsheet->getActiveSheet()
444-
->getComment($columnID . $rowID)
445-
->setText($this->parseRichText($text));
446-
// ->setAuthor( $author )
453+
$spreadsheet->getActiveSheet()
454+
->getComment($columnID . $rowID)
455+
->getText()
456+
->createText($this->parseRichText($text));
457+
}
447458
}
448459
}
449460

@@ -731,6 +742,8 @@ protected function scanElementForText(DOMNode $element): string
731742
/** @var DOMNode $child */
732743
if ($child->nodeType == XML_TEXT_NODE) {
733744
$str .= $child->nodeValue;
745+
} elseif ($child->nodeType == XML_ELEMENT_NODE && $child->nodeName == 'text:line-break') {
746+
$str .= "\n";
734747
} elseif ($child->nodeType == XML_ELEMENT_NODE && $child->nodeName == 'text:s') {
735748
// It's a space
736749

src/PhpSpreadsheet/Writer/Ods/Cell/Comment.php

+16-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,22 @@ public static function write(XMLWriter $objWriter, Cell $cell): void
2424
$objWriter->writeAttribute('svg:x', $comment->getMarginLeft());
2525
$objWriter->writeAttribute('svg:y', $comment->getMarginTop());
2626
$objWriter->writeElement('dc:creator', $comment->getAuthor());
27-
$objWriter->writeElement('text:p', $comment->getText()->getPlainText());
27+
28+
$objWriter->startElement('text:p');
29+
$text = $comment->getText()->getPlainText();
30+
$textElements = explode("\n", $text);
31+
$newLineOwed = false;
32+
foreach ($textElements as $textSegment) {
33+
if ($newLineOwed) {
34+
$objWriter->writeElement('text:line-break');
35+
}
36+
$newLineOwed = true;
37+
if ($textSegment !== '') {
38+
$objWriter->writeElement('text:span', $textSegment);
39+
}
40+
}
41+
$objWriter->endElement(); // text:p
42+
2843
$objWriter->endElement();
2944
}
3045
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpOffice\PhpSpreadsheetTests\Reader\Ods;
6+
7+
use PhpOffice\PhpSpreadsheet\Reader\Ods;
8+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
9+
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
10+
11+
class MultiLineCommentTest extends AbstractFunctional
12+
{
13+
public function testMultipleParagraphs(): void
14+
{
15+
$filename = 'tests/data/Reader/Ods/issue.4081.ods';
16+
$reader = new Ods();
17+
$spreadsheet = $reader->load($filename);
18+
$sheet = $spreadsheet->getActiveSheet();
19+
self::assertSame("First line.\n\nSecond line.", $sheet->getComment('A1')->getText()->getPlainText());
20+
$spreadsheet->disconnectWorksheets();
21+
}
22+
23+
public function testOneParagraphMultipleSpans(): void
24+
{
25+
$spreadsheetOld = new Spreadsheet();
26+
$sheetOld = $spreadsheetOld->getActiveSheet();
27+
$sheetOld->getCell('A1')->setValue('Hello');
28+
$text = $sheetOld->getComment('A1')->getText();
29+
$text->createText('First');
30+
$text->createText(' line.');
31+
$text->createText("\n");
32+
$text->createText("\n");
33+
$text->createText("Second line.\nThird line.");
34+
$spreadsheet = $this->writeAndReload($spreadsheetOld, 'Ods');
35+
$spreadsheetOld->disconnectWorksheets();
36+
37+
$sheet = $spreadsheet->getActiveSheet();
38+
self::assertSame("First line.\n\nSecond line.\nThird line.", $sheet->getComment('A1')->getText()->getPlainText());
39+
$spreadsheet->disconnectWorksheets();
40+
}
41+
}

tests/data/Reader/Ods/issue.4081.ods

3.07 KB
Binary file not shown.

0 commit comments

Comments
 (0)