PHP导入非标准格式HTML Excel文件至数据库的最佳实践及指定列提取方案
嘿,我来帮你搞定这个问题!首先咱们聊聊把这种非标准HTML格式的Excel导入数据库的最佳实践,再修改你现有的代码来只保留第二、第三列。
PHP导入非标准Excel(HTML格式)的最佳实践
- 别自己造轮子,用成熟库:正则处理HTML表格很容易踩坑(比如遇到嵌套标签、
colspan/rowspan直接歇菜),推荐用PhpSpreadsheet(原PHPExcel的升级版本),它能完美解析这种伪装成HTML的Excel文件,还能自动处理编码、单元格格式这些细节。 - 先清洗再入库:导入前一定要验证数据——比如第二列是数字,要确保格式正确;阿拉伯语文本要确认UTF-8编码一致;还要去掉多余的空白字符,避免脏数据进入数据库。
- 批量插入更高效:别一条一条往数据库插,攒几十上百条用
INSERT INTO table (col1, col2) VALUES (val1,val2), (val3,val4)...这种批量语句,能大幅减少数据库连接开销。 - 错误处理不能少:文件上传失败、读取出错、数据库插入失败这些情况都要捕获,最好记录日志,出问题了好排查。
- 用事务保数据一致:如果导入多条数据,开启数据库事务,要是中间某条出错直接回滚,避免一半数据成功一半失败的尴尬情况。
修改你的现有代码:只保留第二、第三列
你的正则提取思路没问题,但需要调整一下,只抓取索引为1和2的列(数组从0开始,第二列对应索引1,第三列对应索引2)。修改后的代码如下:
$file = $_FILES["file"]["tmp_name"]; $file_open = fopen($file,"r"); $html = file($file); preg_match_all('#<tr[^>]*>(.*?)</tr>#is', $html[0], $lines); $result = array(); foreach ($lines[1] as $k => $line) { preg_match_all('#<td[^>]*>(.*?)</td>#is', $line, $cell); $filteredCells = array(); // 只保留第二列(索引1)和第三列(索引2),先判断是否存在避免数组越界 if(isset($cell[1][1])) { $filteredCells[] = trim($cell[1][1]); } if(isset($cell[1][2])) { $filteredCells[] = trim($cell[1][2]); } // 只加入非空的行数据 if(!empty($filteredCells)) { $result[$k] = $filteredCells; } } var_dump($result);
代码修改说明:
- 不再遍历所有单元格,直接定位到需要的第二、第三列
- 增加
isset判断,避免某行缺少列导致数组越界报错 - 只把非空的过滤结果加入最终数组,去掉无效行
更推荐的方案:用PhpSpreadsheet处理
虽然修改正则能解决当前问题,但如果以后遇到更复杂的表格(比如合并单元格、隐藏列),正则就不好使了。用PhpSpreadsheet的方案更稳妥:
首先通过Composer安装依赖:composer require phpoffice/phpspreadsheet
然后用下面的代码:
require 'vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\IOFactory; $file = $_FILES["file"]["tmp_name"]; // 自动识别文件格式(包括这种HTML格式的Excel) $spreadsheet = IOFactory::load($file); $worksheet = $spreadsheet->getActiveSheet(); $result = array(); // 遍历每一行 foreach ($worksheet->getRowIterator() as $row) { $cellIterator = $row->getCellIterator(); $cellIterator->setIterateOnlyExistingCells(false); // 遍历所有单元格,包括空单元格 $rowData = array(); $columnNum = 0; foreach ($cellIterator as $cell) { $columnNum++; // 只取第二列(B列,对应数字2)和第三列(C列,对应数字3) if($columnNum === 2 || $columnNum === 3) { $rowData[] = trim($cell->getValue()); } } if(!empty($rowData)) { $result[] = $rowData; } } var_dump($result);
这个方法的优势在于:完全不用自己处理HTML解析的细节,库会自动搞定编码、单元格格式,扩展性极强,以后要加其他列或者处理复杂表格都很容易。
内容的提问来源于stack exchange,提问作者P.Coder




