PHP Spreadsheet读取Excel单元格循环报错,数组无法填充数据
PHP Spreadsheet提取Excel数据报错及修正方案
你的Excel结构显示,数据行从第8行开始,A列对应商品编码、B列对应数量、C列对应价格,上方第3、5行还有客户编码、目的地编码、配送备注等单独字段。结合你给出的代码,问题出在这几个地方:
- 遍历逻辑混乱:用
foreach($worksheet as $data)遍历工作表时,$data本身就是每行的Row对象,你同时手动维护$row变量会导致行号重复计数,直接跳过第8行的数据,甚至取到不存在的单元格,触发数组键错误。 - 数组覆盖问题:
$data_detail是单个关联数组,每次循环会覆盖之前的字段值,根本存不下多行明细数据。 - 错误调用方法:循环里的
$data->getActiveSheet()完全错误,Row对象没有这个方法,这也是报错的直接原因之一。
下面是修正后的代码:
$request->validate([ 'uploaded_file' => 'required|file|mimes:xls,xlsx' ]); $excel_file = $request->file('uploaded_file'); $file = IOFactory::load($excel_file->getRealPath()); $worksheet = $file->getActiveSheet(); $data_grid = []; // 改为二维数组,用于存储多行明细数据 $data_detail = []; // 提取顶部固定字段 $data_grid['codice_cliente'] = $worksheet->getCell('B3')->getValue(); $data_grid['codice_destinazione'] = $worksheet->getCell('G3')->getValue(); $data_grid['data_ordine'] = '2022-07-15 15:32:04'; $data_grid['data_richiesta'] = '2022-06-15'; $data_grid['note_consegna'] = $worksheet->getCell('G5')->getValue(); $data_grid['id_agente'] = Auth::user()->id; $data_grid['canale'] = 'B'; $data_grid['tipologia'] = 'O'; $data_grid['edi_id'] = 1; $data_grid['edi_company'] = 'C'; $data_grid['edi_doctype'] = 'D'; $data_grid['jde_id'] = 2; $data_grid['jde_company'] = 'E'; $data_grid['jde_doctype'] = 'F'; $data_grid['stato_ordine'] = 1; $data_grid['total_order'] = 99.99; // 从第8行开始遍历数据行,获取最大行号避免遍历空行 $startRow = 8; $highestRow = $worksheet->getHighestRow(); for ($row = $startRow; $row <= $highestRow; $row++) { // 每行创建新的明细数组,避免覆盖之前的数据 $rowDetail = [ 'nr_riga' => 50, // 如果需要递增,可改为 50 + ($row - $startRow) 'codice_articolo' => $worksheet->getCell("A$row")->getValue(), 'quantita' => $worksheet->getCell("B$row")->getValue(), 'prezzo' => $worksheet->getCell("C$row")->getValue() ]; // 将当前行明细添加到二维数组 $data_detail[] = $rowDetail; }
关键修正点说明:
- 改用
for循环直接控制行号范围,从第8行开始到工作表最大行结束,逻辑更清晰,不会出现行号混乱。 $data_detail改为二维数组,每次循环生成独立的$rowDetail并推入数组,确保所有行数据都能保存。- 移除错误的
$data->getActiveSheet()调用,统一使用已定义的$worksheet操作单元格。 - 如果
nr_riga需要随行数递增(比如第8行是50,第9行是51),把对应代码改成'nr_riga' => 50 + ($row - $startRow)即可。
内容的提问来源于stack exchange,提问作者user18182496
相关产品推荐
相关产品推荐

