From 44f6abdb8b81043b7c9f839af198cedcd30fbd8e Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Tue, 6 Jul 2021 09:08:13 +0200 Subject: [PATCH] #634 : Migrated use of PHPExcel to PhpSpreadsheet --- composer.json | 3 +- docs/changes/1.0.0.md | 1 + phpstan.neon.dist | 3 - samples/Sample_05_Chart_with_PHPExcel.php | 122 ------------------ .../Sample_05_Chart_with_PhpSpreadsheet.php | 119 +++++++++++++++++ src/PhpPresentation/Shape/Chart.php | 38 +++--- .../Writer/PowerPoint2007/PptCharts.php | 64 +++++---- .../Writer/PowerPoint2007/PptChartsTest.php | 74 +++++++++++ 8 files changed, 253 insertions(+), 171 deletions(-) delete mode 100644 samples/Sample_05_Chart_with_PHPExcel.php create mode 100644 samples/Sample_05_Chart_with_PhpSpreadsheet.php diff --git a/composer.json b/composer.json index 0b0fe88f3..2f1e0f3a8 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,8 @@ "php": "^7.1|^8.0", "ext-xml": "*", "ext-zip": "*", - "phpoffice/common": "0.2.*" + "phpoffice/common": "0.2.*", + "phpoffice/phpspreadsheet": "^1.9.0" }, "require-dev": { "phpunit/phpunit": ">=7.0", diff --git a/docs/changes/1.0.0.md b/docs/changes/1.0.0.md index 560145d5c..41a791172 100644 --- a/docs/changes/1.0.0.md +++ b/docs/changes/1.0.0.md @@ -9,6 +9,7 @@ - PHP 7.1 is now supported - @Progi1984 GH-355 - Added support PHP 7.4 to 8.0 & Removed support PHP < 7.1 - @Progi1984 GH-636 - Removed deprecated methods/classes - @Progi1984 GH-650 +- Migrated use of PHPExcel to PhpSpreadsheet - @Progi1984 GH-652 - PhpOffice\PhpPresentation\Style\Color : Define only the transparency - @Progi1984 GH-370 - PowerPoint2007 Reader : Background Color based on SchemeColor - @Progi1984 GH-397 - PowerPoint2007 Reader : Support for hyperlinks under pictures - @ulziibuyan diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 907a6c7f9..0ab30292c 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -7,9 +7,6 @@ parameters: - tests reportUnmatchedIgnoredErrors: false ignoreErrors: - ## Relative to PHPExcel - - '#^Call to static method createWriter\(\) on an unknown class PHPExcel_IOFactory\.#' - - '#^Call to static method stringFromColumnIndex\(\) on an unknown class PHPExcel_Cell\.#' ## Relative to Common - '#^Parameter \#1 \$pValue of static method PhpOffice\\Common\\Drawing\:\:angleToDegrees\(\) expects int, string given\.#' - '#^Parameter \#1 \$pValue of static method PhpOffice\\Common\\Drawing\:\:centimetersToPixels\(\) expects int, string given\.#' diff --git a/samples/Sample_05_Chart_with_PHPExcel.php b/samples/Sample_05_Chart_with_PHPExcel.php deleted file mode 100644 index cae9b4637..000000000 --- a/samples/Sample_05_Chart_with_PHPExcel.php +++ /dev/null @@ -1,122 +0,0 @@ -PHPExcel has not been loaded. Include PHPExcel.php in your script, e.g. require_once \'PHPExcel.php\'.'; -} else { - // Create new PHPPresentation object - echo date('H:i:s') . ' Create new PHPPresentation object' . EOL; - $objPHPPresentation = new PhpPresentation(); - - // Set properties - echo date('H:i:s') . ' Set properties' . EOL; - $objPHPPresentation->getDocumentProperties()->setCreator('PHPOffice') - ->setLastModifiedBy('PHPPresentation Team') - ->setTitle('Sample 08 Title') - ->setSubject('Sample 08 Subject') - ->setDescription('Sample 08 Description') - ->setKeywords('office 2007 openxml libreoffice odt php') - ->setCategory('Sample Category'); - - // Remove first slide - echo date('H:i:s') . ' Remove first slide' . EOL; - $objPHPPresentation->removeSlideByIndex(0); - - // Create templated slide - echo date('H:i:s') . ' Create templated slide' . EOL; - $currentSlide = createTemplatedSlide($objPHPPresentation); // local function - - // Generate sample data for first chart - echo date('H:i:s') . ' Generate sample data for first chart' . EOL; - $series1Data = ['Jan' => 133, 'Feb' => 99, 'Mar' => 191, 'Apr' => 205, 'May' => 167, 'Jun' => 201, 'Jul' => 240, 'Aug' => 226, 'Sep' => 255, 'Oct' => 264, 'Nov' => 283, 'Dec' => 293]; - $series2Data = ['Jan' => 266, 'Feb' => 198, 'Mar' => 271, 'Apr' => 305, 'May' => 267, 'Jun' => 301, 'Jul' => 340, 'Aug' => 326, 'Sep' => 344, 'Oct' => 364, 'Nov' => 383, 'Dec' => 379]; - - // Create a bar chart (that should be inserted in a shape) - echo date('H:i:s') . ' Create a bar chart (that should be inserted in a chart shape)' . EOL; - $bar3DChart = new Bar3D(); - $bar3DChart->addSeries(new Series('2009', $series1Data)); - $bar3DChart->addSeries(new Series('2010', $series2Data)); - - // Create a shape (chart) - echo date('H:i:s') . ' Create a shape (chart)' . EOL; - $shape = $currentSlide->createChartShape(); - $shape->setName('PHPPresentation Monthly Downloads') - ->setResizeProportional(false) - ->setHeight(550) - ->setWidth(700) - ->setOffsetX(120) - ->setOffsetY(80) - ->setIncludeSpreadsheet(true); - $shape->getShadow()->setVisible(true) - ->setDirection(45) - ->setDistance(10); - $shape->getFill()->setFillType(Fill::FILL_GRADIENT_LINEAR) - ->setStartColor(new Color('FFCCCCCC')) - ->setEndColor(new Color('FFFFFFFF')) - ->setRotation(270); - $shape->getBorder()->setLineStyle(Border::LINE_SINGLE); - $shape->getTitle()->setText('PHPPresentation Monthly Downloads'); - $shape->getTitle()->getFont()->setItalic(true); - $shape->getPlotArea()->getAxisX()->setTitle('Month'); - $shape->getPlotArea()->getAxisY()->setTitle('Downloads'); - $shape->getPlotArea()->setType($bar3DChart); - $shape->getView3D()->setRightAngleAxes(true); - $shape->getView3D()->setRotationX(20); - $shape->getView3D()->setRotationY(20); - $shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); - $shape->getLegend()->getFont()->setItalic(true); - - // Create templated slide - echo date('H:i:s') . ' Create templated slide' . EOL; - $currentSlide = createTemplatedSlide($objPHPPresentation); // local function - - // Generate sample data for second chart - echo date('H:i:s') . ' Generate sample data for second chart' . EOL; - $seriesData = ['Monday' => 12, 'Tuesday' => 15, 'Wednesday' => 13, 'Thursday' => 17, 'Friday' => 14, 'Saturday' => 9, 'Sunday' => 7]; - - // Create a pie chart (that should be inserted in a shape) - echo date('H:i:s') . ' Create a pie chart (that should be inserted in a chart shape)' . EOL; - $pie3DChart = new Pie3D(); - $pie3DChart->addSeries(new Series('Downloads', $seriesData)); - - // Create a shape (chart) - echo date('H:i:s') . ' Create a shape (chart)' . EOL; - $shape = $currentSlide->createChartShape(); - $shape->setName('PHPPresentation Daily Downloads') - ->setResizeProportional(false) - ->setHeight(550) - ->setWidth(700) - ->setOffsetX(120) - ->setOffsetY(80) - ->setIncludeSpreadsheet(true); - $shape->getShadow()->setVisible(true) - ->setDirection(45) - ->setDistance(10); - $shape->getFill()->setFillType(Fill::FILL_GRADIENT_LINEAR) - ->setStartColor(new Color('FFCCCCCC')) - ->setEndColor(new Color('FFFFFFFF')) - ->setRotation(270); - $shape->getBorder()->setLineStyle(Border::LINE_SINGLE); - $shape->getTitle()->setText('PHPPresentation Daily Downloads'); - $shape->getTitle()->getFont()->setItalic(true); - $shape->getPlotArea()->setType($pie3DChart); - $shape->getView3D()->setRotationX(30); - $shape->getView3D()->setPerspective(30); - $shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); - $shape->getLegend()->getFont()->setItalic(true); - - // Save file - echo write($objPHPPresentation, basename(__FILE__, '.php'), $writers); -} -if (!CLI) { - include_once 'Sample_Footer.php'; -} diff --git a/samples/Sample_05_Chart_with_PhpSpreadsheet.php b/samples/Sample_05_Chart_with_PhpSpreadsheet.php new file mode 100644 index 000000000..bdbf79e75 --- /dev/null +++ b/samples/Sample_05_Chart_with_PhpSpreadsheet.php @@ -0,0 +1,119 @@ +getDocumentProperties()->setCreator('PHPOffice') + ->setLastModifiedBy('PHPPresentation Team') + ->setTitle('Sample 08 Title') + ->setSubject('Sample 08 Subject') + ->setDescription('Sample 08 Description') + ->setKeywords('office 2007 openxml libreoffice odt php') + ->setCategory('Sample Category'); + +// Remove first slide +echo date('H:i:s') . ' Remove first slide' . EOL; +$objPHPPresentation->removeSlideByIndex(0); + +// Create templated slide +echo date('H:i:s') . ' Create templated slide' . EOL; +$currentSlide = createTemplatedSlide($objPHPPresentation); // local function + +// Generate sample data for first chart +echo date('H:i:s') . ' Generate sample data for first chart' . EOL; +$series1Data = ['Jan' => 133, 'Feb' => 99, 'Mar' => 191, 'Apr' => 205, 'May' => 167, 'Jun' => 201, 'Jul' => 240, 'Aug' => 226, 'Sep' => 255, 'Oct' => 264, 'Nov' => 283, 'Dec' => 293]; +$series2Data = ['Jan' => 266, 'Feb' => 198, 'Mar' => 271, 'Apr' => 305, 'May' => 267, 'Jun' => 301, 'Jul' => 340, 'Aug' => 326, 'Sep' => 344, 'Oct' => 364, 'Nov' => 383, 'Dec' => 379]; + +// Create a bar chart (that should be inserted in a shape) +echo date('H:i:s') . ' Create a bar chart (that should be inserted in a chart shape)' . EOL; +$bar3DChart = new Bar3D(); +$bar3DChart->addSeries(new Series('2009', $series1Data)); +$bar3DChart->addSeries(new Series('2010', $series2Data)); + +// Create a shape (chart) +echo date('H:i:s') . ' Create a shape (chart)' . EOL; +$shape = $currentSlide->createChartShape(); +$shape->setName('PHPPresentation Monthly Downloads') + ->setResizeProportional(false) + ->setHeight(550) + ->setWidth(700) + ->setOffsetX(120) + ->setOffsetY(80) + ->setIncludeSpreadsheet(true); +$shape->getShadow()->setVisible(true) + ->setDirection(45) + ->setDistance(10); +$shape->getFill()->setFillType(Fill::FILL_GRADIENT_LINEAR) + ->setStartColor(new Color('FFCCCCCC')) + ->setEndColor(new Color('FFFFFFFF')) + ->setRotation(270); +$shape->getBorder()->setLineStyle(Border::LINE_SINGLE); +$shape->getTitle()->setText('PHPPresentation Monthly Downloads'); +$shape->getTitle()->getFont()->setItalic(true); +$shape->getPlotArea()->getAxisX()->setTitle('Month'); +$shape->getPlotArea()->getAxisY()->setTitle('Downloads'); +$shape->getPlotArea()->setType($bar3DChart); +$shape->getView3D()->setRightAngleAxes(true); +$shape->getView3D()->setRotationX(20); +$shape->getView3D()->setRotationY(20); +$shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); +$shape->getLegend()->getFont()->setItalic(true); + +// Create templated slide +echo date('H:i:s') . ' Create templated slide' . EOL; +$currentSlide = createTemplatedSlide($objPHPPresentation); // local function + +// Generate sample data for second chart +echo date('H:i:s') . ' Generate sample data for second chart' . EOL; +$seriesData = ['Monday' => 12, 'Tuesday' => 15, 'Wednesday' => 13, 'Thursday' => 17, 'Friday' => 14, 'Saturday' => 9, 'Sunday' => 7]; + +// Create a pie chart (that should be inserted in a shape) +echo date('H:i:s') . ' Create a pie chart (that should be inserted in a chart shape)' . EOL; +$pie3DChart = new Pie3D(); +$pie3DChart->addSeries(new Series('Downloads', $seriesData)); + +// Create a shape (chart) +echo date('H:i:s') . ' Create a shape (chart)' . EOL; +$shape = $currentSlide->createChartShape(); +$shape->setName('PHPPresentation Daily Downloads') + ->setResizeProportional(false) + ->setHeight(550) + ->setWidth(700) + ->setOffsetX(120) + ->setOffsetY(80) + ->setIncludeSpreadsheet(true); +$shape->getShadow()->setVisible(true) + ->setDirection(45) + ->setDistance(10); +$shape->getFill()->setFillType(Fill::FILL_GRADIENT_LINEAR) + ->setStartColor(new Color('FFCCCCCC')) + ->setEndColor(new Color('FFFFFFFF')) + ->setRotation(270); +$shape->getBorder()->setLineStyle(Border::LINE_SINGLE); +$shape->getTitle()->setText('PHPPresentation Daily Downloads'); +$shape->getTitle()->getFont()->setItalic(true); +$shape->getPlotArea()->setType($pie3DChart); +$shape->getView3D()->setRotationX(30); +$shape->getView3D()->setPerspective(30); +$shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); +$shape->getLegend()->getFont()->setItalic(true); + +// Save file +echo write($objPHPPresentation, basename(__FILE__, '.php'), $writers); + +if (!CLI) { + include_once 'Sample_Footer.php'; +} diff --git a/src/PhpPresentation/Shape/Chart.php b/src/PhpPresentation/Shape/Chart.php index fd49ecb07..d840ccb3b 100644 --- a/src/PhpPresentation/Shape/Chart.php +++ b/src/PhpPresentation/Shape/Chart.php @@ -32,33 +32,33 @@ class Chart extends AbstractGraphic implements ComparableInterface /** * Title. * - * @var \PhpOffice\PhpPresentation\Shape\Chart\Title + * @var Title */ private $title; /** * Legend. * - * @var \PhpOffice\PhpPresentation\Shape\Chart\Legend + * @var Legend */ private $legend; /** * Plot area. * - * @var \PhpOffice\PhpPresentation\Shape\Chart\PlotArea + * @var PlotArea */ private $plotArea; /** * View 3D. * - * @var \PhpOffice\PhpPresentation\Shape\Chart\View3D + * @var View3D */ private $view3D; /** - * Include spreadsheet for editing data? Requires PHPExcel in the same folder as PhpPresentation. + * Is the spreadsheet included for editing data ? * * @var bool */ @@ -92,9 +92,9 @@ public function __clone() /** * Get Title. * - * @return \PhpOffice\PhpPresentation\Shape\Chart\Title + * @return Title */ - public function getTitle() + public function getTitle(): Title { return $this->title; } @@ -102,9 +102,9 @@ public function getTitle() /** * Get Legend. * - * @return \PhpOffice\PhpPresentation\Shape\Chart\Legend + * @return Legend */ - public function getLegend() + public function getLegend(): Legend { return $this->legend; } @@ -112,9 +112,9 @@ public function getLegend() /** * Get PlotArea. * - * @return \PhpOffice\PhpPresentation\Shape\Chart\PlotArea + * @return PlotArea */ - public function getPlotArea() + public function getPlotArea(): PlotArea { return $this->plotArea; } @@ -122,31 +122,31 @@ public function getPlotArea() /** * Get View3D. * - * @return \PhpOffice\PhpPresentation\Shape\Chart\View3D + * @return View3D */ - public function getView3D() + public function getView3D(): View3D { return $this->view3D; } /** - * Include spreadsheet for editing data? Requires PHPExcel in the same folder as PhpPresentation. + * Is the spreadsheet included for editing data ? * * @return bool */ - public function hasIncludedSpreadsheet() + public function hasIncludedSpreadsheet(): bool { return $this->includeSpreadsheet; } /** - * Include spreadsheet for editing data? Requires PHPExcel in the same folder as PhpPresentation. + * Is the spreadsheet included for editing data ? * * @param bool $value * - * @return \PhpOffice\PhpPresentation\Shape\Chart + * @return self */ - public function setIncludeSpreadsheet($value = false) + public function setIncludeSpreadsheet(bool $value = false): self { $this->includeSpreadsheet = $value; @@ -158,7 +158,7 @@ public function setIncludeSpreadsheet($value = false) * * @return string */ - public function getIndexedFilename() + public function getIndexedFilename(): string { return 'chart' . $this->getImageIndex() . '.xml'; } diff --git a/src/PhpPresentation/Writer/PowerPoint2007/PptCharts.php b/src/PhpPresentation/Writer/PowerPoint2007/PptCharts.php index f895b36b1..3da4c7385 100644 --- a/src/PhpPresentation/Writer/PowerPoint2007/PptCharts.php +++ b/src/PhpPresentation/Writer/PowerPoint2007/PptCharts.php @@ -21,6 +21,9 @@ use PhpOffice\PhpPresentation\Shape\Chart\Type\Scatter; use PhpOffice\PhpPresentation\Style\Border; use PhpOffice\PhpPresentation\Style\Fill; +use PhpOffice\PhpSpreadsheet\Cell\Coordinate; +use PhpOffice\PhpSpreadsheet\IOFactory; +use PhpOffice\PhpSpreadsheet\Spreadsheet; class PptCharts extends AbstractDecoratorWriter { @@ -36,7 +39,7 @@ public function render(): ZipInterface if ($shape->hasIncludedSpreadsheet()) { $this->getZip()->addFromString('ppt/charts/_rels/' . $shape->getIndexedFilename() . '.rels', $this->writeChartRelationships($shape)); - $pFilename = tempnam(sys_get_temp_dir(), 'PHPExcel'); + $pFilename = tempnam(sys_get_temp_dir(), 'PhpSpreadsheet'); $this->getZip()->addFromString('ppt/embeddings/' . $shape->getIndexedFilename() . '.xlsx', $this->writeSpreadsheet($this->getPresentation(), $shape, $pFilename . '.xlsx')); // remove temp file @@ -212,23 +215,23 @@ public function writeSpreadsheet(PhpPresentation $presentation, Chart $chart, st throw new \Exception('No spreadsheet output is required for the given chart.'); } - // Verify PHPExcel - if (!class_exists('PHPExcel')) { - throw new \Exception('PHPExcel has not been loaded. Include PHPExcel.php in your script, e.g. require_once \'PHPExcel.php\'.'); - } - // Create new spreadsheet - $workbook = new \PHPExcel(); + $spreadsheet = new Spreadsheet(); // Set properties $title = $chart->getTitle()->getText(); if (0 == strlen($title)) { $title = 'Chart'; } - $workbook->getProperties()->setCreator($presentation->getDocumentProperties()->getCreator())->setLastModifiedBy($presentation->getDocumentProperties()->getLastModifiedBy())->setTitle($title); + $spreadsheet->getProperties() + ->setCreator( + $presentation->getDocumentProperties()->getCreator())->setLastModifiedBy( + $presentation->getDocumentProperties()->getLastModifiedBy() + ) + ->setTitle($title); // Add chart data - $sheet = $workbook->setActiveSheetIndex(0); + $sheet = $spreadsheet->setActiveSheetIndex(0); $sheet->setTitle('Sheet1'); // Write series @@ -255,7 +258,7 @@ public function writeSpreadsheet(PhpPresentation $presentation, Chart $chart, st } // Save to string - $writer = \PHPExcel_IOFactory::createWriter($workbook, 'Excel2007'); + $writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); $writer->save($tempName); // Load file in memory @@ -294,18 +297,27 @@ protected function writeSingleValueOrReference(XMLWriter $objWriter, bool $isRef } // Reference and cache + // c:strRef $objWriter->startElement('c:strRef'); + // c:strRef/c:f $objWriter->writeElement('c:f', $reference); + // c:strRef/c:strCache $objWriter->startElement('c:strCache'); + // c:strRef/c:strCache/c:ptCount $objWriter->startElement('c:ptCount'); $objWriter->writeAttribute('val', '1'); $objWriter->endElement(); + // c:strRef/c:strCache/c:pt $objWriter->startElement('c:pt'); $objWriter->writeAttribute('idx', '0'); + // c:strRef/c:strCache/c:pt/c:v $objWriter->writeElement('c:v', $value); + // c:strRef/c:strCache/c:pt $objWriter->endElement(); + // c:strRef/c:strCache $objWriter->endElement(); + // c:strRef $objWriter->endElement(); } @@ -706,7 +718,7 @@ protected function writeTypeArea(XMLWriter $objWriter, Area $subject, bool $incl // c:ser > c:tx $objWriter->startElement('c:tx'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); $this->writeSingleValueOrReference($objWriter, $includeSheet, $series->getTitle(), $coords); $objWriter->endElement(); @@ -751,7 +763,7 @@ protected function writeTypeArea(XMLWriter $objWriter, Area $subject, bool $incl // c:val $objWriter->startElement('c:val'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisYData, $coords); $objWriter->endElement(); @@ -814,7 +826,7 @@ protected function writeTypeBar(XMLWriter $objWriter, Bar $subject, bool $includ // c:tx $objWriter->startElement('c:tx'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); $this->writeSingleValueOrReference($objWriter, $includeSheet, $series->getTitle(), $coords); $objWriter->endElement(); @@ -950,7 +962,7 @@ protected function writeTypeBar(XMLWriter $objWriter, Bar $subject, bool $includ // c:val $objWriter->startElement('c:val'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisYData, $coords); $objWriter->endElement(); @@ -1032,7 +1044,7 @@ protected function writeTypeBar3D(XMLWriter $objWriter, Bar3D $subject, bool $in // c:tx $objWriter->startElement('c:tx'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); $this->writeSingleValueOrReference($objWriter, $includeSheet, $series->getTitle(), $coords); $objWriter->endElement(); @@ -1153,7 +1165,7 @@ protected function writeTypeBar3D(XMLWriter $objWriter, Bar3D $subject, bool $in // c:val $objWriter->startElement('c:val'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisYData, $coords); $objWriter->endElement(); @@ -1220,7 +1232,7 @@ protected function writeTypeDoughnut(XMLWriter $objWriter, Doughnut $subject, bo // c:tx $objWriter->startElement('c:tx'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); $this->writeSingleValueOrReference($objWriter, $includeSheet, $series->getTitle(), $coords); $objWriter->endElement(); @@ -1252,7 +1264,7 @@ protected function writeTypeDoughnut(XMLWriter $objWriter, Doughnut $subject, bo // c:val $objWriter->startElement('c:val'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisYData, $coords); $objWriter->endElement(); @@ -1379,7 +1391,7 @@ protected function writeTypePie(XMLWriter $objWriter, Pie $subject, bool $includ // c:tx $objWriter->startElement('c:tx'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); $this->writeSingleValueOrReference($objWriter, $includeSheet, $series->getTitle(), $coords); $objWriter->endElement(); @@ -1497,7 +1509,7 @@ protected function writeTypePie(XMLWriter $objWriter, Pie $subject, bool $includ // c:val $objWriter->startElement('c:val'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisYData, $coords); $objWriter->endElement(); @@ -1544,7 +1556,7 @@ protected function writeTypePie3D(XMLWriter $objWriter, Pie3D $subject, bool $in // c:tx $objWriter->startElement('c:tx'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); $this->writeSingleValueOrReference($objWriter, $includeSheet, $series->getTitle(), $coords); $objWriter->endElement(); @@ -1656,7 +1668,7 @@ protected function writeTypePie3D(XMLWriter $objWriter, Pie3D $subject, bool $in // c:val $objWriter->startElement('c:val'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisYData, $coords); $objWriter->endElement(); @@ -1703,7 +1715,7 @@ protected function writeTypeLine(XMLWriter $objWriter, Line $subject, bool $incl // c:tx $objWriter->startElement('c:tx'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); $this->writeSingleValueOrReference($objWriter, $includeSheet, $series->getTitle(), $coords); $objWriter->endElement(); @@ -1805,7 +1817,7 @@ protected function writeTypeLine(XMLWriter $objWriter, Line $subject, bool $incl // c:val $objWriter->startElement('c:val'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisYData, $coords); $objWriter->endElement(); @@ -1878,7 +1890,7 @@ protected function writeTypeScatter(XMLWriter $objWriter, Scatter $subject, bool // c:tx $objWriter->startElement('c:tx'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); $this->writeSingleValueOrReference($objWriter, $includeSheet, $series->getTitle(), $coords); $objWriter->endElement(); @@ -1989,7 +2001,7 @@ protected function writeTypeScatter(XMLWriter $objWriter, Scatter $subject, bool // c:yVal $objWriter->startElement('c:yVal'); - $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); + $coords = ($includeSheet ? 'Sheet1!$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . Coordinate::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisYData, $coords); $objWriter->endElement(); diff --git a/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptChartsTest.php b/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptChartsTest.php index 510e7ffaf..370cf2419 100644 --- a/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptChartsTest.php +++ b/tests/PhpPresentation/Tests/Writer/PowerPoint2007/PptChartsTest.php @@ -38,6 +38,80 @@ class PptChartsTest extends PhpPresentationTestCase 'E' => '2', ]; + public function testChartIncludeSpreadsheet(): void + { + $oSlide = $this->oPresentation->getActiveSlide(); + $oShape = $oSlide->createChartShape(); + $oShape->setIncludeSpreadsheet(true); + $oLine = new Line(); + $oSeries = new Series('Downloads', $this->seriesData); + $oLine->addSeries($oSeries); + $oShape->getPlotArea()->setType($oLine); + + $this->assertTrue($oShape->hasIncludedSpreadsheet()); + + $this->assertZipFileExists('ppt/charts/' . $oShape->getIndexedFilename()); + $this->assertZipFileExists('ppt/embeddings/' . $oShape->getIndexedFilename() . '.xlsx'); + + $this->assertZipFileExists('ppt/charts/_rels/' . $oShape->getIndexedFilename() . '.rels'); + $element = '/Relationships/Relationship[@Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/package"]'; + $this->assertZipXmlElementExists('ppt/charts/_rels/' . $oShape->getIndexedFilename() . '.rels', $element); + + $element = '/p:sld/p:cSld/p:spTree/p:graphicFrame/a:graphic/a:graphicData'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $element = '/c:chartSpace/c:chart/c:plotArea/c:lineChart'; + $this->assertZipXmlElementExists('ppt/charts/' . $oShape->getIndexedFilename(), $element); + $element = '/c:chartSpace/c:chart/c:plotArea/c:lineChart/c:ser'; + $this->assertZipXmlElementExists('ppt/charts/' . $oShape->getIndexedFilename(), $element); + $element = '/c:chartSpace/c:chart/c:plotArea/c:lineChart/c:ser/c:tx/c:v'; + $this->assertZipXmlElementNotExists('ppt/charts/' . $oShape->getIndexedFilename(), $element); + $element = '/c:chartSpace/c:chart/c:plotArea/c:lineChart/c:ser/c:tx/c:strRef'; + $this->assertZipXmlElementExists('ppt/charts/' . $oShape->getIndexedFilename(), $element); + $element = '/c:chartSpace/c:chart/c:plotArea/c:lineChart/c:ser/c:tx/c:strRef/c:f'; + $this->assertZipXmlElementExists('ppt/charts/' . $oShape->getIndexedFilename(), $element); + $this->assertZipXmlElementEquals('ppt/charts/' . $oShape->getIndexedFilename(), $element, 'Sheet1!$A$1'); + $element = '/c:chartSpace/c:chart/c:plotArea/c:lineChart/c:ser/c:tx/c:strRef/c:strCache'; + $this->assertZipXmlElementExists('ppt/charts/' . $oShape->getIndexedFilename(), $element); + $element = '/c:chartSpace/c:chart/c:plotArea/c:lineChart/c:ser/c:tx/c:strRef/c:strCache/c:pt'; + $this->assertZipXmlElementExists('ppt/charts/' . $oShape->getIndexedFilename(), $element); + $element = '/c:chartSpace/c:chart/c:plotArea/c:lineChart/c:ser/c:tx/c:strRef/c:strCache/c:pt/c:v'; + $this->assertZipXmlElementExists('ppt/charts/' . $oShape->getIndexedFilename(), $element); + $this->assertZipXmlElementEquals('ppt/charts/' . $oShape->getIndexedFilename(), $element, 'Downloads'); + $element = '/c:chartSpace/c:externalData'; + $this->assertZipXmlElementExists('ppt/charts/' . $oShape->getIndexedFilename(), $element); + $this->assertZipXmlAttributeExists('ppt/charts/' . $oShape->getIndexedFilename(), $element, 'r:id'); + $this->assertZipXmlAttributeEquals('ppt/charts/' . $oShape->getIndexedFilename(), $element, 'r:id', 'rId1'); + $element = '/c:chartSpace/c:externalData/c:autoUpdate'; + $this->assertZipXmlElementExists('ppt/charts/' . $oShape->getIndexedFilename(), $element); + $this->assertZipXmlAttributeExists('ppt/charts/' . $oShape->getIndexedFilename(), $element, 'val'); + $this->assertZipXmlAttributeEquals('ppt/charts/' . $oShape->getIndexedFilename(), $element, 'val', '0'); + + $this->assertIsSchemaECMA376Valid(); + + $this->resetPresentationFile(); + $oShape->setIncludeSpreadsheet(false); + + $this->assertFalse($oShape->hasIncludedSpreadsheet()); + + $this->assertZipFileExists('ppt/charts/' . $oShape->getIndexedFilename()); + $this->assertZipFileNotExists('ppt/charts/_rels/' . $oShape->getIndexedFilename() . '.rels'); + $this->assertZipFileNotExists('ppt/embeddings/' . $oShape->getIndexedFilename() . '.xlsx'); + + $element = '/p:sld/p:cSld/p:spTree/p:graphicFrame/a:graphic/a:graphicData'; + $this->assertZipXmlElementExists('ppt/slides/slide1.xml', $element); + $element = '/c:chartSpace/c:chart/c:plotArea/c:lineChart'; + $this->assertZipXmlElementExists('ppt/charts/' . $oShape->getIndexedFilename(), $element); + $element = '/c:chartSpace/c:chart/c:plotArea/c:lineChart/c:ser'; + $this->assertZipXmlElementExists('ppt/charts/' . $oShape->getIndexedFilename(), $element); + $element = '/c:chartSpace/c:chart/c:plotArea/c:lineChart/c:ser/c:tx/c:v'; + $this->assertZipXmlElementExists('ppt/charts/' . $oShape->getIndexedFilename(), $element); + $this->assertZipXmlElementEquals('ppt/charts/' . $oShape->getIndexedFilename(), $element, 'Downloads'); + $element = '/c:chartSpace/c:externalData'; + $this->assertZipXmlElementNotExists('ppt/charts/' . $oShape->getIndexedFilename(), $element); + + $this->assertIsSchemaECMA376Valid(); + } + public function testPlotAreaBadType(): void { $this->expectException(Exception::class);