From e0dff1c8b064d595ee35ce2ae3a8d5b932fc601c Mon Sep 17 00:00:00 2001 From: Kris2x Date: Wed, 23 Apr 2025 13:16:00 +0200 Subject: [PATCH 1/5] Improve XML text element creation and add tests for special character handling (eq. &) --- src/XlsxFastEditor.php | 14 +++++++++----- tests/test.php | 6 ++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/XlsxFastEditor.php b/src/XlsxFastEditor.php index 12c586a..34f5443 100644 --- a/src/XlsxFastEditor.php +++ b/src/XlsxFastEditor.php @@ -1028,13 +1028,17 @@ public function _makeNewSharedString(string $value): int } try { - $t = $dom->createElement('t', $value); + // First, we create an empty element t + $t = $dom->createElement('t'); + if ($t === false) { + throw new XlsxFastEditorXmlException('Failed to create element'); + } + // Add content as a text node + $textNode = $dom->createTextNode($value); + $t->appendChild($textNode); } catch (\DOMException $dex) { throw new XlsxFastEditorXmlException('Error creating in shared strings!', $dex->code, $dex); } - if ($t === false) { - throw new XlsxFastEditorXmlException('Error creating in shared strings!'); - } $si->appendChild($t); if (!($dom->firstElementChild instanceof \DOMElement)) { throw new XlsxFastEditorXmlException('Invalid shared strings!'); @@ -1048,7 +1052,7 @@ public function _makeNewSharedString(string $value): int $dom->firstElementChild->setAttribute('uniqueCount', (string)$uniqueCount); $this->touchPath(self::SHARED_STRINGS_PATH); - return $uniqueCount - 1; // Base 0 + return $uniqueCount - 1; // Base 0 } /** diff --git a/tests/test.php b/tests/test.php index 66a688f..ae5e819 100644 --- a/tests/test.php +++ b/tests/test.php @@ -119,6 +119,9 @@ $xlsxFastEditor->writeInt($sheet2, 'C3', -7); $xlsxFastEditor->writeFloat($sheet2, 'D3', 273.15); + // Test writing special character '&' + $xlsxFastEditor->writeString($sheet2, 'A5', '&'); + // Writing non-existing cells but existing lines $xlsxFastEditor->writeFormula($sheet2, 'I2', '=7*3'); $xlsxFastEditor->writeString($sheet2, 'F2', 'γ'); @@ -166,6 +169,9 @@ assert($xlsxFastEditor->readString($sheet1, 'B2') === 'World'); + // Test writing special character '&' + assert($xlsxFastEditor->readString($sheet2, 'A5') === '&'); + $xlsxFastEditor->close(); // Verify by hand that the resulting file opens without warning in Microsoft Excel. From 2423e41210face12cd8f804f18ef2514134e0e03 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 24 Apr 2025 00:59:04 +0200 Subject: [PATCH 2/5] Revert unrelated change --- src/XlsxFastEditor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/XlsxFastEditor.php b/src/XlsxFastEditor.php index 34f5443..c70134d 100644 --- a/src/XlsxFastEditor.php +++ b/src/XlsxFastEditor.php @@ -1052,7 +1052,7 @@ public function _makeNewSharedString(string $value): int $dom->firstElementChild->setAttribute('uniqueCount', (string)$uniqueCount); $this->touchPath(self::SHARED_STRINGS_PATH); - return $uniqueCount - 1; // Base 0 + return $uniqueCount - 1; // Base 0 } /** From a9ddee351d5781e80b7b40afd8f3cb52235dfc8e Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 24 Apr 2025 00:59:33 +0200 Subject: [PATCH 3/5] Handle another error possibility --- src/XlsxFastEditor.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/XlsxFastEditor.php b/src/XlsxFastEditor.php index c70134d..17f029e 100644 --- a/src/XlsxFastEditor.php +++ b/src/XlsxFastEditor.php @@ -1035,6 +1035,9 @@ public function _makeNewSharedString(string $value): int } // Add content as a text node $textNode = $dom->createTextNode($value); + if ($textNode === false) { + throw new XlsxFastEditorXmlException('Failed to create text node'); + } $t->appendChild($textNode); } catch (\DOMException $dex) { throw new XlsxFastEditorXmlException('Error creating in shared strings!', $dex->code, $dex); From 2830286953e8a3efd21a51776c200462602737f7 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 24 Apr 2025 01:00:02 +0200 Subject: [PATCH 4/5] Handle special XML characters also for formula --- src/XlsxFastEditorCell.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/XlsxFastEditorCell.php b/src/XlsxFastEditorCell.php index 738579f..d568605 100644 --- a/src/XlsxFastEditorCell.php +++ b/src/XlsxFastEditorCell.php @@ -307,10 +307,17 @@ public function writeFormula(string $value): void throw new XlsxFastEditorXmlException("Internal error accessing cell {$this->name()}!"); } try { - $f = $dom->createElement('f', $value); - if (!($f instanceof \DOMElement)) { + // First, we create an empty element t + $f = $dom->createElement('f'); + if ($f === false) { throw new XlsxFastEditorXmlException("Error creating DOMElement of formula for cell {$this->name()}!"); } + // Add content as a text node + $textNode = $dom->createTextNode($value); + if ($textNode === false) { + throw new XlsxFastEditorXmlException("Error creating text node of formula for cell {$this->name()}!"); + } + $f->appendChild($textNode); } catch (\DOMException $dex) { throw new XlsxFastEditorXmlException("Error creating formula for cell {$this->name()}!", $dex->code, $dex); } From 3649e2a2ca1f419ef5851ec937aefab1efbbce8c Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 24 Apr 2025 01:00:18 +0200 Subject: [PATCH 5/5] Improve tests --- tests/test.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/test.php b/tests/test.php index ae5e819..70fa78e 100644 --- a/tests/test.php +++ b/tests/test.php @@ -119,8 +119,9 @@ $xlsxFastEditor->writeInt($sheet2, 'C3', -7); $xlsxFastEditor->writeFloat($sheet2, 'D3', 273.15); - // Test writing special character '&' - $xlsxFastEditor->writeString($sheet2, 'A5', '&'); + // Writing special XML characters + $xlsxFastEditor->writeString($sheet2, 'B5', '< " & \' >'); + $xlsxFastEditor->writeFormula($sheet2, 'C5', '=LEN("< & \' >")'); // Writing non-existing cells but existing lines $xlsxFastEditor->writeFormula($sheet2, 'I2', '=7*3'); @@ -169,8 +170,9 @@ assert($xlsxFastEditor->readString($sheet1, 'B2') === 'World'); - // Test writing special character '&' - assert($xlsxFastEditor->readString($sheet2, 'A5') === '&'); + // Test special XML characters + assert($xlsxFastEditor->readString($sheet2, 'B5') === '< " & \' >'); + assert($xlsxFastEditor->readFormula($sheet2, 'C5') === '=LEN("< & \' >")'); $xlsxFastEditor->close();