Php laravel 5控制器中的CSV导出

Php laravel 5控制器中的CSV导出,php,csv,laravel,laravel-5,Php,Csv,Laravel,Laravel 5,因此,我对我的reviewsController@export 现在,当我console.log()。但是,我的CSV尚未下载。因此,我有所有正确的信息,并已创建的csv基本上 我认为这可能与设置标题有关,也许 public function export() { header("Content-type: text/csv"); header("Content-Disposition: attachment; filename=file.csv"); header("P

因此,我对我的
reviewsController@export

现在,当我
console.log()。但是,我的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();
}

这里有什么我做错了的吗,或者Laravel有什么东西可以解决这个问题吗?

试试这个版本-这应该可以让您使用
Response::stream()
获得很好的输出

(根据该答案改编:)


尝试使用带有
target=“\u blank”
的常规链接,而不是使用JavaScript/AJAX。因为它是在新选项卡中打开的文件下载,所以用户体验应该不会太笨拙。

这可能无法直接回答您的问题,但我正在为此使用一个名为“”的包

要使用此软件包,请执行以下操作:

  • 作曲家需要联盟/csv
  • 在控制器中放入以下“使用”语句:

    use Illuminate\Database\Eloquent\Collection;
    use League\Csv\Writer;
    use Schema;
    use SplTempFileObject;
    
    以及您计划使用的任何模型类

  • 为函数(在控制器中)创建代码,例如:

  • 在控制器中,创建get函数以检索/下载CSV(用您自己的模型类替换“MainMeta”):

    创建管线以调用此功能时,它将在浏览器中下载所选模型集合/数据的CSV文件

  • 在App\Http\routes.php中创建路由,如下所示:

    Route::get(
        '/data/download/main_meta',
        [
            'as' => 'data/download/main_meta',
            'uses' => 'YourController@getMainMetaData'
        ]
    );
    
  • (可选)在刀片视图文件(例如data.blade.php)中,包括一个链接或按钮,以便您可以轻松访问下载url/路径:

    <p><a href="{{ URL::route('data/download/main_meta') }}" class="btn btn-lg btn-primary pull-left">Download Main Meta Data</a></p>
    

    单击链接时,CSV文件将在浏览器中下载。在我编写的应用程序中,单击此链接后,您将停留在页面上

  • 当然,这取决于您自己的应用程序。使用这个软件包,您可以做更多的事情(完整的文档位于)。我在中使用此功能的项目位于-几个月后,我刚刚开始再次对其进行编码,因此还有一些重构/测试/整理工作要做:)。

    尝试以下操作:

    <?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;
    
    }
    

    我做了一个小包装

    把它放在

    装置

    $ composer require  eugene-melbourne/laravel-csv-generator
    
    在控制器中使用的示例

    class MyController extends Controller
    {
    
        public function getCsv(): \Symfony\Component\HttpFoundation\StreamedResponse
        {
            $data    = [
                    [1, 2.1],
                    [3, "hi, there"],
                ];
            $headers = ['one', 'two'];
            $data = array_merge([$headers], $data);
    
            return (new \LaravelCsvGenerator\LaravelCsvGenerator())
                    ->setData($data)
                    ->renderStream();
        }
    
    请不要犹豫,在下面的答案中评论您的想法。

    我在Laravel 5.7中的方法 简单的方法

            $headers = [
            'Cache-Control'       => 'must-revalidate, post-check=0, pre-check=0'
            ,   'Content-type'        => 'text/csv'
            ,   'Content-Disposition' => 'attachment; filename=leads.csv'
            ,   'Expires'             => '0'
            ,   'Pragma'              => 'public'
        ];
        $leads = []
        return response(view('exports.leads.csv', [ 'leads' => $leads ]))
            ->withHeaders($headers);
    

    您必须将文件存储在服务器上(临时或磁盘上),并将文件的url发送到前端。然后通过javascript触发正常下载

    公共函数导出(请求$Request)
    {
    您必须将文件存储在服务器上(临时或磁盘上),并将文件的url发送到前端,然后通过javascript触发正常下载。
    
    谢谢,这就是我现在所做的。好吧,这不起作用,因为您使用Ajax调用此功能,Ajax可能不支持下载头。使用Ajax是否有任何特定要求?我想您可以直接调用该脚本并设置适当的头,以便它应该在同一页面上,CSV将生成。我只是建议呃使用ajax,因为它不会重新加载页面。看起来更好,呃,@Nerdwood。我刚刚编辑了你的答案,以便在调用
    fclose
    时添加缺少的文件处理程序。我尝试了你的L5.4解决方案,但因此出现了一个错误。添加该解决方案后,效果非常好。:)较新版本的Laravel删除了
    Response::stream()
    函数。相反,使用
    response()->stream($callback,200,$headers);
    对于laravel 5.7.*,
    return response()->streamDownload($callback,'prefix-'.date('d-m-Y-H:i:s')。.csv',$headers);
    它在本地为我工作。但在服务器上我不断遇到这个错误:“无法在streamdresponse实例上设置内容。”知道为什么吗?@Shrikant我不知道详细信息(这不是我的原始代码),但这一行正在获取一个数据数组(关于评论),该数组后来被循环通过(foreach循环)。getReviewExport()是属于reviews类的一个方法,它被传递一个ID(用于获取评论).healthwatchID是$this->hw对象的属性。不确定这是否有帮助!:)在
    fputcsv($FH,$row)上进行数组到字符串的转换
    hello@Hoángėng,它在我的项目中起作用,可能是以前的PHP/Laravel版本,如果你发现问题,你可以更正答案谢谢hello@Hoángăng,如何将文件移动到特定文件夹以获得可下载链接只需发送一个字符串,但我需要一个文件。我不明白你的意思是什么“替换为您自己的数组”。@DavideCasiraghi
    [['a','b','c'],[1,2,3]
    只是示例数据,您在应用程序中使用这些数据毫无意义。因此,请根据您的需要自定义该部分。与
    ['blah','yada','hmm']
    相同。
    $ composer require  eugene-melbourne/laravel-csv-generator
    
    class MyController extends Controller
    {
    
        public function getCsv(): \Symfony\Component\HttpFoundation\StreamedResponse
        {
            $data    = [
                    [1, 2.1],
                    [3, "hi, there"],
                ];
            $headers = ['one', 'two'];
            $data = array_merge([$headers], $data);
    
            return (new \LaravelCsvGenerator\LaravelCsvGenerator())
                    ->setData($data)
                    ->renderStream();
        }
    
    /**
     * @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);
    }
    
            $headers = [
            'Cache-Control'       => 'must-revalidate, post-check=0, pre-check=0'
            ,   'Content-type'        => 'text/csv'
            ,   'Content-Disposition' => 'attachment; filename=leads.csv'
            ,   'Expires'             => '0'
            ,   'Pragma'              => 'public'
        ];
        $leads = []
        return response(view('exports.leads.csv', [ 'leads' => $leads ]))
            ->withHeaders($headers);