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

Laravel Excel导入时日期与长数字格式异常问题求助

Laravel Excel 导入保持原始格式解决方案

问题分析

导入时出现两类格式异常:

  • 日期2074-08-15被解析为数字63781(Excel内部日期序列号)
  • 银行账号6013820134824000000被转为科学计数法6.013820134824E+18

解决步骤

1. 恢复日期原始格式

Excel会将日期存储为自1900年起的天数序列号,需手动转换回目标格式。修改AllowanceImport类的model方法,利用PhpSpreadsheet工具处理:

use PhpOffice\PhpSpreadsheet\Shared\Date;

public function model(array $row)
{
    $dateOfRegistration = '';
    if (isset($row['date_of_registration'])) {
        // 区分是数字序列号还是原始日期字符串
        if (is_numeric($row['date_of_registration'])) {
            // 转换为DateTime对象后格式化
            $dateObject = Date::excelToDateTimeObject($row['date_of_registration']);
            $dateOfRegistration = $dateObject->format('Y-m-d');
            // 若需转换为尼泊尔历(BS),需额外引入历法转换库(如kbsali/nepal-date)处理
        } else {
            $dateOfRegistration = $row['date_of_registration'];
        }
    }

    return new Allowance([
        'date_of_registration' => $dateOfRegistration,
        'bank_account_no'      => isset($row['bank_account_no']) ? $row['bank_account_no'] : '',
    ]);
}

2. 修复银行账号科学计数法问题

长数字被Excel自动转为科学计数法,可通过两种方式解决:

方案一:强制按文本格式读取列

在AllowanceImport类中实现WithColumnFormatting接口,指定银行账号列为文本格式:

use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;

class AllowanceImport implements WithColumnFormatting // 保留原有的其他接口
{
    // 定义列格式,假设银行账号在B列,根据实际列调整
    public function columnFormats(): array
    {
        return [
            'B' => NumberFormat::FORMAT_TEXT,
        ];
    }

    public function model(array $row)
    {
        // 此时$row['bank_account_no']已为原始字符串
        return new Allowance([
            'date_of_registration' => isset($row['date_of_registration']) ? $row['date_of_registration'] : '',
            'bank_account_no'      => isset($row['bank_account_no']) ? $row['bank_account_no'] : '',
        ]);
    }
}

方案二:手动转换科学计数法字符串

若无法提前指定列格式,可在model方法中直接处理:

public function model(array $row)
{
    $bankAccountNo = '';
    if (isset($row['bank_account_no'])) {
        $account = $row['bank_account_no'];
        // 判断是否为科学计数法格式
        if (strpos($account, 'E') !== false) {
            // 转换为完整数字字符串
            $bankAccountNo = rtrim(rtrim(sprintf('%.0f', $account), '0'), '.');
        } else {
            $bankAccountNo = $account;
        }
    }

    return new Allowance([
        'date_of_registration' => isset($row['date_of_registration']) ? $row['date_of_registration'] : '',
        'bank_account_no'      => $bankAccountNo,
    ]);
}

注意事项

  • 数据库中银行账号建议存储为varchar类型,避免数字类型导致的精度丢失
  • 若处理尼泊尔历日期,需引入专门的历法转换库实现序列号到BS日期的转换

内容的提问来源于stack exchange,提问作者Umesh Kumar Yadav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 22:48:13