From f0059bb4bcd65e5465673ca67d1274948301f9a3 Mon Sep 17 00:00:00 2001 From: oleibman <10341515+oleibman@users.noreply.github.com> Date: Thu, 14 Jul 2022 07:48:53 -0700 Subject: [PATCH] Xlsx Chart Reader and Writer Mishandle Explosion Value (#2928) Fix #2506. Reader only tests if Explosion is set without capturing its value. Writer hard-codes value when it is set. --- src/PhpSpreadsheet/Reader/Xlsx/Chart.php | 2 +- src/PhpSpreadsheet/Writer/Xlsx/Chart.php | 16 ++-- .../Chart/Issue2506Test.php | 73 ++++++++++++++++++ tests/data/Reader/XLSX/issue.2506.xlsx | Bin 0 -> 22547 bytes 4 files changed, 79 insertions(+), 12 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Chart/Issue2506Test.php create mode 100644 tests/data/Reader/XLSX/issue.2506.xlsx diff --git a/src/PhpSpreadsheet/Reader/Xlsx/Chart.php b/src/PhpSpreadsheet/Reader/Xlsx/Chart.php index cf77a7f2..55365a17 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx/Chart.php +++ b/src/PhpSpreadsheet/Reader/Xlsx/Chart.php @@ -228,7 +228,7 @@ class Chart case 'doughnutChart': case 'pieChart': case 'pie3DChart': - $explosion = isset($chartDetail->ser->explosion); + $explosion = self::getAttribute($chartDetail->ser->explosion, 'val', 'string'); $plotSer = $this->chartDataSeries($chartDetail, $chartDetailKey); $plotSer->setPlotStyle("$explosion"); $plotSeries[] = $plotSer; diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Chart.php b/src/PhpSpreadsheet/Writer/Xlsx/Chart.php index 356b44e9..8d01038b 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Chart.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Chart.php @@ -875,10 +875,6 @@ class Chart extends WriterPart $objWriter->writeAttribute('val', "$val"); $objWriter->endElement(); // c:idx - $objWriter->startElement('c:bubble3D'); - $objWriter->writeAttribute('val', '0'); - $objWriter->endElement(); // c:bubble3D - $objWriter->startElement('c:spPr'); $this->writeColor($objWriter, $fillColor); $objWriter->endElement(); // c:spPr @@ -1052,13 +1048,11 @@ class Chart extends WriterPart $catIsMultiLevelSeries = $catIsMultiLevelSeries || $plotSeriesCategory->isMultiLevelSeries(); if (($groupType == DataSeries::TYPE_PIECHART) || ($groupType == DataSeries::TYPE_PIECHART_3D) || ($groupType == DataSeries::TYPE_DONUTCHART)) { - if ($plotGroup->getPlotStyle() !== null) { - $plotStyle = $plotGroup->getPlotStyle(); - if ($plotStyle) { - $objWriter->startElement('c:explosion'); - $objWriter->writeAttribute('val', '25'); - $objWriter->endElement(); - } + $plotStyle = $plotGroup->getPlotStyle(); + if (is_numeric($plotStyle)) { + $objWriter->startElement('c:explosion'); + $objWriter->writeAttribute('val', $plotStyle); + $objWriter->endElement(); } } diff --git a/tests/PhpSpreadsheetTests/Chart/Issue2506Test.php b/tests/PhpSpreadsheetTests/Chart/Issue2506Test.php new file mode 100644 index 00000000..a2a14c9d --- /dev/null +++ b/tests/PhpSpreadsheetTests/Chart/Issue2506Test.php @@ -0,0 +1,73 @@ +setIncludeCharts(true); + } + + public function writeCharts(XlsxWriter $writer): void + { + $writer->setIncludeCharts(true); + } + + public function testDataSeriesValues(): void + { + $reader = new XlsxReader(); + self::readCharts($reader); + $spreadsheet = $reader->load(self::DIRECTORY . 'issue.2506.xlsx'); + $worksheet = $spreadsheet->getActiveSheet(); + $charts = $worksheet->getChartCollection(); + self::assertCount(4, $charts); + $originalChart1 = $charts[0]; + self::assertNotNull($originalChart1); + $originalPlotArea1 = $originalChart1->getPlotArea(); + self::assertNotNull($originalPlotArea1); + $originalPlotSeries1 = $originalPlotArea1->getPlotGroup(); + self::assertCount(1, $originalPlotSeries1); + self::assertSame('0', $originalPlotSeries1[0]->getPlotStyle()); + $originalChart2 = $charts[1]; + self::assertNotNull($originalChart2); + $originalPlotArea2 = $originalChart2->getPlotArea(); + self::assertNotNull($originalPlotArea2); + $originalPlotSeries2 = $originalPlotArea2->getPlotGroup(); + self::assertCount(1, $originalPlotSeries2); + self::assertSame('5', $originalPlotSeries2[0]->getPlotStyle()); + + /** @var callable */ + $callableReader = [$this, 'readCharts']; + /** @var callable */ + $callableWriter = [$this, 'writeCharts']; + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx', $callableReader, $callableWriter); + $spreadsheet->disconnectWorksheets(); + + $sheet = $reloadedSpreadsheet->getActiveSheet(); + $charts2 = $sheet->getChartCollection(); + self::assertCount(4, $charts2); + $chart1 = $charts[0]; + self::assertNotNull($chart1); + $plotArea1 = $chart1->getPlotArea(); + self::assertNotNull($plotArea1); + $plotSeries1 = $plotArea1->getPlotGroup(); + self::assertCount(1, $plotSeries1); + self::assertSame('0', $plotSeries1[0]->getPlotStyle()); + $chart2 = $charts[1]; + self::assertNotNull($chart2); + $plotArea2 = $chart2->getPlotArea(); + self::assertNotNull($plotArea2); + $plotSeries2 = $plotArea2->getPlotGroup(); + self::assertCount(1, $plotSeries2); + self::assertSame('5', $plotSeries2[0]->getPlotStyle()); + + $reloadedSpreadsheet->disconnectWorksheets(); + } +} diff --git a/tests/data/Reader/XLSX/issue.2506.xlsx b/tests/data/Reader/XLSX/issue.2506.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6b2c7fbcc99e967b846a8e78aba5c0327cf0d8c7 GIT binary patch literal 22547 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 L0AL9TPXYV~Pyzv~ literal 0 HcmV?d00001