
phpspreadsheet 在读取并保存 excel 文件时,会生成新文件而非直接修改原文件,而部分图像、形状等富媒体元素因底层不支持而被丢弃,需通过启用内存缓存和正确配置写入器来解决。
在使用 PhpSpreadsheet 处理包含图片(如插入的 PNG/JPEG)、形状(如文本框、箭头、自定义图形)的 Excel 文件时,常见问题是在调用 $writer->save() 后,目标工作表(如 Sheet2)中的图像或形状完全消失。根本原因在于:PhpSpreadsheet 并非完整实现 Excel 的所有 OOXML 规范,尤其对
✅ 正确做法是启用 内存中绘图对象缓存 并禁用不兼容的兼容性模式:
清理、标准化、验证并汇总杂乱的 Excel 工作簿。当 Codex 需要处理 `.xlsx`、`.xls`、`.xlsm` 或 `.csv` 格式的数据时使用,包括:统一表头格式、删除空白行与空白列、修剪文本内容、去重记录、检测数据质量问题、拆分或合并工作表、生成清洗后的工作簿,以及为业务电子表格生成审计摘要。
<?php require __DIR__ . '/vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; $origin_file = 'original_with_images.xlsx'; // ✅ 使用 IOFactory 更健壮地加载(自动识别格式) $spreadsheet = IOFactory::load($origin_file); // ? 关键:确保绘图对象(图片/形状)被加载到内存 // PhpSpreadsheet 1.23+ 默认已启用,但旧版本建议显式确认 // (无需额外代码,但请确保使用 ≥1.20 版本) $writer = new Xlsx($spreadsheet); // ❌ 移除以下两行 —— 它们会破坏兼容性与绘图支持: // $writer->setPreCalculateFormulas(false); // 非必需,且可能干扰渲染 // $writer->setOffice2003Compatibility(true); // ⚠️ 严重警告:此选项强制降级为 Excel 2003 兼容模式,**完全不支持现代绘图对象**!必须禁用! $new_file = './file_uploads/report_file/' . $file_info_idx . '_tmp.' . $file_ext; // ✅ 推荐:启用内存缓存(默认已开启),并确保写入器使用标准 XLSX 模式 $writer->setIncludeCharts(false); // 如无需图表可设为 false(默认 false) $writer->save($new_file);
⚠️ 注意事项:
- setOffice2003Compatibility(true) 是导致图片消失的最常见原因:该模式会绕过 DrawingML 渲染流程,仅输出 BIFF 格式兼容的极简结构,所有图片/形状均被丢弃;
- 确保 PhpSpreadsheet 版本 ≥ 1.20(推荐 ≥ 1.26):早期版本(如
- 图片路径需为相对路径或嵌入二进制流:PhpSpreadsheet 仅支持已嵌入工作簿的图片(即 Excel 中“插入 → 图片”后保存的文件),不支持链接外部图片(
中的嵌入式 rId); - 若仍丢失,请检查原始文件是否使用了 Excel 特有功能(如 Ink 签名、3D 模型、SVG 图形),这些目前不受 PhpSpreadsheet 支持。
? 总结:
图片/形状丢失并非 Bug,而是功能边界所致。解决核心是——禁用 Office 2003 兼容模式、升级到稳定新版、避免手动干预绘图逻辑。如业务强依赖复杂图形,建议将 PhpSpreadsheet 用于数据处理,再通过模板引擎(如 Twig + Excel XML 模板)或桌面自动化(Power Automate / Win32::OLE)补全图形导出环节。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










