laravel 5控制器中的CSV导出

Mat*_*art 27 php csv laravel laravel-5

所以我向我提出了一个小的ajax请求reviewsController@export.

现在当console.log()我成功方法中的数据时,ajax响应显示正确的数据.但是我的CSV尚未下载.所以我拥有所有正确的信息并且基本上创建了csv.

我认为这可能与设置标题有关吗?

public function export()
{
    header("Content-type: text/csv");
    header("Content-Disposition: attachment; filename=file.csv");
    header("Pragma: no-cache");
    header("Expires: 0");

    $reviews = Reviews::getReviewExport($this->hw->healthwatchID)->get();
    $columns = array('ReviewID', 'Provider', 'Title', 'Review', 'Location', 'Created', 'Anonymous', 'Escalate', 'Rating', 'Name');

    $file = fopen('php://output', 'w');
    fputcsv($file, $columns);

    foreach($reviews as $review) {
        fputcsv($file, array($review->reviewID,$review->provider,$review->title,$review->review,$review->location,$review->review_created,$review->anon,$review->escalate,$review->rating,$review->name));
    }
    exit();
}
Run Code Online (Sandbox Code Playgroud)

我在这里做错了什么,或者Laravel有什么可以满足的吗?

Ner*_*ood 44

试试这个版本 - 这应该可以让你得到一个很好的输出 Response::stream().

public function export()
{
    $headers = array(
        "Content-type" => "text/csv",
        "Content-Disposition" => "attachment; filename=file.csv",
        "Pragma" => "no-cache",
        "Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
        "Expires" => "0"
    );

    $reviews = Reviews::getReviewExport($this->hw->healthwatchID)->get();
    $columns = array('ReviewID', 'Provider', 'Title', 'Review', 'Location', 'Created', 'Anonymous', 'Escalate', 'Rating', 'Name');

    $callback = function() use ($reviews, $columns)
    {
        $file = fopen('php://output', 'w');
        fputcsv($file, $columns);

        foreach($reviews as $review) {
            fputcsv($file, array($review->reviewID, $review->provider, $review->title, $review->review, $review->location, $review->review_created, $review->anon, $review->escalate, $review->rating, $review->name));
        }
        fclose($file);
    };
    return Response::stream($callback, 200, $headers);
}
Run Code Online (Sandbox Code Playgroud)

(改编自此 SO答案:使用Laravel以CSV格式下载表格)

尝试使用常规链接target="_blank"而不是使用JavaScript/AJAX.因为它是在新选项卡中打开的文件,所以用户体验不应该太笨重.

  • 嘿,@Nerdwood。我刚刚编辑了您的答案,以在调用 `fclose` 时添加丢失的文件处理程序。我用 L5.4 尝试了你的解决方案,并因此出现错误。添加后,它就像一个魅力。:) (2认同)
  • 较新版本的Laravel删除了`Response :: stream()`函数。而是使用`response()-> stream($ callback,200,$ headers);` (2认同)
  • 对于laravel 5.7。*,`return response()-> streamDownload($ callback,'prefix-'。date('dmYH:i:s')。'。csv',$ headers);`[ref](https: //laravel.com/docs/5.7/responses) (2认同)

Rya*_*yan 8

我在Laravel 5.7中的方法

/**
 * @param array $columnNames
 * @param array $rows
 * @param string $fileName
 * @return \Symfony\Component\HttpFoundation\StreamedResponse
 */
public static function getCsv($columnNames, $rows, $fileName = 'file.csv') {
    $headers = [
        "Content-type" => "text/csv",
        "Content-Disposition" => "attachment; filename=" . $fileName,
        "Pragma" => "no-cache",
        "Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
        "Expires" => "0"
    ];
    $callback = function() use ($columnNames, $rows ) {
        $file = fopen('php://output', 'w');
        fputcsv($file, $columnNames);
        foreach ($rows as $row) {
            fputcsv($file, $row);
        }
        fclose($file);
    };
    return response()->stream($callback, 200, $headers);
}

public function someOtherControllerFunction() {
    $rows = [['a','b','c'],[1,2,3]];//replace this with your own array of arrays
    $columnNames = ['blah', 'yada', 'hmm'];//replace this with your own array of string column headers        
    return self::getCsv($columnNames, $rows);
}
Run Code Online (Sandbox Code Playgroud)


Luc*_* C. 7

尝试这个:

<?php

public function download()
{
    $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'
    ];

    $list = User::all()->toArray();

    # add headers for each column in the CSV download
    array_unshift($list, array_keys($list[0]));

   $callback = function() use ($list) 
    {
        $FH = fopen('php://output', 'w');
        foreach ($list as $row) { 
            fputcsv($FH, $row);
        }
        fclose($FH);
    };

    return Response::stream($callback, 200, $headers); //use Illuminate\Support\Facades\Response;

}
Run Code Online (Sandbox Code Playgroud)

注意:仅当您不加载关系时才有效,否则会出现异常