You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHPExcel Codeigniter-4用SpreadsheetReader_XLSX无法上传超5万行Excel问题

问题根因定位

小文件导入正常、大文件无报错失败基本都是运行配置限制、内存溢出、读取逻辑不合理三类问题,按以下步骤排查修复即可:

具体修复方案

1. 调整PHP运行参数

优先排查PHP配置的资源限制,可先在控制器导入方法的最开头动态添加配置:

ini_set('memory_limit', '1G'); // 内存限制调整为1G,可根据实际情况再放大
set_time_limit(0); // 取消执行时间限制

如果动态配置不生效(php-fpm模式下部分参数不允许动态修改),直接修改php.ini文件的以下参数:

  • memory_limit >= 1G
  • max_execution_time >= 300 或设为0
  • post_max_size >= 100M
  • upload_max_filesize >= 100M
  • max_input_time >= 300 或设为-1
    修改后重启php-fpm或apache/nginx服务生效。

2. 优化Excel读取逻辑

不要一次性把整个Excel文件加载到内存,改用逐行读取+分批插入的方案,示例代码如下:

// 假设你已经通过CI4的上传类拿到了文件路径 $filePath
$reader = new \SpreadsheetReader_XLSX($filePath);
$batchInsertData = [];
$batchSize = 1000; // 每1000行批量插入一次,可根据实际调整
$db = \Config\Database::connect();

foreach ($reader as $row) {
    // 跳过表头(如果有表头的话加这行)
    if ($reader->key() == 0) continue;

    // 处理当前行数据,不要存到全局大数组中
    $rowData = [
        'column1' => $row[0],
        'column2' => $row[1],
        // 对应你的40列字段依次映射
    ];
    $batchInsertData[] = $rowData;

    // 凑够批量大小就写入数据库,清空临时数组释放内存
    if (count($batchInsertData) == $batchSize) {
        $db->table('你的表名')->insertBatch($batchInsertData);
        $batchInsertData = [];
    }
}

// 插入最后剩余的不足批次大小的数据
if (!empty($batchInsertData)) {
    $db->table('你的表名')->insertBatch($batchInsertData);
}

注意:读取时不要开启单元格样式、公式解析功能,仅读取纯文本值可减少80%以上的内存占用

3. 调整框架与数据库配置

  • 打开CI4的app/Config/Upload.php,把$maxSize参数调整到和PHP上传限制一致,避免大文件被框架上传验证拦截。
  • 调整MySQL的max_allowed_packet参数到64M以上,避免批量插入时数据包过大被数据库拒绝。
  • 排查时可临时开启PHP报错显示,确认具体报错原因:
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    
可选优化方案

如果上述方案还是达不到性能要求,可替换SpreadsheetReader_XLSX为更轻量的逐行读取库,内存占用可控制在10M以内,完全不受文件大小限制。

内容的提问来源于stack exchange,提问作者Shiv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 21:15:00