使用 PHP 电子表格 1.2.1 保存图表



我正在读取一个XLSX文件作为模板并填写几个现有的工作表。文件中我没有触摸的其他一些工作表包含指向更新工作表的链接以及基于这些链接单元格的图表。

当我在填写数据后将模板另存为新的 XLSX 文件时,图表从我什至没有触摸的其他工作表中消失了。

我在作者中添加了一个"includeCharts"语句,但这也无济于事

$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->setIncludeCharts(true);
$writer->save($systemPath);

知道我需要做什么才能避免丢失图表吗?

在这里找到了答案。nic86(4天前(的最后一条评论成功了。但我只让它适用于 xlsx,这对我来说已经足够了。

模板中的 Excel 未复制图表。 #382

随后我遇到了另一个问题:如果你想拥有基于动态命名范围的图表:运气不好。不久前已经注意到一个错误,但似乎什么也没发生。也在这里:没有回答我的问题... 这是错误描述:定义的名称范围从模板文件未复制到文件 #462

更准确地说: 这有效(静态范围(

$spreadsheet->addNamedRange( new NamedRange('DRange_AvgVarInt_modified', $worksheet, 'A1', true) );

这不起作用(动态范围(

$spreadsheet->addNamedRange( new NamedRange('DRange_AvgVarRate', $worksheet, '=OFFSET(midlayer!$B$7,0,0,1,MIN(BaseData!$C$2,36))', true) );

错误消息是:

Exception: Invalid cell coordinate 36))

显然,PHPSpreadsheet试图解析表达式,而不是简单地复制它。对解决方法有任何想法吗?或者任何人都可以提供错误修复。不幸的是,我不是一个足够好的编码员,无法自己做。但我真的很讨厌不得不回到静态范围......

解决方法实际上是以编程方式动态创建静态范围。不幸的是,没有其他办法。就我而言,我的图表是完全动态的,即基表的长度也是动态的。 我试图通过像这样动态操作图表来使用 PHP 电子表格解决这个问题。它基本上有效,但我的部分更改后来被覆盖,所以它并没有真正成功。现在我决定放弃:我现在将以编程方式创建所有图表,因为如果您使用动态图表,从模板更改图表有太多限制。

foreach ($worksheet->getChartCollection() as $chart) {
if ($chart instanceof Chart) {
$plotArea = $chart->getPlotArea(); //get the plot area of the chart (one thing)
$dataSeries = $plotArea->getPlotGroup(); //array of all the data series
$dataManipulated = false;
foreach ($dataSeries as &$dataSer) { //by reference to change the values deep down!!
$val = $dataSer->getPlotValues();
foreach ( $val as &$dataSeriesValues) {
$dataSource = $dataSeriesValues->getDataSource();
$dataValues = $dataSeriesValues->getDataValues();
$dataValuesLength = count($dataValues);
for ($y=$pointCount; $y < $dataValuesLength; $y++) {
unset($dataValues[$y]);
}                        
if ( strpos($dataSource, 'DRange_Dates_' . $tf ) !== false ) {
$dataSeriesValues->setDataSource( $sheetName . '!D2:' . $xC . '2' );                            
} elseif ( strpos($dataSource, 'DRange_AvgVarInt_modified_' . $tf ) !== false ) {
$dataSeriesValues->setDataSource( 'midlayer!B10:' . $xCML . '10' ); 
} elseif ( strpos($dataSource, 'DRange_AvgVarRate_' . $tf ) !== false ) {
$dataSeriesValues->setDataSource( 'midlayer!B7:' . $xCML . '7' ); 
}
$dataSeriesValues->setDataValues( $dataValues );
}
$cat = $dataSer->getPlotCategories();
foreach ( $cat as &$categoryValues) {
$dataSource = $categoryValues->getDataSource();
$dataValues = $categoryValues->getDataValues();
$dataValuesLength = count($dataValues);
for ($y=$pointCount; $y < $dataValuesLength; $y++) {
unset($dataValues[$y]);
}                        
if ( strpos($dataSource, 'DRange_Dates_' . $tf ) !== false ) {
$categoryValues->setDataSource( $sheetName . '!D2:' . $xC . '2' );                            
} elseif ( strpos($dataSource, 'DRange_AvgVarInt_modified_' . $tf ) !== false ) {
$categoryValues->setDataSource( 'midlayer!B10:' . $xCML . '10' ); 
} elseif ( strpos($dataSource, 'DRange_AvgVarRate_' . $tf ) !== false ) {
$categoryValues->setDataSource( 'midlayer!B7:' . $xCML . '7' ); 
}
$categoryValues->setDataValues( $dataValues );
}
}
$plotArea->setPlotSeries($dataSeries); 
unset($dataSeriesValues); // break the reference with the last element
unset($categoryValues); // break the reference with the last element
unset($dataSer); // break the reference with the last element               
}

}

如果你想让你的图表看起来更好一点,你就会遇到下一个障碍。您无法自行设置图表的配色方案。

class Theme extends WriterPart

包含这个

private static $colourScheme = [
'dk2' => '1F497D',
'lt2' => 'EEECE1',
'accent1' => '4F81BD',
'accent2' => 'C0504D',
'accent3' => '9BBB59',
'accent4' => '8064A2',
'accent5' => '4BACC6',
'accent6' => 'F79646',
'hlink' => '0000FF',
'folHlink' => '800080',
];

这是十六进制的标准办公室配色方案。使用它,您的图表将看起来像其他人的图表。如果您不希望这样做,则无法更改它,除非进行硬编码更改,这当然不是最佳选择。但我没有找到其他方法。如果有人有更好的方法,请告诉我。谢谢。使用多种配色方案而不仅仅是一种配色方案也很棒。不幸的是,也没有找到做到这一点的方法。

最新更新