PhpSpreadsheet:无法在同一图表绘图区添加多组数据系列
问题分析与解决方案
你遇到的问题根源在于两个DataSeries的plotOrder(系列顺序)重复,以及标签未区分两组数据,导致Excel解析图表时出现冲突。以下是修正后的代码,可实现多组数据系列在同一图表中正常显示:
修正后的代码
use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Chart\DataSeries; use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues; use PhpOffice\PhpSpreadsheet\Chart\PlotArea; use PhpOffice\PhpSpreadsheet\Chart\Layout; use PhpOffice\PhpSpreadsheet\Chart\Title; use PhpOffice\PhpSpreadsheet\Chart\Legend as ChartLegend; use PhpOffice\PhpSpreadsheet\Chart\Chart as ExcelChart; $spreadsheet = new Spreadsheet(); $layout = new Layout(); $layout->setShowVal(true); $layout->setShowPercent(true); $layout->setShowLegendKey(true); $worksheet = $spreadsheet->getActiveSheet(); $worksheet->setSelectedCell('A26'); // 第一组数据(统一表头为数字类型) $worksheet->fromArray( [ ['', 2010, 2011, 2012], ['Q1', 12, 15, 21], ['Q2', 56, 73, 86], ['Q3', 52, 61, 69], ['Q4', 30, 32, 12], ], NULL, 'A26' ); // 第二组数据(统一表头为数字类型) $worksheet->fromArray( [ ['', 2010, 2011, 2012], ['Q1', 18, 154, 29], ['Q2', 76, 33, 16], ['Q3', 59, 89, 103], ['Q4', 51, 98, 45], ], NULL, 'A35' ); // 第一组数据的标签 $dataSeriesLabels1 = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$26', null, 1), // 2010(组1) new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$26', null, 1), // 2011(组1) new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$26', null, 1), // 2012(组1) ]; // 第二组数据的标签(添加后缀区分两组) $dataSeriesLabels2 = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$35', null, 1, '2010(组2)'), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$35', null, 1, '2011(组2)'), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$35', null, 1, '2012(组2)'), ]; $xAxisTickValues = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$27:$A$30', null, 4), // Q1-Q4 ]; // 第一组数据值 $dataSeriesValues1 = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$27:$B$30', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$27:$C$30', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$27:$D$30', null, 4), ]; // 创建第一组数据系列,plotOrder为0-2 $series1 = new DataSeries( DataSeries::TYPE_BARCHART, DataSeries::GROUPING_CLUSTERED, range(0, count($dataSeriesValues1) - 1), $dataSeriesLabels1, $xAxisTickValues, $dataSeriesValues1 ); $series1->setPlotDirection(DataSeries::DIRECTION_COL); // 第二组数据值 $dataSeriesValues2 = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$36:$B$39', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$36:$C$39', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$36:$D$39', null, 4), ]; // 创建第二组数据系列,plotOrder从3开始,避免与第一组重复 $series2 = new DataSeries( DataSeries::TYPE_BARCHART, DataSeries::GROUPING_CLUSTERED, range(count($dataSeriesValues1), count($dataSeriesValues1) + count($dataSeriesValues2) - 1), $dataSeriesLabels2, $xAxisTickValues, $dataSeriesValues2 ); $series2->setPlotDirection(DataSeries::DIRECTION_COL); // 将两个数据系列加入同一绘图区 $plotArea = new PlotArea($layout, [$series1, $series2]); $legend = new ChartLegend(ChartLegend::POSITION_RIGHT, null, false); $title = new Title('Test Bar Chart'); $yAxisLabel = new Title('Value ($k)'); // 创建图表 $chart = new ExcelChart( 'chart1', $title, $legend, $plotArea, true, DataSeries::EMPTY_AS_GAP, null, $yAxisLabel ); // 设置图表位置 $chart->setTopLeftPosition('A6'); $chart->setBottomRightPosition('K22'); $worksheet->addChart($chart); // 保存文件(可选) $writer = new Xlsx($spreadsheet); $writer->save('multi-series-chart.xlsx');
关键修改点
- plotOrder不重复:第二组数据系列的
plotOrder从第一组的长度开始(即3、4、5),确保所有系列在Excel中拥有唯一的顺序标识,避免冲突。 - 区分系列标签:为第二组数据的标签添加后缀(如“(组2)”),使图例能够清晰区分两组数据,同时避免标签重复导致的解析问题。
- 统一数据类型:将第二组数据的表头从字符串改为数字,与第一组保持一致,避免潜在的类型解析异常。
如果需要动态添加更多数据系列,只需重复上述逻辑:创建新的DataSeries时,确保其plotOrder从之前所有系列的总数量开始递增,并定义独立的标签即可。
内容的提问来源于stack exchange,提问作者Vlado
相关产品推荐
相关产品推荐

