PHPSpreadsheet加载模板生成折线图保存失败,提示被另一用户锁定
PHPSpreadsheet模板折线图导出报错解决方案
问题根因
- 第一个内容损坏报错:模板中的折线图绑定的数据源区域无有效数据时,PHPSpreadsheet生成的图表配置文件包含无效空值序列,触发Office文件校验规则。
- 第二个文件锁定报错:属于第一个报错的衍生现象,Office尝试修复损坏文件时会生成临时锁文件,并非真实被其他用户占用。
修复方案
无需在模板中预置假数据,通过代码兼容空数据场景+主动刷新图表缓存即可解决,修改后的代码如下:
<?php // ... snip $reader = IOFactory::createReader($inputFileType); $reader->setIncludeCharts(true); $spreadsheet = $reader->load($inputFileName); // ... snip // populate chart data $sheet = $spreadsheet->getSheetByName('Ratios'); $hasValidData = false; // reverse order, so populate "backwards" for($endingRow = 14; ($endingRow > 1) && ($row = $last13Ratios->nextRecord()); $endingRow--) { $hasValidData = true; $sheet->setCellValue('A'.$endingRow, $row->date); $sheet->setCellValue('B'.$endingRow, $row->percent60/100); $sheet->setCellValue('C'.$endingRow, $row->percent90/100); $helper->log(print_r($row, true)); // 补充print_r第二个参数,避免输出内容污染文件流 } // 无有效数据时兼容处理 if (!$hasValidData) { // 给绑定区域写入空值,保证格式合法,不会显示假数据 for ($i = 2; $i <= 14; $i++) { $sheet->setCellValue('A'.$i, ''); $sheet->setCellValue('B'.$i, ''); $sheet->setCellValue('C'.$i, ''); } // 可选配置:无数据时直接隐藏图表,更符合「无信息也不输出错误」的需求 foreach ($sheet->getChartCollection() as $chart) { $chart->setVisible(false); } } // 关键步骤:刷新所有图表的数据源缓存,同步单元格修改后的最新数据 foreach ($sheet->getChartCollection() as $chart) { $chart->refresh(); } // ... snip $writer = new XlsxWriter($spreadsheet); $writer->setIncludeCharts(true); $callStartTime = microtime(true); $writer->save($saveFileName); $helper->logWrite($writer, $saveFileName, $callStartTime); $spreadsheet->disconnectWorksheets(); unset($spreadsheet); // 补充释放对象,避免文件句柄残留 die();
额外注意事项
如果文件锁定报错持续出现,可以检查保存目录下是否存在~$Hello World.xlsx格式的隐藏临时锁文件,删除后重新测试即可。
内容的提问来源于stack exchange,提问作者Tim Morton
相关产品推荐
相关产品推荐

