流响应以下载CSV文件

时间:2019-08-10 19:17:08

标签: php laravel csv laravel-5

我正在尝试从服务器流式传输大CSV。我加载一个JSON文件,将其转换为数组,然后将其作为CSV处理。从前端,我在单击按钮时调用以下内容

public function downloadCSVData()
{
    //load JSON file
    $data = file_get_contents($file_path, true);

    //Convert file to array
    $array = json_decode($data, true);

    $headers = [
        'Cache-Control'       => 'must-revalidate, post-check=0, pre-check=0'
        ,   'Content-type'        => 'text/csv'
        ,   'Content-Disposition' => 'attachment; filename=galleries.csv'
        ,   'Expires'             => '0'
        ,   'Pragma'              => 'public'
    ];

    $response = new StreamedResponse(function() use($array){
        // Open output stream
        $handle = fopen('php://output', 'w');

        // Add CSV headers
        fputcsv($handle, array_keys($array['element'][0]), ',');

        foreach ($array['element'] as $key => $row) {
            fputcsv($handle, $row);
        }

        // Close the output stream
        fclose($handle);
    }, 200, $headers);

    return $response->send();
}

然后此函数执行以下操作

["Key":"SomeKeyValue", "Key":"SomeKeyValue"]

现在在前端,在控制台内,我可以看到响应以所需的方式打印。但是,据我了解,后端应该触发文件下载,但没有发生。

我在这里缺少什么吗,如何才能将其作为物理文件下载到前端?

谢谢

1 个答案:

答案 0 :(得分:1)

如果您直接访问了URL,则您的PHP设置应该可以强制进行下载。但是您已经在一个完全加载的HTML页面中,因此您需要使用<iframe>技巧来下载文件。这样,浏览器就可以像打开新浏览器窗口一样接收传入的数据。

尝试将您的下载功能更改为此:

downloadCSVData() {
    $('<iframe />')
        .attr('src', '/downloadCSVData')
        .hide()
        .appendTo('body');
}