layui.excel导出图片需将URL转base64并封装为{src: 'data:image/...;base64,...', width, height}对象,字段名必须为img,否则仅显示字符串;纯二维数组不支持图片嵌入。
layui.excel 导出含图片路径的数据时,图片不会自动显示
直接把图片 url 字符串(如 "https://example.com/img/1.jpg")塞进 layui.excel.exportexcel() 的二维数组里,导出的 excel 里只会显示文字路径,不是真实图片。sheetjs 和 layui-excel 默认不解析和嵌入图片,这是最常被误踩的点。
真正能导出「可见图片」的方案,必须满足两个条件:图片可被前端 JS 读取(同源或支持 CORS),且用 XLSX.utils.sheet_add_ole_object() 或类似机制手动插入 —— 但 layui-excel 当前版本(v2.0+)并未封装该能力。
所以现实路径只有一条:把图片路径转成 base64 后,交由 layui.excel 的 img 字段约定格式处理(它内部会调用 SheetJS 的图片写入逻辑)。
- 确保图片资源允许跨域(服务端响应头含
Access-Control-Allow-Origin: *) - 不能传原始 URL 字符串,得先 fetch +
response.arrayBuffer()+arrayBufferToBase64() - base64 字符串需按
layui.excel要求包装为对象:{ src: 'data:image/png;base64,...', width: 80, height: 60 } - 字段名必须叫
img(大小写敏感),否则插件忽略该列
如何构造带图片的二维数组并导出
layui.excel.exportExcel() 支持两种数据结构:纯二维数组([['A','B'],[1,2]])或带 img 字段的对象数组(推荐)。后者才能触发图片嵌入逻辑。
关键不是“有路径”,而是“字段命名 + base64 + 尺寸声明”三者缺一不可。示例中假设你已有用户头像 URL 列表:
const data = [
{ name: '张三', score: 95, img: { src: 'data:image/png;base64,iVBORw0KGgo...', width: 60, height: 60 } },
{ name: '李四', score: 87, img: { src: 'data:image/jpeg;base64,/9j/4AAQ...', width: 60, height: 60 } }
];
然后导出:
layui.excel.exportExcel({
sheet1: data
}, '成绩单.xlsx', 'xlsx');
注意:sheet1 是工作表名,不是变量;若用纯数组方式,img 字段会被当作文本输出,无效。
大图或大量图片导出会卡顿甚至失败
每张图片转 base64 后体积膨胀约 33%,100 张 100KB 的图 → 内存中近 13MB 字符串。浏览器可能触发内存警告或主线程阻塞。
- 单次导出建议控制在 ≤ 50 张图,单图尺寸压缩到 ≤ 200×200 像素
- 避免在
done回调里同步 fetch 所有图:要用Promise.all()并发限制(如concurrency: 5) - 超大列表(如 1w 行带图)应放弃前端导出,改用后端生成(传 ID 列表,服务端拉图、压缩、写入 xlsx 流)
- 若图片来自本地文件选择(
<input type="file">),可用FileReader.readAsDataURL(),无需跨域
导出后 Excel 中图片错位或变形
这是因 width/height 值未匹配实际像素比,或单元格行高列宽未适配。layui-excel 不自动调整行列尺寸,全靠你预设。
- 务必设置
img对象里的width和height(单位是像素,非百分比) - 导出前可加空行或隐藏列预留空间,例如在表头后插入一行
['','',''],再设该行高为80 - 若需精确控制,改用原生 SheetJS:
XLSX.utils.sheet_add_img()+cell.v定位,但失去 layui-excel 的便捷性 - 测试时用 Excel 桌面版打开,网页版 Excel Online 可能不渲染 OLE 图片
src 前缀是否完整(必须含 data:image/xxx;base64,)、以及目标 Excel 版本是否 ≥ 2010。











