我正在阅读XLSX文件作为模板并填写几个现有的工作表。我不接触的文件中的其他工作表包含指向更新的工作表的链接以及基于这些链接单元格的图表。
当我在填写数据后将模板另存为新的XLSX文件时,图表将从我甚至不接触的其他工作表中消失。
我添加了一个" includeCharts"对作者的陈述,但这对任何人都没有帮助
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->setIncludeCharts(true);
$writer->save($systemPath);
知道我需要做些什么才能避免丢失图表吗?
答案 0 :(得分:0)
在这里找到答案。来自nic86(4天前)的最后评论就是这个伎俩。但我只为xlsx工作,这对我来说已经足够了。
Excel from template didn't copy charts. #382
随后我又陷入了另一个问题:如果你想拥有基于动态命名范围的图表:运气不好。有一个错误已经被注意到,但似乎没有任何事情发生。也在这里:没有回答我的问题...... 这是错误描述:Defined Name Range from template file not copying to file #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尝试解析表达式而不是简单地复制它。关于解决方法的任何想法?或者任何人都可以提供错误修复。不幸的是,我自己也不是一个好的编码员。但我真的很讨厌不得不回到静态范围......
答案 1 :(得分:0)
解决方法实际上是以编程方式动态创建静态范围。不幸的是没有其他方式。在我的情况下,我的图表是完全动态的,即基表的长度也是动态的。 我试图通过像这样动态操作图表来解决PHP Spreadsheet问题。它基本上工作但我的部分改变后来被覆盖所以它并没有真正成功。现在我决定放弃:我现在将以编程方式创建我的所有图表,因为如果你使用的话,从模板更改图表有太多限制动态图表。
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配色方案。使用此图表将看起来像其他人的图表。如果你不希望你改变它,除了硬编码的改变,当然这不是最好的选择。但我没有找到另一种方式。如果有人有更好的方法请告诉我。谢谢。使用几种颜色方案而不是一种颜色方案也会很棒。不幸的是,没有办法做到这一点。