From 5bf0656e923c61a9ab64a451a1e7968afadc5df3 Mon Sep 17 00:00:00 2001 From: oleibman <10341515+oleibman@users.noreply.github.com> Date: Sat, 12 Feb 2022 06:43:29 -0800 Subject: [PATCH 1/3] Xlsx Reader Warning When No sz Tag for RichText (#2550) Fix #2542. Xlsx Reader is expecting a `sz` tag when reading RichText, but it is not required, and PhpSpreadsheet issues a warning message when it is missing. --- src/PhpSpreadsheet/Reader/Xlsx.php | 16 +++--- .../Reader/Xlsx/Issue2542Test.php | 47 ++++++++++++++++++ tests/data/Reader/XLSX/issue.2542.xlsx | Bin 0 -> 15599 bytes 3 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Reader/Xlsx/Issue2542Test.php create mode 100644 tests/data/Reader/XLSX/issue.2542.xlsx diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index bf696a60..f7625d5e 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -1691,13 +1691,17 @@ class Xlsx extends BaseReader } else { $objText = $value->createTextRun(StringHelper::controlCharacterOOXML2PHP((string) $run->t)); - $attr = $run->rPr->rFont->attributes(); - if (isset($attr['val'])) { - $objText->getFont()->setName((string) $attr['val']); + if (isset($run->rPr->rFont)) { + $attr = $run->rPr->rFont->attributes(); + if (isset($attr['val'])) { + $objText->getFont()->setName((string) $attr['val']); + } } - $attr = $run->rPr->sz->attributes(); - if (isset($attr['val'])) { - $objText->getFont()->setSize((float) $attr['val']); + if (isset($run->rPr->sz)) { + $attr = $run->rPr->sz->attributes(); + if (isset($attr['val'])) { + $objText->getFont()->setSize((float) $attr['val']); + } } if (isset($run->rPr->color)) { $objText->getFont()->setColor(new Color($this->styleReader->readColor($run->rPr->color))); diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/Issue2542Test.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/Issue2542Test.php new file mode 100644 index 00000000..ad970001 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/Issue2542Test.php @@ -0,0 +1,47 @@ +Factor group +(for Rental items only)', $data); + } + } + + public function testIssue2542(): void + { + $filename = self::$testbook; + $reader = new Xlsx(); + $spreadsheet = $reader->load($filename); + $sheet = $spreadsheet->getActiveSheet(); + $value = $sheet->getCell('P1')->getValue(); + if ($value instanceof RichText) { + self::assertSame("Factor group\n(for Rental items only)", $value->getPlainText()); + } else { + self::fail('Cell P1 is not RichText'); + } + $spreadsheet->disconnectWorksheets(); + } +} diff --git a/tests/data/Reader/XLSX/issue.2542.xlsx b/tests/data/Reader/XLSX/issue.2542.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..85faa63a1e10857bf15ce6bf61670a750cc874c7 GIT binary patch literal 15599 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 YgeYVspr9YCg#h~b0s#gF&Gi`jKgQluZU6uP literal 0 HcmV?d00001 From 90e9ea95055ded508874e1067dc661db33ffc225 Mon Sep 17 00:00:00 2001 From: mweimerskirch <362092+mweimerskirch@users.noreply.github.com> Date: Sat, 12 Feb 2022 15:55:48 +0100 Subject: [PATCH 2/3] Fixed handling of inline strings in XLSX (#2569) * Fixed handling of inline strings * Added an example for the "inline string" datatype for which the generated XML was fixed in the previous commit. * Handle inline strings exactly the same way as regular strings in the XLS writer, because this is only relevant in the XLSX format. --- samples/Basic/02_Types.php | 6 ++++++ src/PhpSpreadsheet/Writer/Xls/Worksheet.php | 1 + src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 2 ++ 3 files changed, 9 insertions(+) diff --git a/samples/Basic/02_Types.php b/samples/Basic/02_Types.php index 79f109f5..965071b8 100644 --- a/samples/Basic/02_Types.php +++ b/samples/Basic/02_Types.php @@ -1,5 +1,6 @@ getActiveSheet() $spreadsheet->getActiveSheet() ->setCellValue('C18', '=HYPERLINK("mailto:abc@def.com","abc@def.com")'); +$spreadsheet->getActiveSheet() + ->setCellValue('A20', 'String') + ->setCellValue('B20', 'inline') + ->setCellValueExplicit('C20', 'This will not be added to sharedStrings.xml', DataType::TYPE_INLINE); + $spreadsheet->getActiveSheet() ->getColumnDimension('B') ->setAutoSize(true); diff --git a/src/PhpSpreadsheet/Writer/Xls/Worksheet.php b/src/PhpSpreadsheet/Writer/Xls/Worksheet.php index 2387ceb0..979d3cb7 100644 --- a/src/PhpSpreadsheet/Writer/Xls/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xls/Worksheet.php @@ -433,6 +433,7 @@ class Worksheet extends BIFFwriter } else { switch ($cell->getDatatype()) { case DataType::TYPE_STRING: + case DataType::TYPE_INLINE: case DataType::TYPE_NULL: if ($cVal === '' || $cVal === null) { $this->writeBlank($row, $column, $xfIndex); diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index 86f966e7..ab390a90 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -1189,10 +1189,12 @@ class Worksheet extends WriterPart { $objWriter->writeAttribute('t', $mappedType); if (!$cellValue instanceof RichText) { + $objWriter->startElement('is'); $objWriter->writeElement( 't', StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue, Settings::htmlEntityFlags())) ); + $objWriter->endElement(); } elseif ($cellValue instanceof RichText) { $objWriter->startElement('is'); $this->getParentWriter()->getWriterPartstringtable()->writeRichText($objWriter, $cellValue); From 0eeba6dc0ce35433de6ce6db57b81f117408d56d Mon Sep 17 00:00:00 2001 From: Orkhan Ahmadov Date: Sat, 12 Feb 2022 16:08:11 +0100 Subject: [PATCH 3/3] `ReferenceHelper@insertNewBefore` checks for missing coordinates before replacing values (#2541) * ReferenceHelper@insertNewBefore now changes for missing columns before replacing and deleting columns * Changelog updated * Fixed code style * Added assertion for all cells. Change bugfix implementation to use `createNewCell` on Worksheet * Additional assertions --- CHANGELOG.md | 2 ++ src/PhpSpreadsheet/ReferenceHelper.php | 20 +++++++++++++ src/PhpSpreadsheet/Worksheet/Worksheet.php | 2 +- .../ReferenceHelperTest.php | 28 +++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b10abb0e..1f470329 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org). ## Unreleased - TBD +- Fixed `ReferenceHelper@insertNewBefore` behavior when removing column before last column with null value + ### Added - Improved support for passing of array arguments to Excel function implementations to return array results (where appropriate). [PR #2562](https://github.com/PHPOffice/PhpSpreadsheet/pull/2562) diff --git a/src/PhpSpreadsheet/ReferenceHelper.php b/src/PhpSpreadsheet/ReferenceHelper.php index 0d72b305..98c4807a 100644 --- a/src/PhpSpreadsheet/ReferenceHelper.php +++ b/src/PhpSpreadsheet/ReferenceHelper.php @@ -398,6 +398,26 @@ class ReferenceHelper } } + // Find missing coordinates. This is important when inserting column before the last column + $missingCoordinates = array_filter( + array_map(function ($row) use ($highestColumn) { + return $highestColumn . $row; + }, range(1, $highestRow)), + function ($coordinate) use ($allCoordinates) { + return !in_array($coordinate, $allCoordinates); + } + ); + + // Create missing cells with null values + if (!empty($missingCoordinates)) { + foreach ($missingCoordinates as $coordinate) { + $worksheet->createNewCell($coordinate); + } + + // Refresh all coordinates + $allCoordinates = $worksheet->getCoordinates(); + } + // Loop through cells, bottom-up, and change cell coordinate if ($remove) { // It's faster to reverse and pop than to use unshift, especially with large cell collections diff --git a/src/PhpSpreadsheet/Worksheet/Worksheet.php b/src/PhpSpreadsheet/Worksheet/Worksheet.php index 51cf3c52..362f20f0 100644 --- a/src/PhpSpreadsheet/Worksheet/Worksheet.php +++ b/src/PhpSpreadsheet/Worksheet/Worksheet.php @@ -1291,7 +1291,7 @@ class Worksheet implements IComparable * * @return Cell Cell that was created */ - private function createNewCell($coordinate) + public function createNewCell($coordinate) { $cell = new Cell(null, DataType::TYPE_NULL, $this); $this->cellCollection->add($coordinate, $cell); diff --git a/tests/PhpSpreadsheetTests/ReferenceHelperTest.php b/tests/PhpSpreadsheetTests/ReferenceHelperTest.php index 874dbfb5..2c016b0b 100644 --- a/tests/PhpSpreadsheetTests/ReferenceHelperTest.php +++ b/tests/PhpSpreadsheetTests/ReferenceHelperTest.php @@ -149,4 +149,32 @@ class ReferenceHelperTest extends TestCase self::assertSame($oldValue, $newValue); self::assertSame($oldDataType, $newDataType); } + + public function testRemoveColumnShiftsCorrectColumnValueIntoRemovedColumnCoordinates(): void + { + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + $sheet->fromArray([ + ['a1', 'b1', 'c1'], + ['a2', 'b2', null], + ]); + + $cells = $sheet->toArray(); + self::assertSame('a1', $cells[0][0]); + self::assertSame('b1', $cells[0][1]); + self::assertSame('c1', $cells[0][2]); + self::assertSame('a2', $cells[1][0]); + self::assertSame('b2', $cells[1][1]); + self::assertNull($cells[1][2]); + + $sheet->removeColumn('B'); + + $cells = $sheet->toArray(); + self::assertSame('a1', $cells[0][0]); + self::assertSame('c1', $cells[0][1]); + self::assertArrayNotHasKey(2, $cells[0]); + self::assertSame('a2', $cells[1][0]); + self::assertNull($cells[1][1]); + self::assertArrayNotHasKey(2, $cells[1]); + } }