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

Laravel+Vue导出Excel遇问题:foreach循环报错或返回异常值

Laravel+Vue导出预订数据到Excel遍历报错排查

场景概述

基于Laravel后端、Vue前端的项目,需导出预订数据到Excel。前端通过带参数的href调用导出接口,使用JSON.stringify处理数据后URL编码正常,但在后端导出的Excel视图中遍历数据时,出现两种异常:要么返回1,要么提示错误foreach() argument must be of type array|object, null given。

相关代码片段

前端调用代码

<a class="btn btn-primary" target="_blank" :href="server + '/admin/booking-status-report/excel?method=export'+ '&data=' + JSON.stringify(this.bookings)">Print</a>

注:未使用JSON.stringify时,URL中data参数会显示为[object%20Object],[object%20Object],使用后编码格式正常。

后端Controller代码

public function export(Request $request) 
{
    $dataParam = $request->query('data');

    if (!empty($dataParam)) {
        $data = json_decode(urldecode($dataParam), true);
        return Excel::store(new BookingStatusExport($data), 'booking-status-report.xlsx');
    } else {
        return response()->json(['error' => 'Data parameter is missing'], 400);
    }
}

导出类BookingStatusExport代码

private $data;

public function __construct($data)
{
    $this->data = $data;
}
public function view(): View
{
    return view('excel.booking-status-report', [
        'data' => $this->data
    ]);
}

视图遍历代码

@foreach($data as $d)
    <tr>
        <td>{{ $d['trip_date'] }}</td>
        <td>{{ $d['trip_time'] }}</td>
        <td>{{ $d['invoice'] }}</td>
        <td>{{ $d['customer_name'] }}</td>
    </tr>  
@endforeach

排查与修复方案

1. 修正JSON解码逻辑

Laravel的$request->query()已经自动完成URL解码,手动调用urldecode()会导致二次解码,破坏原始JSON结构,导致json_decode返回null。修改Controller代码:

// 移除urldecode,直接解码
$data = json_decode($dataParam, true);

同时前端建议对JSON字符串额外做URL编码,避免特殊字符干扰:

:href="server + '/admin/booking-status-report/excel?method=export&data=' + encodeURIComponent(JSON.stringify(this.bookings))"

2. 确保导出类实现正确接口

使用Maatwebsite/Laravel-Excel时,导出类必须实现FromView接口,否则框架无法识别视图导出逻辑:

use Maatwebsite\Excel\Concerns\FromView;
use Illuminate\Contracts\View\View;

class BookingStatusExport implements FromView
{
    private $data;

    public function __construct($data)
    {
        // 兜底空数组,避免null传入
        $this->data = is_array($data) ? $data : [];
    }

    public function view(): View
    {
        return view('excel.booking-status-report', [
            'data' => $this->data
        ]);
    }
}

3. 视图层增加数据校验

在视图中提前判断数据有效性,避免foreach直接遍历null:

@if(is_array($data) && count($data) > 0)
    @foreach($data as $d)
        <tr>
            <td>{{ $d['trip_date'] ?? '' }}</td>
            <td>{{ $d['trip_time'] ?? '' }}</td>
            <td>{{ $d['invoice'] ?? '' }}</td>
            <td>{{ $d['customer_name'] ?? '' }}</td>
        </tr>  
    @endforeach
@else
    <tr>
        <td colspan="4">暂无数据</td>
    </tr>
@endif

4. 规避GET请求长度限制

如果预订数据量较大,GET请求的URL长度限制会导致JSON字符串被截断,解码后为null。建议改用POST请求传递数据:

  • 前端用axios发送POST请求:
    exportExcel() {
        axios.post('/admin/booking-status-report/excel', {
            data: this.bookings
        }, {
            responseType: 'blob'
        }).then(res => {
            const url = window.URL.createObjectURL(new Blob([res.data]))
            const a = document.createElement('a')
            a.href = url
            a.download = 'booking-status-report.xlsx'
            document.body.appendChild(a)
            a.click()
            window.URL.revokeObjectURL(url)
            document.body.removeChild(a)
        })
    }
    
  • 后端修改接收逻辑:
    public function export(Request $request) 
    {
        $data = $request->input('data');
        if (!empty($data)) {
            return Excel::download(new BookingStatusExport($data), 'booking-status-report.xlsx');
        } else {
            return response()->json(['error' => 'Data parameter is missing'], 400);
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:36:11