From 3446bb0ef781465f12e073b918dace0cffd03a18 Mon Sep 17 00:00:00 2001 From: Vagir Date: Sat, 23 May 2020 14:09:10 +0300 Subject: [PATCH] Fix saving XLSX with drawings (#1462) * Fix incorrect behaviour when saving XLSX file with drawings --- CHANGELOG.md | 1 + src/PhpSpreadsheet/Writer/Xlsx/Rels.php | 11 +++-- src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 1 + .../Writer/Xlsx/DrawingsTest.php | 45 ++++++++++++++++++ .../data/Writer/XLSX/drawing_on_2nd_page.xlsx | Bin 0 -> 16265 bytes 5 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingsTest.php create mode 100644 tests/data/Writer/XLSX/drawing_on_2nd_page.xlsx diff --git a/CHANGELOG.md b/CHANGELOG.md index eb9b3810..22fd8c3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). - Fix RATE, PRICE, XIRR, and XNPV Functions [#1456](https://github.com/PHPOffice/PhpSpreadsheet/pull/1456) - Save Excel 2010+ functions properly in XLSX [#1461](https://github.com/PHPOffice/PhpSpreadsheet/pull/1461) - Several improvements in HTML writer [#1464](https://github.com/PHPOffice/PhpSpreadsheet/pull/1464) +- Fix incorrect behaviour when saving XLSX file with drawings [#1462](https://github.com/PHPOffice/PhpSpreadsheet/pull/1462), - Fix Crash while trying setting a cell the value "123456\n" [#1476](https://github.com/PHPOffice/PhpSpreadsheet/pull/1481) ### Changed diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Rels.php b/src/PhpSpreadsheet/Writer/Xlsx/Rels.php index c2876065..a4e5769e 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Rels.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Rels.php @@ -183,7 +183,6 @@ class Rels extends WriterPart $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); // Write drawing relationships? - $d = 0; $drawingOriginalIds = []; $unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData(); if (isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingOriginalIds'])) { @@ -197,13 +196,19 @@ class Rels extends WriterPart } if (($pWorksheet->getDrawingCollection()->count() > 0) || (count($charts) > 0) || $drawingOriginalIds) { - $relPath = '../drawings/drawing' . $pWorksheetId . '.xml'; - $rId = ++$d; + $rId = 1; + // Use original $relPath to get original $rId. + // Take first. In future can be overwritten. + // (! synchronize with \PhpOffice\PhpSpreadsheet\Writer\Xlsx\Worksheet::writeDrawings) + reset($drawingOriginalIds); + $relPath = key($drawingOriginalIds); if (isset($drawingOriginalIds[$relPath])) { $rId = (int) (substr($drawingOriginalIds[$relPath], 3)); } + // Generate new $relPath to write drawing relationship + $relPath = '../drawings/drawing' . $pWorksheetId . '.xml'; $this->writeRelationship( $objWriter, $rId, diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index 15359a4c..3d47eeaa 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -1215,6 +1215,7 @@ class Worksheet extends WriterPart if (isset($unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds'])) { $drawingOriginalIds = $unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds']; // take first. In future can be overriten + // (! synchronize with \PhpOffice\PhpSpreadsheet\Writer\Xlsx\Rels::writeWorksheetRelationships) $rId = reset($drawingOriginalIds); } diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingsTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingsTest.php new file mode 100644 index 00000000..d6ad77c6 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingsTest.php @@ -0,0 +1,45 @@ +prevValue = Settings::getLibXmlLoaderOptions(); + + // Disable validating XML with the DTD + Settings::setLibXmlLoaderOptions($this->prevValue & ~LIBXML_DTDVALID & ~LIBXML_DTDATTR & ~LIBXML_DTDLOAD); + } + + protected function tearDown(): void + { + Settings::setLibXmlLoaderOptions($this->prevValue); + } + + /** + * Test save and load XLSX file with drawing on 2nd worksheet. + */ + public function testSaveLoadWithDrawingOn2ndWorksheet(): void + { + // Read spreadsheet from file + $inputFilename = 'tests/data/Writer/XLSX/drawing_on_2nd_page.xlsx'; + $reader = new Xlsx(); + $spreadsheet = $reader->load($inputFilename); + + // Save spreadsheet to file and read it back + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx'); + + // Fake assert. The only thing we need is to ensure the file is loaded without exception + self::assertNotNull($reloadedSpreadsheet); + } +} diff --git a/tests/data/Writer/XLSX/drawing_on_2nd_page.xlsx b/tests/data/Writer/XLSX/drawing_on_2nd_page.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..fa51215ac8fe09ce4b7e2e8f0473cc85ffb364b0 GIT binary patch literal 16265 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 literal 0 HcmV?d00001