最简方案是在表格列定义中用templet函数为身份证字段值末尾添加制表符 ,即templet: function(d) { return (d.idCard || '') + ' '; },确保Excel识别为文本;若需导出时脱敏,则须重写layui.table.parseTempData方法处理原始数据。
导出前用 templet 对身份证字段加制表符(最简方案)
layui 自带的 exportfile 导出逻辑会把纯数字长串(如18位身份证)识别为数值,excel 打开后自动转成科学计数法或截断末尾 0。最轻量的解法不是改源码、也不是引入 xlsx 插件,而是在表格列定义里用 templet 预处理字段值:在身份证号后面拼一个 ,强制 excel 当作文本读取。
-
templet: function(d) { return d.idCard + ' '; }—— 注意是单引号包裹的,不是字符串'\t'或't' - 如果后端返回的是 null/undefined,得先兜底:
return (d.idCard || '') + ' '; - 这个
不会影响页面渲染(浏览器忽略制表符空白),只作用于导出时的原始数据流 - 别用
或空格替代 —— Excel 会裁掉首尾空白,是唯一被广泛保留的“无害文本标记”
需要完整脱敏(如 110101********1234)就改 parseTempData 入口
如果你不满足于“显示正常”,而是明确要求导出文件里身份证就得是脱敏格式(比如只显示前6后4),就不能只靠 templet —— 因为 templet 只影响页面展示,导出时仍会走 parseTempData 重新取原始字段值。必须拦截这个环节:
- 在 layui 初始化之后、
table.render()之前,重写layui.table.parseTempData: layui.table.parseTempData = function(options, data, item) { if (item.field === 'idCard' && data) { const id = String(data); return id.length === 18 ? id.slice(0, 6) + '****' + id.slice(-4) : id; } return data; };- 注意:这个函数会被反复调用,别在里面做 DOM 操作或异步请求
- 如果表格有多个身份证字段(如
idCard和guardianIdCard),要分别判断item.field
为什么不用改 table.js 源码或引入 xlsx.full.min.js
网上很多方案让你下载 xlsx 插件、修改 table.js 里的 prepareExcelData,实际踩坑概率高:
-
xlsx.full.min.js和 layui 2.x 的 Promise 链不兼容,容易导致导出按钮点击无响应 - 直接改
table.js源码会让升级困难,且新版 layui(如 2.9+)已调整导出逻辑路径,老教程的 patch 位置可能失效 - 多数项目只需要解决“显示正确”或“简单脱敏”,没必要为单个字段引入 500KB 的 xlsx 库
- 真正需要 Excel 样式控制(合并单元格、颜色、公式)才值得上 xlsx;纯数据导出,CSV 就够用,而
方案对 CSV 和 Excel 都生效
导出后 Excel 里仍显示 000?检查这三点
即使加了 ,还是出现末尾三位变 000,大概率是以下某个环节漏了:
- 后端接口返回的身份证字段是数字类型(如 JSON 里没加引号),浏览器自动转成 Number 后丢失精度 —— 必须确保接口返回的是字符串:
"idCard": "110101199003072234",不是"idCard": 110101199003072234 - 用了
lay-data动态绑定但没设data-type="text",某些旧版 layui 渲染时会二次转换 - 导出时用了自定义
data参数(如table.exportFile('id', customData)),但customData里身份证字段没加—— 此时templet不生效,得手动处理数组
真正麻烦的不是加那一个 ,而是你得确认它从接口、到渲染、再到导出这一整条链路上,没有被任何地方悄悄 toString() 或 Number() 一次。只要中间断一环,脱敏或防科学计数法都会失效。











