# hyperf-import **Repository Path**: ysy-s87/hyperf-import ## Basic Information - **Project Name**: hyperf-import - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-09-05 - **Last Updated**: 2025-09-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Hyperf Import Package 一款专为 Hyperf 框架设计的轻量级导入包,支持 CSV、Excel(xlsx/xls)文件流式读取,内置进度跟踪与文件验证,无长生命周期状态残留问题。 ## 1. 功能特性 - 支持格式:CSV、Excel(.xlsx、.xls) - 流式读取:低内存占用,适配大文件(10万+行) - 进度跟踪:实时获取已读行数与总有效行数 - 灵活配置:支持编码、分隔符、多Sheet控制、流式阈值自定义等参数 - 智能/手动流式切换:文件超阈值自动启用流式驱动,也可手动强制触发 - 安全兼容:适配 Hyperf 长生命周期,无状态驱动设计 ## 2. 安装 通过 Composer 安装: ```bash composer require ysy/hyperf-import ``` ## 3. 快速使用 ### 3.1 自动流式读取(默认) 文件大小超过阈值(默认10MB)时自动启用流式驱动,无需额外配置: ```php importer->read( $file, skipHeader: true, options: [ 'encoding' => 'GBK', // CSV专属 'read_all_sheets' => false, // Excel专属 'streaming_threshold' => 20 * 1024 * 1024 // 自定义阈值20MB(可选) ], totalCount: $totalCount ); foreach ($generator as $item) { // 数据处理逻辑(同原示例) $data = $item['data']; if (empty($data['company']) || empty($data['order_num'])) continue; Db::table('orders')->insert([ 'company' => $data['company'], 'order_num' => $data['order_num'], 'total_amount' => $data['total_amount'] ?? 0, 'created_at' => date('Y-m-d H:i:s') ]); $successCount++; echo "已处理:{$item['current_count']} 条,总计:{$totalCount} 条\n"; } return [ 'code' => 200, 'msg' => '导入成功', 'data' => [ 'total' => $totalCount, 'success' => $successCount, 'failed' => $totalCount - $successCount ] ]; } catch (\Exception $e) { return [ 'code' => 500, 'msg' => "导入失败:{$e->getMessage()}", 'data' => ['total' => $totalCount, 'success' => $successCount] ]; } } } ``` ### 3.2 手动强制流式读取 无论文件大小,主动指定使用流式驱动(仅支持 xlsx/xls 格式): ```php #[PostMapping('/api/import/stream')] public function importStream(UploadedFileInterface $file) { try { $totalCount = 0; $successCount = 0; // 手动调用流式读取方法(仅xlsx/xls支持) $generator = $this->importer->readStream( $file, skipHeader: true, options: [ 'read_all_sheets' => false, // Excel专属配置 ], totalCount: $totalCount ); // 后续数据处理逻辑同自动模式 foreach ($generator as $item) { $data = $item['data']; // ...数据验证与入库 $successCount++; } return [ 'code' => 200, 'msg' => '流式导入成功', 'data' => ['total' => $totalCount, 'success' => $successCount] ]; } catch (\Exception $e) { return ['code' => 500, 'msg' => "流式导入失败:{$e->getMessage()}"]; } } ``` ## 4. 详细配置(重点:`options` 参数) `options` 支持**通用配置**与**驱动专属配置**,无需的配置可省略: ### 4.1 通用配置(所有格式适用) | 参数名 | 类型 | 默认值 | 说明 | 示例 | |---------------------|--------|-----------------|---------------------------------------|---------------------------------------| | `streaming_threshold` | int | 10*1024*1024 (10MB) | 触发自动流式读取的文件大小阈值(字节) | `'streaming_threshold' => 20971520`(20MB) | ### 4.2 CSV 文件专属配置 | 参数名 | 类型 | 默认值 | 说明 | 示例 | |--------------|--------|--------|---------------------------------------|-----------------------| | `encoding` | string | UTF-8 | CSV 文件编码(解决中文乱码) | `'encoding' => 'GBK'` | | `delimiter` | string | , | 字段分隔符(如制表符、分号) | `'delimiter' => "\t"` | | `enclosure` | string | " | 字段包围符(通常无需修改) | `'enclosure' => "'"` | ### 4.3 Excel 文件专属配置(xlsx/xls 通用) | 参数名 | 类型 | 默认值 | 说明 | 示例 | |------------------|---------|--------|---------------------------------------|-------------------------------| | `read_all_sheets`| bool | true | 是否读取所有 Sheet(false 只读第一个)| `'read_all_sheets' => false` | ## 5. 核心方法说明 ### 5.1 `Importer::read()` 方法(自动流式判断) | 参数名 | 类型 | 必需 | 说明 | |-----------------|-----------------------|------|---------------------------------------| | `$file` | UploadedFileInterface | 是 | Hyperf 上传文件对象 | | `$skipHeader` | bool | 否 | 是否跳过表头(默认 true) | | `$options` | array | 否 | 通用配置+驱动专属配置(见 4.x) | | `&$totalCount` | int | 否 | 引用传递:接收总有效行数(默认 0) | **返回值**:`\Generator` 迭代器,结构同下。 ### 5.2 `Importer::readStream()` 方法(手动流式读取) | 参数名 | 类型 | 必需 | 说明 | |-----------------|-----------------------|------|---------------------------------------| | `$file` | UploadedFileInterface | 是 | Hyperf 上传文件对象 | | `$skipHeader` | bool | 否 | 是否跳过表头(默认 true) | | `$options` | array | 否 | 仅支持对应驱动的专属配置(见 4.3) | | `&$totalCount` | int | 否 | 引用传递:接收总有效行数(默认 0) | **返回值**:`\Generator` 迭代器,每次迭代返回: ```php [ 'sheet_name' => 'Sheet1', // 工作表名(CSV无此场景,流式仅支持Excel) 'row_index' => 7, // 原始行号(含表头) 'data' => ['company' => 'xxx', 'order_num' => 'xxx'], // 关联数组格式数据 'current_count' => 300 // 已读取的有效行数(实时进度) ] ``` **注意**:`readStream()` 仅支持 `xlsx/xls` 格式,调用 CSV 会抛异常。 ## 6. 文件验证规则 包内置 `FileValidator` 自动验证以下规则: - 支持扩展名:`csv`、`xlsx`、`xls`(其他格式抛异常) - 文件大小:默认无硬限制(仅影响流式触发逻辑,可自定义阈值) ## 7. 常见问题 ### Q1:CSV 中文乱码怎么办? A:在 `options` 中指定 `encoding` 为文件实际编码(如 GBK、GB2312)。 ### Q2:如何只读取 Excel 的某个 Sheet? A:设置 `options['read_all_sheets'] = false`,仅读取第一个 Sheet;如需指定特定 Sheet,需自定义 ExcelDriver。 ### Q3:大文件导入内存溢出? A:包默认按 10MB 阈值自动启用流式读取(逐行处理);也可通过 `readStream()` 手动强制流式处理,配合批量入库(如每 1000 行批量插入)优化性能。 ### Q4:如何强制使用流式读取? A:调用 `readStream()` 方法(仅支持 xlsx/xls),不受文件大小阈值限制。 ### Q5:如何修改流式读取的触发阈值? A:在 `options` 中配置 `streaming_threshold`(单位:字节),如 `20*1024*1024` 表示 20MB 触发。