You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 14:48:09