如何避免ExcelJS读取日期转为数字?求日期转换方案
解决ExcelJS读取日期为数字的问题
一、直接避免读取为数字的方法
ExcelJS流式读取时,row.values返回的是单元格的原始序列化值(Excel内部存储的数字),要获取解析后的日期,需通过row.cells访问单元格详细信息,利用类型或格式判断并转换:
修改读取代码如下:
worksheet.on("row", async row => { const values = row.cells.map(cell => { // 若单元格已被识别为日期类型,直接返回Date对象 if (cell.type === 'date') { return cell.value; } // 针对未自动识别的情况,通过单元格格式判断(匹配日期类格式) if (cell.type === 'number' && cell.style?.numFmt?.match(/(dd|mm|yyyy)/i)) { // 手动转换Excel日期数字为JS Date const baseDate = new Date(1900, 0, 1); // 处理Excel的1900闰年bug:数字>59对应1900-03-01及以后,需减2天,否则减1天 const offsetDays = cell.value > 59 ? cell.value - 2 : cell.value - 1; return new Date(baseDate.getTime() + offsetDays * 86400000); } return cell.value; }); });
二、数字转日期的原生方案(无需额外库)
若只能拿到数字,用原生JS即可转换,核心处理Excel的日期起始规则和1900年闰年bug:
function excelNumToDate(excelNum) { const baseDate = new Date(1900, 0, 1); const offsetDays = excelNum > 59 ? excelNum - 2 : excelNum - 1; return new Date(baseDate.getTime() + offsetDays * 86400000); } // 使用示例: console.log(excelNumToDate(45618)); // 输出:2024-05-31T00:00:00.000Z
可选:第三方库简化转换
如果需要更丰富的日期处理能力,可使用以下库:
- date-fns(轻量级):
import { addDays } from 'date-fns'; const excelNumToDate = (num) => { const adjustment = num > 59 ? -2 : -1; return addDays(new Date(1900, 0, 1), num + adjustment); }; - moment.js(老牌全量库):
import moment from 'moment'; const excelNumToDate = (num) => { const adjustment = num > 59 ? -2 : -1; return moment('1900-01-01').add(num + adjustment, 'days').toDate(); };
内容的提问来源于stack exchange,提问作者kevin seda
相关产品推荐
相关产品推荐

