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
相关产品推荐
相关产品推荐

