You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 02:05:42