如何在xlsx转JSON时保留DOB列的原始日期而非数字?
解决Excel日期转JSON时变为序列号的问题
你遇到的是Excel日期的典型问题:Excel里的日期本质是序列号(比如36986代表1900年日期系统下的2001年4月5日),而你开启了{raw: true}选项,xlsx库会直接返回这个原始序列号,而非解析后的日期字符串。下面提供两种可行的修复方案:
方法1:关闭raw模式,自动解析并格式化日期
去掉sheet_to_json的{raw: true}参数,让xlsx自动将日期单元格解析为Date对象,再格式化为你需要的DD-MM-YYYY格式:
static convertExcelFileToJsonUsingXlsxTrimSpaces = (path: string) => { const file = xlsx.readFile(path); const sheetNames = file.SheetNames; const totalSheets = sheetNames.length; const parsedData: any[] = []; // 自定义日期格式化函数,输出DD-MM-YYYY格式 const formatDate = (date: Date): string => { const day = String(date.getDate()).padStart(2, '0'); const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始,需加1 const year = date.getFullYear(); return `${day}-${month}-${year}`; }; for (let i = 0; i < totalSheets; i += 1) { // 移除raw: true,让xlsx自动解析日期为Date对象 const sheetData = xlsx.utils.sheet_to_json(file.Sheets[sheetNames[i]]); const processedData: any[] = []; sheetData.forEach((row: any) => { const processedRow: any = {}; Object.keys(row).forEach((key) => { const value = row[key]; // 判断是否为有效Date对象 if (value instanceof Date && !isNaN(value.getTime())) { processedRow[key] = formatDate(value); } else { // 非日期类型按原逻辑处理空值和去空格 processedRow[key] = value?.toString().trim() ?? ''; } }); processedData.push(processedRow); }); parsedData.push(...processedData); } return parsedData; };
方法2:保留raw模式,手动转换日期序列号
如果必须保留{raw: true}(比如需要保留其他单元格的原始数值),可以用xlsx内置的SSF.format函数,通过单元格格式判断并转换序列号:
static convertExcelFileToJsonUsingXlsxTrimSpaces = (path: string) => { const file = xlsx.readFile(path); const sheetNames = file.SheetNames; const totalSheets = sheetNames.length; const parsedData: any[] = []; for (let i = 0; i < totalSheets; i += 1) { const sheet = file.Sheets[sheetNames[i]]; // 保留raw模式获取原始数据 const sheetData = xlsx.utils.sheet_to_json(sheet, { raw: true }); const processedData: any[] = []; sheetData.forEach((row: any, rowIndex: number) => { const processedRow: any = {}; Object.keys(row).forEach((key) => { const value = row[key]; // 计算单元格的引用位置(Excel行索引从1开始) const cellRef = xlsx.utils.encode_cell({ r: rowIndex + 1, c: xlsx.utils.decode_col(key) }); const cell = sheet[cellRef]; // 判断是否为日期格式的数值单元格 if (typeof value === 'number' && cell && cell.t === 'n' && (cell.z?.includes('d') || cell.z?.includes('m') || cell.z?.includes('y'))) { // 转换为DD-MM-YYYY格式的日期字符串 processedRow[key] = xlsx.SSF.format('DD-MM-YYYY', value); } else { processedRow[key] = value.toString().trim(); } }); processedData.push(processedRow); }); parsedData.push(...processedData); } return parsedData; };
额外优化提示
如果你明确知道DOB列是固定的日期列,可以直接针对该列做转换,省去全局判断的开销:
// 在处理row的循环里 if (key === 'DOB' && typeof value === 'number') { processedRow[key] = xlsx.SSF.format('DD-MM-YYYY', value); } else { processedRow[key] = value.toString().trim(); }
内容的提问来源于stack exchange,提问作者Anuj Todankar
相关产品推荐
相关产品推荐

