[英]Save charts with PHP Spreadsheet 1.2.1
我正在读取XLSX文件作为模板,并填写几个现有的工作表。 我不触摸的文件中的其他一些工作表包含指向更新的工作表的链接以及基于这些链接单元格的图表。
当我在填写数据后将模板另存为新的XLSX文件时,图表从我什至没有碰过的其他工作表中消失了。
我向编写者添加了一个“ includeCharts”语句,但这也无济于事
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->setIncludeCharts(true);
$writer->save($systemPath);
为了避免丢失图表,我需要做什么?
在这里找到答案。 nic86的最新评论(4天前)做到了。 但是我只为xlsx工作,这对我来说已经足够了。
随后,我遇到了另一个问题:如果您想要基于动态命名范围的图表:运气不好。 之前已经注意到一个错误,但是似乎什么也没有发生。 还在这里:对我的问题没有回应...这是错误描述: 模板文件中的已定义名称范围未复制到文件#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尝试解析表达式,而不是简单地复制它。 有任何解决方法的想法吗? 或者任何人都可以提供错误修复。 不幸的是,我自己还不够熟练。 但是我真的很讨厌不得不回到静态范围...
解决方法实际上是通过编程动态创建静态范围。 不幸的是没有其他方法。 就我而言,我的图表是完全动态的,即基表的长度也是动态的。 我试图通过像这样动态地操纵图表来解决该问题。 它基本上可以正常工作,但是部分更改后来被覆盖,因此并没有真正成功。现在我决定放弃:我现在将以编程方式创建所有图表,因为如果您使用模板,则从模板更改图表会有太多限制动态图表。
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',
];
这是十六进制的标准Office配色方案。 使用此图表,您的图表将看起来像其他任何人的图表。 如果您不希望更改,则除了硬编码更改外,这当然不是最佳选择。 但是我没有找到其他方法。 如果有人有更好的方法,请告诉我。 谢谢。 使用多种配色方案,而不是仅使用一种配色方案也将非常不错。 不幸的是,没有找到一种方法来做到这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.