model = new \app\admin\model\Records; } /** * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法 * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑 * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改 */ /** * 处理Excel文件上传并获取数据,然后保存到数据库 */ public function getxlsxdata(){ // 处理POST请求 if (!$this->request->isPost()) { return json(['code' => 0, 'msg' => '请求方式错误,需要POST请求']); } // 获取上传的文件 $file = $this->request->file('file'); if (!$file) { return json(['code' => 0, 'msg' => '请选择要上传的文件']); } try { // 验证文件类型 $info = $file->validate(['ext' => 'xlsx,xls'])->move(ROOT_PATH . 'public/uploads/excel/'); if (!$info) { return json(['code' => 0, 'msg' => '文件验证失败: ' . $file->getError()]); } // 获取文件路径 $fullPath = ROOT_PATH . 'public/uploads/excel/' . $info->getSaveName(); // 读取Excel文件内容 $excelData = []; // 根据文件扩展名选择相应的读取方法 $ext = strtolower(pathinfo($fullPath, PATHINFO_EXTENSION)); try { // 检查是否安装了PhpSpreadsheet if (class_exists('\PhpOffice\PhpSpreadsheet\IOFactory')) { $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader(ucfirst($ext)); $spreadsheet = $reader->load($fullPath); $sheet = $spreadsheet->getActiveSheet(); $excelData = $sheet->toArray(); } // 检查是否安装了PHPExcel else if (class_exists('\PHPExcel_IOFactory')) { $reader = \PHPExcel_IOFactory::createReader(ucfirst($ext)); $excel = $reader->load($fullPath); $sheet = $excel->getActiveSheet(); $excelData = $sheet->toArray(); } // 如果都没有,返回文件已上传但无法解析的信息 else { return json([ 'code' => 0, 'msg' => '文件上传成功,但服务器缺少Excel解析库', 'data' => ['file_name' => $info->getFilename()] ]); } } catch (\Exception $e) { // 清理上传的文件 @unlink($fullPath); return json(['code' => 0, 'msg' => '解析Excel文件时出错:' . $e->getMessage()]); } // 清理上传的临时文件 @unlink($fullPath); // 检查数据是否为空 if (count($excelData) < 2) { return json(['code' => 0, 'msg' => 'Excel文件数据为空或只有表头', 'data' => ['file_name' => $info->getFilename()]]); } // 获取表头(第一行) $headers = $excelData[0]; // 定义表头与数据库字段的映射关系 $fieldMapping = [ '电子耳标号' => 'rfid', '国标号' => 'number', '出生日期' => 'birthDate', '品类' => 'category', '性别' => 'gender', '日龄' => 'dayage' ]; // 准备要插入数据库的数据 $insertData = []; $successCount = 0; $errorCount = 0; $errorMessages = []; // 处理数据行(从第二行开始) for ($i = 1; $i < count($excelData); $i++) { $rowData = $excelData[$i]; $record = []; $hasData = false; // 构建关联数组 for ($j = 0; $j < count($headers); $j++) { $header = $headers[$j]; $value = isset($rowData[$j]) ? trim($rowData[$j]) : ''; // 如果表头在映射中存在,添加到记录中 if (isset($fieldMapping[$header])) { $field = $fieldMapping[$header]; // 特殊字段处理 if ($field === 'birthDate' && !empty($value)) { // 尝试转换日期格式,只保留日期部分 $timestamp = strtotime($value); if ($timestamp) { $record[$field] = date('Y-m-d', $timestamp); } else { $record[$field] = $value; // 保持原样 } } else { $record[$field] = $value; } if (!empty($value)) { $hasData = true; } } } // 如果记录有数据,添加创建时间和更新时间 if ($hasData) { // $record['createtime'] = time(); // $record['updatetime'] = time(); $insertData[] = $record; $successCount++; } else { $errorCount++; $errorMessages[] = "第" . ($i + 1) . "行数据为空"; } } // 准备导入进度数据 $totalRows = count($excelData) - 1; // 减去表头 $totalInsertData = count($insertData); $insertedCount = 0; $batchSize = 50; // 每批插入的数据量 $duplicateCount = 0; // 重复数据计数 // 打印要插入的数据(仅开发环境使用) if (!empty($insertData)) { // 打印数据 // echo "
";
// echo "要插入的数据总量: " . count($insertData) . " 条\n";
// print_r(array_slice($insertData, 0, 5));
// echo "";
// 提取所有rfid值用于检查重复
$rfidValues = array_column($insertData, 'rfid');
// 查询数据库中已存在的rfid值
$existingRfids = Db::name('new_records')
->where('rfid', 'in', $rfidValues)
->column('rfid');
// 过滤掉重复数据,只保留不存在的记录
$uniqueData = [];
foreach ($insertData as $record) {
if (!in_array($record['rfid'], $existingRfids)) {
$uniqueData[] = $record;
} else {
$duplicateCount++;
$errorMessages[] = "重复数据,rfid: " . $record['rfid'] . " 已存在,跳过插入";
}
}
// 如果有唯一数据需要插入
if (!empty($uniqueData)) {
// 将数据分成多批
$batches = array_chunk($uniqueData, $batchSize);
foreach ($batches as $batch) {
try {
$result = Db::name('new_records')->insertAll($batch);
$insertedCount += $result;
} catch (\Exception $e) {
// 记录错误
$errorCount++;
$errorMessages[] = "插入数据时出错:" . $e->getMessage();
}
}
}
}
// 返回成功信息
return json([
'code' => 1,
'msg' => '文件上传并保存成功!',
'data' => [
'file_name' => $info->getFilename(),
'total_rows' => $totalRows,
'total_data_rows' => $totalInsertData,
'inserted_count' => $insertedCount,
'success_count' => $insertedCount,
'duplicate_count' => $duplicateCount,
'error_count' => $errorCount,
'error_messages' => $errorMessages
]
]);
} catch (\Exception $e) {
return json(['code' => 0, 'msg' => '处理文件时出错:' . $e->getMessage()]);
}
}
}