Laravel 6中如何将TXT文件指定字段数据导入MySQL
Laravel 6 批量导入TXT数据到MySQL解决方案
问题分析
你的现有代码逻辑是按行分割后每5行组合成一条记录,但实际目标数据格式是每行包含完整的4个字段键值对(如atm_id = AT8502 atm_name = example ip = 10.51.7.50 agent_connection = complete),因此需要调整解析逻辑,直接从每行提取对应字段值。
修正后的实现代码
public function importTxt(Request $request) { // 验证上传文件 $request->validate([ 'file' => 'required|file|mimes:txt', ]); $file = $request->file('file'); $filePath = $file->getRealPath(); $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); // 过滤出包含目标字段的有效行(可根据需求替换为找含'PAR'的行) $validLines = array_filter($lines, function ($line) { return strpos($line, 'atm_id') !== false && strpos($line, 'ip') !== false; }); $importData = []; // 正则匹配每行的字段值,适配字段值不含空格的场景 $pattern = '/atm_id = (\S+) atm_name = (\S+) ip = (\S+) agent_connection = (\S+)/'; foreach ($validLines as $line) { if (preg_match($pattern, trim($line), $matches)) { $importData[] = [ 'atm_id' => $matches[1], 'name_atm' => $matches[2], // 对应你定义的字段名 'ip' => $matches[3], 'agent_connection' => $matches[4], 'created_at' => now(), 'updated_at' => now(), ]; } } // 批量插入到数据库(替换为你的实际模型类) if (!empty($importData)) { \App\Models\Atm::insert($importData); return redirect()->back()->with('success', '数据导入成功'); } return redirect()->back()->with('error', '未找到有效数据'); }
关键说明
- 文件读取优化:用
file()函数直接读取文件为数组,同时忽略空行和换行符,比file_get_contents+explode更高效简洁。 - 有效行过滤:通过判断行内是否包含核心字段,快速跳过无关的头部或注释行;如果需要保留含'PAR'的行,把过滤逻辑改回
return strpos($item,'PAR') !== false;即可。 - 正则解析:用正则精准匹配每行的键值对,
\S+匹配非空白字符;如果字段值包含空格,可修改正则为/atm_id = (.+?) atm_name = (.+?) ip = (.+?) agent_connection = (.+)/,并对匹配结果做trim()处理。 - 批量插入:使用Laravel的
insert()方法一次性插入多条数据,比循环save()性能提升明显;如果你的表没有created_at/updated_at字段,可直接移除这两个键值。
注意事项
- 确保数据库表字段与
$importData中的键名完全对应。 - 可根据TXT文件的实际格式调整正则表达式,适配不同的字段分隔或值的格式。
内容的提问来源于stack exchange,提问作者Yahya Zakaria
相关产品推荐
相关产品推荐

