Chart not rendered properly - php

I have a small table
and want to create a TYPE_DONUTCHART with the PHPExcel library. I took the example code from the Examples/33chartcreate-pie.php file and adapted it accordingly:
$dataseriesLabels2 = array(
//new PHPExcel_Chart_DataSeriesValues('String', 'Summen!$A$1', NULL, 1),
);
$xAxisTickValues2 = array(
new PHPExcel_Chart_DataSeriesValues('String', 'Summen!$B$1:$C$1', NULL, 2),
);
$dataSeriesValues2 = array(
new PHPExcel_Chart_DataSeriesValues('Number', 'Summen!$B$2:$C$2', NULL, 2),
);
The file is served by the script, but when I try to open it, an error message occurs:
We found a problem with some content in "Myfile.xlsx". Do you want us to try to recover as much as we can? If you trust the source of this workbook, click Yes.
When I click Yes and activate editing on the document, I get the following message like this:
Excel has finished the check and repair of your file. Some parts of this file have been repaired or discarded.
Removed part: Part /xl/drawings/drawing4.xml. (drawing form)
What's wrong in my code? What do I have to modify?
Notes:
As you can see, I'm using another dataset than in the example. There's only data in the range A1:C2 (see screenshot above).
The worksheets name is Summen, I double checked, that the problem is not a typo of the sheet.
It's been asked in the comments, I have already tried removing the comment from the dataseriesLabels2 entry.

My example
$objPHPExcel = new PHPExcel();
$objWorksheet = $objPHPExcel->getActiveSheet();
$objWorksheet->fromArray(
array(
array('Whatever', 'Cat1', 'Cat2'),
array(77, 247, 128),
)
);
$objWorksheet->setTitle('Summen');
$dataSeriesLabels1 = array(
// new PHPExcel_Chart_DataSeriesValues('String', 'Summen!$A$1', NULL, 1),
);
$xAxisTickValues1 = array(
new PHPExcel_Chart_DataSeriesValues('String', 'Summen!$B$1:$C$1', NULL, 2),
);
$dataSeriesValues1 = array(
new PHPExcel_Chart_DataSeriesValues('Number', 'Summen!$B$2:$C$2', NULL, 2),
);
$series1 = new PHPExcel_Chart_DataSeries(
PHPExcel_Chart_DataSeries::TYPE_DONUTCHART, // plotType
NULL, // plotGrouping
range(0, count($dataSeriesValues1)-1), // plotOrder
$dataSeriesLabels1, // plotLabel
$xAxisTickValues1, // plotCategory
$dataSeriesValues1 // plotValues
);
$layout1 = new PHPExcel_Chart_Layout();
$layout1->setShowVal(TRUE);
$layout1->setShowPercent(TRUE);
$plotArea1 = new PHPExcel_Chart_PlotArea($layout1, array($series1));
$legend1 = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);
$title1 = new PHPExcel_Chart_Title('Test Pie Chart');
$chart1 = new PHPExcel_Chart(
'chart1', // name
$title1, // title
$legend1, // legend
$plotArea1, // plotArea
true, // plotVisibleOnly
0, // displayBlanksAs
NULL, // xAxisLabel
NULL // yAxisLabel - Pie charts don't have a Y-Axis
);
// Set the position where the chart should appear in the worksheet
$chart1->setTopLeftPosition('A7');
$chart1->setBottomRightPosition('H20');
// Add the chart to the worksheet
$objWorksheet->addChart($chart1);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->setIncludeCharts(TRUE);
$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
generates correctly without any errors

Related

We found a problem with some content in 'Spreadsheet.xlsx'. Do you want us to try to recover as much as we can?

I have the following basic PHP project (just one file plus composer config):
composer.json
{
"config": {
"optimize-autoloader": true,
"platform": {
"php": "7.4.9"
}
},
"require": {
"phpoffice/phpspreadsheet": "1.10.0"
}
}
index.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
function errorHandler() {
return true;
}
set_error_handler('errorHandler');
$sheets = array(
array('index' => 0, 'title' => 'Graph'),
array('index' => 1, 'title' => 'Data'),
);
$phpSpreadsheetObject = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
foreach ($sheets as $sheet) {
$name = $sheet['title'];
if ($sheet['index']) {
$worksheet[$name] = $phpSpreadsheetObject->createSheet($sheet['index']);
} else {
$worksheet[$name] = $phpSpreadsheetObject->getActiveSheet();
}
$phpSpreadsheetObject->setActiveSheetIndex($sheet['index']);
$worksheet[$name]->setTitle($sheet['title']);
}
$sheet = 'Graph'; // !!! SHEET CHANGE
$phpSpreadsheetObject->setActiveSheetIndex(1);
$worksheet[$sheet]->getColumnDimension('A')->setWidth("50");
// Charts
// Clients Chart
$xAxisTickValues = array(new \PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues('String', "'Data'!A2:A4", null, 3));
$dataSeriesValues = array(new \PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues('Number', "'Data'!B2:B4", null, 3));
$chartSeries = new \PhpOffice\PhpSpreadsheet\Chart\DataSeries(
\PhpOffice\PhpSpreadsheet\Chart\DataSeries::TYPE_BARCHART, // plotType
\PhpOffice\PhpSpreadsheet\Chart\DataSeries::GROUPING_CLUSTERED, // plotGrouping
range(0, count($dataSeriesValues) - 1), // plotOrder
[], // plotLabel
$xAxisTickValues, // plotCategory
$dataSeriesValues // plotValues
);
$chartSeries->setPlotDirection(\PhpOffice\PhpSpreadsheet\Chart\DataSeries::DIRECTION_COLUMN);
$plotArea = new \PhpOffice\PhpSpreadsheet\Chart\PlotArea(null, array($chartSeries));
$title = new \PhpOffice\PhpSpreadsheet\Chart\Title('Clients');
$yAxisLabel = new \PhpOffice\PhpSpreadsheet\Chart\Title('');
$charts = new \PhpOffice\PhpSpreadsheet\Chart\Chart(
'clients', // name
$title, // title
null, // legend
$plotArea, // plotArea
true, // plotVisibleOnly
0, // displayBlanksAs
null, // xAxisLabel
$yAxisLabel // yAxisLabel
);
$charts->setTopLeftPosition('A1');
$charts->setBottomRightPosition('B19');
$worksheet[$sheet]->addChart($charts);
$sheet = 'Data'; // !!! SHEET CHANGE
$phpSpreadsheetObject->setActiveSheetIndex(1);
$dataArray = array(
1 => array('Date', 'Clients'),
2 => array(date('m/d/y', strtotime('01/01/2021')), '500'),
3 => array(date('m/d/y', strtotime('01/02/2021')), '725'),
4 => array(date('m/d/y', strtotime('01/03/2021')), '930'),
);
foreach (range('A', 'B') as $columnID) {
$worksheet[$sheet]->getColumnDimension($columnID)->setAutoSize(true);
}
$worksheet[$sheet]->fromArray($dataArray, ' ', 'A1');
// set the first tab as active
$phpSpreadsheetObject->setActiveSheetIndex(0);
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header("Content-Disposition: attachment;filename=Spreadsheet.xlsx");
header('Cache-Control: max-age=0');
$objWriter = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($phpSpreadsheetObject);
$objWriter->setIncludeCharts(true);
$objWriter->save('php://output');
?>
Setup:
$ composer i
When I visit the url:
http://localhost/index.php
the following Excel file is downloaded:
where you have 2 sheets: { Graph, Data }. The Graph is genreated based on the data on sheet: Data.
So far so good.
My Problem is: When I upgrade:
"phpoffice/phpspreadsheet": "1.10.0" -> "phpoffice/phpspreadsheet": "1.10.1"
(just patch update)
and hit the same url again, I get the following errors when trying to open the generated Excel file:
We found a problem with some content in 'Spreadsheet (1).xlsx'. Do you want us to try to recover as much as we can? if you trust the source of this workbook, click Yes.
and then this other error:
and the graph is not shown.
Any idea what modification I need to do on my code above to get rid of those errors and get the graph rendered?
Thanks!
I found the solution.
On the code above, just replace: 0, // displayBlanksAs -> 'gap', // displayBlanksAs.
On latest versions like: "phpoffice/phpspreadsheet": "1.16", there is a constant defined for this: DataSeries::EMPTY_AS_GAP, // displayBlanksAs.
That constant is not present on earlier versions like: 1.10.1.
Thanks!

PhpSpreadsheet charts not saving and/or corrupting file

So I'm working on a reporting application that requires generating Xls files with charts. The charts don't appear to be working though. I've tried just replacing the code below with the example in the PhpSpreadsheet github, but that also doesn't work.
I have the following for inserting the data (and chart) into the worksheet:
$this->spreadsheet->createSheet();
$worksheet = $this->spreadsheet->getActiveSheet();
$worksheet->setTitle($title);
$periodStartArray = array(array('', $periodStartDate, $periodEndDate));
while (!empty($stack)) {
$node = array_pop($stack);
if ($node->getData()['portfolioData'][0] != null) {
if ($node->getData()['portfolioData'][0]->getIncludeInStatusSide()) {
$startValue = (float)$this->getDataPoint($node, 'general', $this->periodStart, 'value');
$startValuePercent = number_format(($startValue / $this->startingTotalValues) * 100, $this->percentDecimals, $decimalPoints, $separators);
$endValue = (float)$this->getDataPoint($node, 'general', $this->periodEnd, 'value');
$endValuePercent = number_format(($endValue / $this->endingTotalValues) * 100, $this->percentDecimals, $decimalPoints, $separators);
$startArray = array($node->getData()['portfolioData'][0]->getNavn(), $startValuePercent, $endValuePercent);
$periodStartArray[] = $startArray;
}
}
}
$maxSize = count($periodStartArray);
$worksheet->fromArray($periodStartArray);
//$title . '!$B$1'
$dataSeriesLabels1 = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $title . '!$B$1', null, 1),
];
// $maxSize - 1 should give the actual number of data points (since the first entry in the array is the
// date row
$dataString = "'" . $title . "'" . '!$A$2:$A$' . $maxSize;
$xAxisTickValues1 = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $dataString, null, $maxSize - 1)
];
$dataString = "'" . $title . "'" . '!$B$2:$B$' . $maxSize;
$dataSeriesValues1 = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, $dataString, null, $maxSize - 1)
];
$series = new DataSeries(
DataSeries::TYPE_PIECHART,
null,
range(0, count($dataSeriesValues1) - 1),
$dataSeriesLabels1,
$xAxisTickValues1,
$dataSeriesValues1
);
$layout = new Layout();
$layout->setShowVal(true);
$layout->setShowPercent(false);
$plotArea = new PlotArea($layout, array($series));
$legend = new Legend(Legend::POSITION_RIGHT, null, false);
$title = new Title($title);
$chart1 = new Chart(
'chart1',
$title,
$legend,
$plotArea,
true,
0,
null,
null
);
$chart1->setTopLeftPosition('A10');
$chart1->setBottomRightPosition('P25');
$worksheet->addChart($chart1);
It successfully inserts the data into the spreadsheet, but does not print out any charts. Here is where I'm saving the spreadsheet:
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xls($this->spreadsheet);
$writer->setIncludeCharts(true);
$writer->save($this->outputFile);
So I'm including the charts, but no charts appear. When I change the format to Xlsx, it seems to at least try to insert the charts but they're corrupt and Excel removes them. It's just simple data. Literally one row of a company name in the A column and two dates of values down the B and C columns. When I manually insert the charts after the excel file gets generated it works no problem.
use this
DataSeries::EMPTY_AS_GAP, // displayBlanksAs
instaea of 0
like in sample file
https://github.com/PHPOffice/PhpSpreadsheet/blob/master/samples/templates/chartSpreadsheet.php
Change the 0 to 'gap' when creating the chart.
$chart1 = new Chart(
'chart1',
$title,
$legend,
$plotArea,
true,
'gap', // use 'gap' instead of 0,
null,
null
);
Below is the issue for PhPSpreadsheet
File containing a chart can not be opened by Excel 2003/2013/2019

PHPSPREADSHEET : show hidden data row in chart on Excel

i have my exported excel using phpspreadsheet contain chart works good on libre office, but have blank area chart when i open using MS. Excel.
The problem is, data range i use to build chart is hidden using this code.
$spreadsheet->getActiveSheet()->getRowDimension($rowNow)->setVisible(false);
but this can be done with setting on MS. excel like this.
and i use this code to build chart:
// Build the dataseries
$series = new PhpOffice\PhpSpreadsheet\Chart\DataSeries(
PhpOffice\PhpSpreadsheet\Chart\DataSeries::TYPE_PIECHART, // plotType
NULL, // plotGrouping
range(0, count($dataSeriesValues) - 1), // plotOrder
$dataSeriesLabels, // plotLabel
$xAxisTickValues, // plotCategory
$dataSeriesValues // plotValues
);
// Set the series in the plot area
$plotArea = new PhpOffice\PhpSpreadsheet\Chart\PlotArea(null, [$series]);
$legend = new PhpOffice\PhpSpreadsheet\Chart\Legend(PhpOffice\PhpSpreadsheet\Chart\Legend::POSITION_RIGHT, null, false);
$title = new PhpOffice\PhpSpreadsheet\Chart\Title($t);
$yAxisLabel = new PhpOffice\PhpSpreadsheet\Chart\Title('Value');
// create chart
$chart = new PhpOffice\PhpSpreadsheet\Chart\Chart(
'chart1', // name
$title, // title
$legend, // legend
$plotArea, // plotArea
true, // plotVisibleOnly
0, // displayBlanksAs
null, // xAxisLabel
$yAxisLabel // yAxisLabel
);
$chart->setTopLeftPosition($pos[0]);
$chart->setBottomRightPosition($pos[1]);
What attribute i should add to my chart builder to represent the setting i provide before?

PHPExcel and Office 2016

I'm currently using PHPExcel (v1.8.0) to generate an xlxs file with datas and graph. But when I open my generated document in office I get an error. I've tried to precise the orientation with the "setPlotDirection" method, and delete the y axis label.
This is the code :
$categories = array(
new \PHPExcel_Chart_DataSeriesValues('String', "'".$this->oSheet->getTitle()."'!\$A$5:\$A$31", null, 1)
);
$values = array(
new \PHPExcel_Chart_DataSeriesValues('Number', "'".$this->oSheet->getTitle()."'!\$BA$5:\$BA$31", null, 1),
);
$this->createChart($categories, $values, 'Title', 'Xlegend', 'YLegend', 'A34', 'K50');
function createChart($categories, $values, $title, $xLegnd, $yLegend, $topLeft, $bottomRight)
{
$series = new \PHPExcel_Chart_DataSeries(
\PHPExcel_Chart_DataSeries::TYPE_BARCHART,
\PHPExcel_Chart_DataSeries::GROUPING_STANDARD,
range(0, count($values) - 1),
null,
$categories,
$values
);
$series->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_VERTICAL);
$layout = new PHPExcel_Chart_Layout();
$layout->setShowVal(true);
$plotArea = new \PHPExcel_Chart_PlotArea(null, array($series));
$title = new \PHPExcel_Chart_Title($title);
$yAxisLabel = new \PHPExcel_Chart_Title($yLegend);
$xAxisLabel = new \PHPExcel_Chart_Title($xLegnd);
$chart = new \PHPExcel_Chart(
$title,
$title,
null,
$plotArea,
true,
0,
null,
$yAxisLabel
);
$chart->setTopLeftPosition($topLeft);
$chart->setBottomRightPosition($bottomRight);
$this->oSheet->addChart($chart);
}
All works fine with Excel 2010/2011 and Libre Office. But I get this error with Excel 2016 :
<recoveryLog>
<logFileName>error066200_01.xml</logFileName>
<summary>Des erreurs ont été détectées dans le fichier xxx</summary>
<removedParts>
<removedPart>Partie supprimée: /xl/drawings/drawing3.xml partie. (Forme de dessin)</removedPart>
</removedParts>
</recoveryLog>
Any idea ?
Thanks

Do not display axis in chart

Is there any option in PHPExcel to hide the primary vertical and horizontal axis in excel's line chart?
you may try this,
$chart2 = new PHPExcel_Chart(
'chart2', // name
$title, // title
NULL, // legend
$plotarea2, // plotArea
true, // plotVisibleOnly
0, // displayBlanksAs
NULL, // xAxisLabel
NULL // yAxisLabel
);
Finally I have found the solution by made changes in code.
File path: PHPExcel/Classes/PHPExcel/Chart/Axis.php
Code change: 'axis_labels' => 'none'
Thanks.
**
As of 1.8.1 or maybe even earlier you can style the x and y axes with setAxisOptionsProperties, like so:
$xAxisStyle = new PHPExcel_Chart_Axis();
$xAxisStyle->setAxisOptionsProperties('none', null, null, null, null, null, null, null);
$yAxisStyle = new PHPExcel_Chart_Axis();
$yAxisStyle->setAxisOptionsProperties('none', null, null, null, null, null, null, null);
$chart = new PHPExcel_Chart(
'Chart1', // name
$title, // title displayed on chart
$legend, // legend
$pa, // plotArea
true, // plotVisibleOnly
0, // displayBlanksAs
NULL, // xAxisLabel
NULL, // yAxisLabel
$xAxisStyle,// X-axis styling vertical
$yAxisStyle //Y-axis style horizontal
);

Categories