在ThinkPHP项目开发中,数据批量导入是非常实用的功能,能够大幅减少手动录入数据的工作量,常见的使用场景包括批量导入用户信息、商品库存、业务台账等。实现该功能通常需要结合Excel文件处理库,完成文件上传、数据解析、校验和批量入库的全流程。

前置准备
首先需要在项目中安装处理Excel的依赖,这里推荐使用PhpSpreadsheet,通过Composer执行安装命令:
composer require phpoffice/phpspreadsheet
同时需要在数据库创建对应的数据表,本文以用户表user为例,表结构包含id、username、phone、create_time字段。
实现步骤
1. 文件上传处理
首先编写文件上传逻辑,接收前端上传的Excel文件,存储到服务器指定目录,代码示例如下:
<?php
namespace app\controller;
use think\Request;
use think\facade\Filesystem;
class Import extends BaseController
{
// 上传Excel文件
public function uploadExcel(Request $request)
{
$file = $request->file('excel_file');
// 验证文件类型和大小
$validate = [
'fileSize' => 1024 * 1024 * 10, // 最大10M
'fileExt' => 'xls,xlsx'
];
$result = validate($validate)->check(['excel_file' => $file]);
if (!$result) {
return json(['code' => 0, 'msg' => '文件格式或大小不符合要求']);
}
// 保存到本地
$saveName = Filesystem::disk('public')->putFile('excel', $file);
$filePath = public_path() . 'storage/' . $saveName;
return json(['code' => 1, 'msg' => '上传成功', 'file_path' => $filePath]);
}
}2. 解析Excel数据
上传成功后,使用PhpSpreadsheet读取Excel内容,解析出需要导入的数据:
use PhpOffice\PhpSpreadsheet\IOFactory;
// 解析Excel数据
public function parseExcel($filePath)
{
// 加载Excel文件
$reader = IOFactory::createReaderForFile($filePath);
$spreadsheet = $reader->load($filePath);
// 获取第一个工作表
$worksheet = $spreadsheet->getActiveSheet();
$highestRow = $worksheet->getHighestRow(); // 最大行数
$importData = [];
// 从第二行开始读取,第一行为表头
for ($row = 2; $row <= $highestRow; $row++) {
$username = $worksheet->getCell('A' . $row)->getValue();
$phone = $worksheet->getCell('B' . $row)->getValue();
if (!empty($username) && !empty($phone)) {
$importData[] = [
'username' => $username,
'phone' => $phone,
'create_time' => time()
];
}
}
return $importData;
}3. 数据校验
解析出的数据需要先进行校验,避免无效数据或重复数据入库,常见校验规则如下:
- 校验手机号格式是否合法
- 校验手机号是否已存在
- 校验用户名是否为空
// 数据校验逻辑
public function validateData($dataList)
{
$validData = [];
$userModel = new \app\model\User();
foreach ($dataList as $item) {
// 校验手机号格式
if (!preg_match('/^1[3-9]\d{9}$/', $item['phone'])) {
continue;
}
// 校验手机号是否重复
$exist = $userModel->where('phone', $item['phone'])->find();
if ($exist) {
continue;
}
$validData[] = $item;
}
return $validData;
}4. 批量入库
校验通过的validData使用ThinkPHP的saveAll方法实现批量插入,提升入库效率:
// 批量入库
public function batchImport()
{
$filePath = input('file_path');
if (empty($filePath)) {
return json(['code' => 0, 'msg' => '请先上传文件']);
}
// 解析数据
$importData = $this->parseExcel($filePath);
if (empty($importData)) {
return json(['code' => 0, 'msg' => '未读取到有效数据']);
}
// 校验数据
$validData = $this->validateData($importData);
if (empty($validData)) {
return json(['code' => 0, 'msg' => '没有符合要求的导入数据']);
}
// 批量入库
$userModel = new \app\model\User();
$result = $userModel->saveAll($validData);
if ($result) {
return json(['code' => 1, 'msg' => '成功导入' . count($validData) . '条数据']);
} else {
return json(['code' => 0, 'msg' => '导入失败']);
}
}注意事项
实际开发中还需要注意几个问题:如果导入数据量特别大,建议分批次解析入库,避免一次性读取过多数据导致内存溢出;导入前可以先备份原有数据,防止误操作覆盖有效数据;可以在前端增加导入进度提示,提升用户使用体验。以上流程就是ThinkPHP实现批量数据导入的完整方法,可根据实际业务需求调整校验规则和字段映射逻辑。