PHP导入Excel到MySQL时如何从E4单元格开始读取指定列数据
问题描述
需要导入的目标Excel文件示例
目前已实现PHP将Excel文件导入MySQL的基础功能,需要调整代码满足以下需求:
- 排除无关行,不从A1单元格起始导入,从E4单元格位置开始读取数据
- 仅提取指定列的数据
现有参考代码如下:
if(isset($_POST['import_mandate'])) { $filename = $_FILES['import-file']['name']; $file_ext = pathinfo($filename, PATHINFO_EXTENSION); $allowed_ext = ['Xls','xlsx','csv']; if(in_array($file_ext, $allowed_ext)) { $inputFileName = $_FILES['import-file']['tmp_name']; /** Load $inputFileName to a Spreadsheet object **/ $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inputFileName); $data = $spreadsheet->getActiveSheet()->toArray(); foreach($data as $row) { $nycid = $row['4']; $lastname = $row['5']; $firstname = $row['6']; $grade = $row['10']; $adbn = $row['12']; $pldbn = $row['13']; $stype = $row['18']; $mb = $row['19']; $language = $row['20']; $ig = $row['21']; $gsize = $row['22']; $freq = $row['23']; $dur = $row['24']; $provider = $row['28']; $mandatequery = "INSERT INTO mandates (nycid, lastname, firstname, grade, adbn, pldbn, stype, mb, language, ig, gsize, freq, dur, provider) VALUES ('$nycid', '$lastname', '$firstname', '$grade', '$adbn', '$pldbn', '$stype', '$mb', '$language', '$ig', '$gsize', '$freq', '$dur', '$provider')"; $query_run = mysqli_query($con,$mandatequery); $msg = true; } if(isset($msg)) { $_SESSION['message'] = "Successfully Imported!"; header("Location: mandates.php"); exit(0); } else { $_SESSION['message'] = "Not Imported!"; header("Location: mandates.php"); exit(0); } } else { $_SESSION['message'] = "Invalid File!"; header("Location: mandates.php"); exit(0);`enter code here` }
需要实现的核心目标:仅从Excel文件的E4单元格开始读取所需目标数据。
调整方案
PhpSpreadsheet默认toArray()返回的数组以0为起始行索引,对应Excel第1行;以0为起始列索引,对应A列。不需要修改核心读取逻辑,只需要在遍历阶段跳过前3行无关内容,即可从第4行(E4所在行)开始处理数据,原有列的索引对应关系完全不需要改动。
本次调整同时修复原代码的几个问题:
- 原文件扩展名判断大小写敏感,统一转小写后比对,避免
.xls这类小写后缀的合法文件被拦截 - 新增空行过滤逻辑,无有效NYCID的空行不会被插入数据库
- 修正导入成功标识的初始化逻辑,避免无数据插入时也提示导入成功
- 移除代码中残留的无效字符
enter code here
调整后的完整代码如下:
if(isset($_POST['import_mandate'])) { $filename = $_FILES['import-file']['name']; $file_ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); $allowed_ext = ['xls','xlsx','csv']; if(in_array($file_ext, $allowed_ext)) { $inputFileName = $_FILES['import-file']['tmp_name']; /** Load $inputFileName to a Spreadsheet object **/ $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inputFileName); $data = $spreadsheet->getActiveSheet()->toArray(); $msg = false; foreach($data as $rowIndex => $row) { // 跳过前3行(对应Excel第1-3行无关内容),从第4行开始处理 if($rowIndex < 3){ continue; } // 过滤空行:NYCID为空则跳过当前行 $nycid = trim($row[4]); if(empty($nycid)){ continue; } $lastname = $row[5]; $firstname = $row[6]; $grade = $row[10]; $adbn = $row[12]; $pldbn = $row[13]; $stype = $row[18]; $mb = $row[19]; $language = $row[20]; $ig = $row[21]; $gsize = $row[22]; $freq = $row[23]; $dur = $row[24]; $provider = $row[28]; $mandatequery = "INSERT INTO mandates (nycid, lastname, firstname, grade, adbn, pldbn, stype, mb, language, ig, gsize, freq, dur, provider) VALUES ('$nycid', '$lastname', '$firstname', '$grade', '$adbn', '$pldbn', '$stype', '$mb', '$language', '$ig', '$gsize', '$freq', '$dur', '$provider')"; $query_run = mysqli_query($con,$mandatequery); if($query_run){ $msg = true; } } if($msg) { $_SESSION['message'] = "Successfully Imported!"; header("Location: mandates.php"); exit(0); } else { $_SESSION['message'] = "Not Imported!"; header("Location: mandates.php"); exit(0); } } else { $_SESSION['message'] = "Invalid File!"; header("Location: mandates.php"); exit(0); } }
可选优化(大文件场景推荐)
如果导入的Excel文件体积较大,可以不用读取全量表格数据,直接通过rangeToArray()指定读取范围为E4到表格最后一个有数据的单元格,减少内存占用。注意使用该方法时,返回的数组列索引从E列开始以0计数,原有代码里的列索引需要统一减4即可,例如原$row[4](E列)对应新数组的$row[0],原$row[5](F列)对应$row[1],以此类推。
内容的提问来源于stack exchange,提问作者Nine Delos Reyes
相关产品推荐
相关产品推荐

