layui.excel导出图片必须使用字段名img(大小写敏感),值为含src(data URI格式base64)、width和height的对象;纯URL字符串或非img字段名、二维数组结构均无法显示图片。
layui.excel 导出图片必须用 img 字段 + base64 对象,不是 URL 字符串
直接把 "https://xxx.com/a.jpg" 塞进数据数组,导出的 excel 里只会显示文字路径,不会渲染图片。layui.excel 只识别名为 img(大小写敏感)的字段,且值必须是形如 { src: 'data:image/png;base64,...', width: 80, height: 60 } 的对象。
常见错误:字段名写成 avatar、photo 或 image;或传了字符串但没转 base64;或漏了 width / height —— 这三者缺一不可。
- 字段名必须严格为
img -
src必须是完整 data URI,格式为data:image/[type];base64,[data] -
width和height单位是像素,建议 ≤ 200,否则导出卡顿或失败
fetch 图片转 base64 要处理跨域和类型推断
浏览器 fetch 图片时若服务端没配 Access-Control-Allow-Origin: *,会直接报错 TypeError: Failed to fetch,后续逻辑中断。即使能 fetch 到,也要手动判断 MIME 类型,不能硬写 png 或 jpg。
实操建议:
- 先检查图片 URL 是否同源;非同源务必确认服务端响应头含
Access-Control-Allow-Origin - 用
response.headers.get('content-type')获取真实 MIME 类型, fallback 到url.endsWith('.png') ? 'png' : 'jpg' - 避免在
map中同步调用fetch,必须用Promise.all()并发控制数量(建议 ≤ 20 个并发)
导出结构必须用对象数组,不能用纯二维数组
layui.excel.exportExcel([[...], [...]]) 这种纯二维数组方式,无论你字段叫什么、值是什么,img 都会被当作文本输出 —— 插件压根不解析对象结构。
真正生效的写法是:
<pre class="brush:php;toolbar:false;">const data = [
{ name: '张三', score: 95, img: { src: 'data:image/png;base64,...', width: 60, height: 60 } },
{ name: '李四', score: 87, img: { src: 'data:image/jpeg;base64,...', width: 60, height: 60 } }
];
layui.excel.exportExcel({ sheet1: data }, '成绩单.xlsx', 'xlsx');
注意:sheet1 是工作表名(任意字符串),不是变量;<code>data 是对象数组,不是二维数组;img 必须在每个对象顶层,嵌套在 user.info.img 里无效。
大图或批量图片极易触发内存崩溃
一张 100KB 的 JPG 转 base64 后约 133KB,50 张就是近 7MB 字符串,加上 SheetJS 渲染开销,Chrome 主线程可能卡死 3 秒以上,甚至弹出“页面无响应”提示。
可操作的缓解手段:
- 前端预压缩:用
canvas将原图缩放到 ≤ 200×200 再转 base64 - 限制单次导出图片数:超过 30 张时,提示用户“建议分批导出”并禁用按钮
- 加 loading 状态 + abortController:用户中途关闭弹窗时主动 cancel fetch 请求
最易被忽略的是:图片尺寸声明(width/height)必须与实际 base64 解码后图像一致,否则 Excel 打开时图片拉伸变形或空白 —— 这个没法靠 guess,得真解码或服务端返回宽高元数据。


















