diff --git a/CHANGELOG.md b/CHANGELOG.md index cc558ee164..0cc47481a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com) and this project adheres to [Semantic Versioning](https://semver.org). ## [Unreleased] - +Fix saving XLSX with drawings [#1421](https://github.com/PHPOffice/PhpSpreadsheet/issues/1421) ## [1.8.2] - 2019-07-08 diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Rels.php b/src/PhpSpreadsheet/Writer/Xlsx/Rels.php index 76c196b449..3820d9a590 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Rels.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Rels.php @@ -194,7 +194,6 @@ public function writeWorksheetRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\ $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'])) { @@ -208,13 +207,19 @@ public function writeWorksheetRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\ } 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 065eaaf1c9..34e913d3df 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -1176,6 +1176,7 @@ private function writeDrawings(XMLWriter $objWriter, PhpspreadsheetWorksheet $pS 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 0000000000..d6ad77c63f --- /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 0000000000..fa51215ac8 Binary files /dev/null and b/tests/data/Writer/XLSX/drawing_on_2nd_page.xlsx differ