-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Don't corrupt file when using chart with fill color
When the fill color property of `DataSeries.plotLabel` using a DataSeriesValues on a line chart is set, the XLSX file written is corrupted, and MSExcel2016 removes the drawing1.xml if forced open. This problem was already documented on issue #589 along with a possible solution. So all credits go to @madrussa. I am only submitting the PR. Fixes #589 Closes #1930
- Loading branch information
1 parent
b674042
commit 0c93bba
Showing
2 changed files
with
172 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
<?php | ||
|
||
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx; | ||
|
||
use DOMDocument; | ||
use DOMNode; | ||
use PhpOffice\PhpSpreadsheet\Chart\Chart; | ||
use PhpOffice\PhpSpreadsheet\Chart\DataSeries; | ||
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues; | ||
use PhpOffice\PhpSpreadsheet\Chart\PlotArea; | ||
use PhpOffice\PhpSpreadsheet\Shared\File; | ||
use PhpOffice\PhpSpreadsheet\Spreadsheet; | ||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as Writer; | ||
use PHPUnit\Framework\TestCase; | ||
use ZipArchive; | ||
|
||
class Issue589Test extends TestCase | ||
{ | ||
/** | ||
* Build a testable chart in a spreadsheet and set fill color for series. | ||
* | ||
* @param string|string[] $color HEX color or array with HEX colors | ||
*/ | ||
private function buildChartSpreadsheet($color): Spreadsheet | ||
{ | ||
// Problem occurs when setting plot line color | ||
// The output chart xml file is missing the a:ln tag | ||
$spreadsheet = new Spreadsheet(); | ||
$worksheet = $spreadsheet->getActiveSheet(); | ||
$worksheet->fromArray( | ||
[ | ||
[2010], | ||
[12], | ||
[56], | ||
] | ||
); | ||
|
||
$dataSeriesLabels = [ | ||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$1', null, 1), | ||
]; | ||
$dataSeriesLabels[0]->setFillColor($color); | ||
$dataSeriesValues = [ | ||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$A$2:$A$3', null, 2), | ||
]; | ||
|
||
// Build the dataseries | ||
$series = new DataSeries( | ||
DataSeries::TYPE_LINECHART, | ||
DataSeries::GROUPING_STACKED, | ||
range(0, count($dataSeriesValues) - 1), | ||
$dataSeriesLabels, | ||
[], | ||
$dataSeriesValues | ||
); | ||
|
||
// Set the series in the plot area | ||
$plotArea = new PlotArea(null, [$series]); | ||
|
||
// Create the chart | ||
$chart = new Chart( | ||
'chart1', | ||
null, | ||
null, | ||
$plotArea | ||
); | ||
|
||
// Add the chart to the worksheet | ||
$worksheet->addChart($chart); | ||
|
||
return $spreadsheet; | ||
} | ||
|
||
public function testLineChartFill(): void | ||
{ | ||
$outputFilename = File::temporaryFilename(); | ||
$spreadsheet = $this->buildChartSpreadsheet('98B954'); | ||
$writer = new Writer($spreadsheet); | ||
$writer->setIncludeCharts(true); | ||
$writer->save($outputFilename); | ||
|
||
$zip = new ZipArchive(); | ||
$zip->open($outputFilename); | ||
$resultChart1Raw = $zip->getFromName('xl/charts/chart1.xml'); | ||
$zip->close(); | ||
unlink($outputFilename); | ||
|
||
$dom = new DOMDocument(); | ||
if ($resultChart1Raw === false) { | ||
self::fail('Unable to open the chart file'); | ||
} else { | ||
$loaded = $dom->loadXML($resultChart1Raw); | ||
if (!$loaded) { | ||
self::fail('Unable to load the chart xml'); | ||
} else { | ||
$series = $dom->getElementsByTagName('ser'); | ||
$firstSeries = $series->item(0); | ||
if ($firstSeries === null) { | ||
self::fail('The chart XML does not contain a \'ser\' tag!'); | ||
} else { | ||
$spPrList = $firstSeries->getElementsByTagName('spPr'); | ||
|
||
// expect to see only one element with name 'c:spPr' | ||
self::assertCount(1, $spPrList); | ||
|
||
/** @var DOMNode $node */ | ||
$node = $spPrList->item(0); // Get the spPr element | ||
$actualXml = $dom->saveXML($node); | ||
if ($actualXml === false) { | ||
self::fail('Failure saving the spPr element as xml string!'); | ||
} else { | ||
self::assertXmlStringEqualsXmlString('<c:spPr><a:ln w="12700"><a:solidFill><a:srgbClr val="98B954"/></a:solidFill></a:ln></c:spPr>', $actualXml); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
public function testLineChartFillIgnoresColorArray(): void | ||
{ | ||
$outputFilename = File::temporaryFilename(); | ||
$spreadsheet = $this->buildChartSpreadsheet(['98B954']); | ||
$writer = new Writer($spreadsheet); | ||
$writer->setIncludeCharts(true); | ||
$writer->save($outputFilename); | ||
|
||
$zip = new ZipArchive(); | ||
$zip->open($outputFilename); | ||
$resultChart1Raw = $zip->getFromName('xl/charts/chart1.xml'); | ||
$zip->close(); | ||
unlink($outputFilename); | ||
|
||
$dom = new DOMDocument(); | ||
if ($resultChart1Raw === false) { | ||
self::fail('Unable to open the chart file'); | ||
} else { | ||
$loaded = $dom->loadXML($resultChart1Raw); | ||
if (!$loaded) { | ||
self::fail('Unable to load the chart xml'); | ||
} else { | ||
$series = $dom->getElementsByTagName('ser'); | ||
$firstSeries = $series->item(0); | ||
if ($firstSeries === null) { | ||
self::fail('The chart XML does not contain a \'ser\' tag!'); | ||
} else { | ||
$spPrList = $firstSeries->getElementsByTagName('spPr'); | ||
|
||
// expect to see only one element with name 'c:spPr' | ||
self::assertCount(1, $spPrList); | ||
|
||
/** @var DOMNode $node */ | ||
$node = $spPrList->item(0); // Get the spPr element | ||
$actualXml = $dom->saveXML($node); | ||
if ($actualXml === false) { | ||
self::fail('Failure saving the spPr element as xml string!'); | ||
} else { | ||
self::assertXmlStringEqualsXmlString('<c:spPr><a:ln w="12700"></a:ln></c:spPr>', $actualXml); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |