文件上传(一)
作者:杨锦龙时间:2026-04-27点击量:0次
1.HTML文件:import_data.html
<!-- index.php -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>旅游数据导入</title>
<style>
body { font-family: sans-serif; padding: 20px; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #ddd; border-radius: 5px; }
h1 { text-align: center; }
.form-group { margin-bottom: 15px; }
input[type="file"] { display: block; margin-top: 5px; }
input[type="submit"] { display: block; width: 100%; padding: 10px; background-color: #28a745; color: white; border: none; border-radius: 3px; cursor: pointer; }
input[type="submit"]:hover { background-color: #218838; }
.note { font-size: 0.9em; color: #666; margin-top: 10px; }
</style>
</head>
<body>
<div class="container">
<h1>旅游数据导入</h1>
<form action="{:url('saveImportData')}" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="csv_file">请选择 CSV 文件:</label>
<input type="file" name="csv_file" id="csv_file" required accept=".csv">
</div>
<div class="form-group">
<input type="submit" value="开始导入">
</div>
</form>
<p class="note">
<strong>注意:</strong>请确保CSV文件编码为 <strong>UTF-8 无BOM</strong> 格式。<br>
第一行应为表头,数据从第二行开始。
</p>
</div>
</body>
</html>2.后端处理文件saveImportData
public function saveImportData()
{
// 1. 获取上传的文件
$file = Request::instance()->file('csv_file'); // 对应前端 input name="csv_file"
if (empty($file)) {
return json(['code'=>105,'msg'=>'请选择上传的文件']);
}
// 2. 验证文件类型 (建议限制为 csv)
$info = $file->validate(['ext' => 'csv'])->move(WEB_PATH . 'runtime' . DS . 'excel');
if (!$info) {
return ['code'=>102,'msg'=>$file->getError()];
}
// 3. 获取文件完整路径
$filePath = $info->getSaveName();
$realPath = WEB_PATH . 'runtime' . DS . 'excel' . DS . $filePath;
// 4. 读取并处理 CSV 文件
$handle = fopen($realPath, 'r');
if (!$handle) {
return json(['code'=>103,'msg'=>'无法打开文件']);
}
$values = []; // 用于存储所有待插入的数据行
$headerSkipped = false;
$insertCount = 0;
$sort = $this->DbSy->getSort(41,'sort desc');
try {
// 开启事务,提高速度并保证数据一致性
Db::startTrans();
while (($row = fgetcsv($handle)) !== false) {
// 跳过表头(第一行)
if (!$headerSkipped) {
$headerSkipped = true;
continue;
}
// 过滤空行
if (empty(array_filter($row))) {
continue;
}
// --- 数据清洗与对应 ---
// 对应你提供的字段顺序
$data = [
'sb_date' => intval($row[0]),
'today_num' => intval($row[1]), // 当日接待游客人次
'gn_num' => intval($row[2]), // 国内游客
'wg_num' => intval($row[3]), // 外国游客
'gat_num' => intval($row[4]), // 港澳台游客
'today_fee' => floatval($row[5]), // 当日经营/营业收入
'ticket_fee' => floatval($row[6]), // 门票收入
'good_fee' => floatval($row[7]), // 商品收入
'food_fee' => floatval($row[8]), // 餐饮收入
'traffic_fee' => floatval($row[9]), // 交通收入
'hotel_fee' => floatval($row[10]), // 住宿收入
'act_fee' => floatval($row[11]),// 演艺收入
'play_fee' => floatval($row[12]),// 游乐收入
'other_fee' => floatval($row[13]), // 其他收入
'place_id' => floatval($row[14]) // 景区ID
];
$place = $this->DbSy->FindWhere(41,array('id'=>$data['place_id']));
$data['title'] = $place['title'];
$data['user_id'] = $this->user['id'];
$data['province'] = $place['province'];
$data['city'] = $place['city'];
$data['county'] = $place['county'];
$data['address'] = $place['address'];
$data['admin_type'] = 1;
$data['status'] = 1;
$data['sb_time'] = strtotime($data['sb_date']);
$data['number'] = date("YmdHis",time()).rand(100,999);
$data['inputtime'] = $data['updatetime'] = time();
$values[] = $data;
}
fclose($handle);
// 5. 批量插入数据
if (!empty($values)) {
// insertAll 是 TP5 的批量插入方法
// 第三个参数 true 表示严格检查字段,防止非法字段
Db::name('yjz_apply')->strict(false)->insertAll($values);
$insertCount = count($values);
}
// 提交事务
Db::commit();
// 可选:导入成功后删除文件
// unlink($realPath);
return json(['code'=>200,'msg'=>"导入成功,共导入 {$insertCount} 条数据"]);
} catch (\Exception $e) {
// 发生错误回滚事务
Db::rollback();
return json(['code'=>104,'msg'=>'导入失败:' . $e->getMessage()]);
}
}