diff --git a/src/PhpSpreadsheet/Writer/Xlsx.php b/src/PhpSpreadsheet/Writer/Xlsx.php index 00c6752037..c18bc85862 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx.php +++ b/src/PhpSpreadsheet/Writer/Xlsx.php @@ -410,6 +410,9 @@ public function save($filename, int $flags = 0): void } } } + if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['drawingOriginalIds']) && !isset($zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'])) { + $zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'] = ''; + } // Add comment relationship parts $legacy = $unparsedLoadedData['sheets'][$this->spreadSheet->getSheet($i)->getCodeName()]['legacyDrawing'] ?? null; diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Chart.php b/src/PhpSpreadsheet/Writer/Xlsx/Chart.php index 9bf65ea5ef..f27156507a 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Chart.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Chart.php @@ -169,8 +169,8 @@ private function writeTitle(XMLWriter $objWriter, ?Title $title = null): void $objWriter->endElement(); $caption = $title->getCaption(); - if ((is_array($caption)) && (count($caption) > 0)) { - $caption = $caption[0]; + if (is_array($caption)) { + $caption = $caption[0] ?? ''; } $this->getParentWriter()->getWriterPartstringtable()->writeRichTextForCharts($objWriter, $caption, 'a'); diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/Issue3767Test.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/Issue3767Test.php new file mode 100644 index 0000000000..9f8c3266c9 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/Issue3767Test.php @@ -0,0 +1,88 @@ +tempfile !== '') { + unlink($this->tempfile); + $this->tempfile = ''; + } + } + + public function readCharts(XlsxReader $reader): void + { + $reader->setIncludeCharts(true); + } + + public function writeCharts(XlsxWriter $writer): void + { + $writer->setIncludeCharts(true); + } + + public function testReadWithoutCharts(): void + { + $reader = new XlsxReader(); + //$this->readCharts($reader); // Commented out - don't want to read charts. + $spreadsheet = $reader->load(self::$testbook); + $sheet = $spreadsheet->getActiveSheet(); + $charts = $sheet->getChartCollection(); + self::assertCount(0, $charts); + $this->tempfile = File::temporaryFileName(); + $writer = new XlsxWriter($spreadsheet); + $this->writeCharts($writer); + $writer->save($this->tempfile); + $spreadsheet->disconnectWorksheets(); + $file = 'zip://'; + $file .= $this->tempfile; + $file .= '#xl/worksheets/_rels/sheet1.xml.rels'; + $data = (string) file_get_contents($file); + // PhpSpreadsheet still generates this target even though charts aren't included + self::assertStringContainsString('Target="../drawings/drawing1.xml"', $data); + $file = 'zip://'; + $file .= $this->tempfile; + $file .= '#xl/drawings/drawing1.xml'; + $data = file_get_contents($file); + self::assertSame('', $data); // fake file because rels needs it + } + + public function testReadWithCharts(): void + { + $reader = new XlsxReader(); + $this->readCharts($reader); + $spreadsheet = $reader->load(self::$testbook); + $xsheet = $spreadsheet->getActiveSheet(); + $xcharts = $xsheet->getChartCollection(); + self::assertCount(1, $xcharts); + /** @var callable */ + $callableReader = [$this, 'readCharts']; + /** @var callable */ + $callableWriter = [$this, 'writeCharts']; + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx', $callableReader, $callableWriter); + $spreadsheet->disconnectWorksheets(); + $sheet = $reloadedSpreadsheet->getActiveSheet(); + $charts = $xsheet->getChartCollection(); + self::assertCount(1, $charts); + // In Excel, a default title ('Chart Title') is shown. + // I can't find that anywhere in the Xml. + self::assertSame('', $charts[0]?->getTitle()?->getCaptionText()); + // Just test anything on the chart. + self::assertSame($sheet->getCell('B2')->getValue(), $charts[0]->getPlotArea()?->getPlotGroup()[0]->getPlotValues()[0]->getDataValues()[0]); + $reloadedSpreadsheet->disconnectWorksheets(); + } +} diff --git a/tests/data/Reader/XLSX/issue.3767.xlsx b/tests/data/Reader/XLSX/issue.3767.xlsx new file mode 100644 index 0000000000..bde09e6a66 Binary files /dev/null and b/tests/data/Reader/XLSX/issue.3767.xlsx differ