You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动