2015-09-07 78 views
8

因此,我已经对我的[email protected]做了一个小AJAX请求。CSV导出laravel 5控制器

现在当我在我的成功方法中的数据为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(); 
} 

有什么我做错了这里,还是Laravel有东西,以应付呢?

+0

AFAIK这是行不通的,因为你调用使用Ajax这个功能和Ajax可能不支持下载头。是否有任何具体要求使用Ajax?我想你可以直接调用该脚本并设置适当的标题,以便它应该在同一页面上并且CSV将会生成。 – Yogesh

+0

我只是喜欢使用ajax,因为它不会使页面重新加载。看起来更好 –

回答

13

试试这个版本 - 这应该允许你使用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); 
} 

(从这个适配成回答:Use Laravel to Download table as CSV

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

+0

这给了我错误:ReviewsController.php中的FatalErrorException第90行: 语法错误,意外的'返回'(T_RETURN) –

+0

封闭定义之后缺少分号(就在'return'之前)!抱歉。 :S – Nerdwood

+0

确定它现在没有错误,但它只是做我的代码做的同样的事情。返回正确的格式并将其记录在控制台中。但不强制下载 –

1

这可能不是直接回答你的问题,但我使用了一个名为“thephpleague/csv”为此,包...

要使用这个包:

  1. 作曲家需要联盟/ CSV
  2. 将下面的 '使用' 的语句在你的控制器:

    use Illuminate\Database\Eloquent\Collection; 
    use League\Csv\Writer; 
    use Schema; 
    use SplTempFileObject; 
    

    任何模型CLAS您是否打算使用。

  3. 摘要CSV创建代码的功能(在你的控制器),例如:

    /** 
    * A function to generate a CSV for a given model collection. 
    * 
    * @param Collection $modelCollection 
    * @param $tableName 
    */ 
    private function createCsv(Collection $modelCollection, $tableName){ 
    
        $csv = Writer::createFromFileObject(new SplTempFileObject()); 
    
        // This creates header columns in the CSV file - probably not needed in some cases. 
        $csv->insertOne(Schema::getColumnListing($tableName)); 
    
        foreach ($modelCollection as $data){ 
         $csv->insertOne($data->toArray()); 
        } 
    
        $csv->output($tableName . '.csv'); 
    
    } 
    
  4. 在您的控制器上,创建get函数来检索/下载CSV(用自己的模型类取代“MainMeta” ):

    public function getMainMetaData(){ 
    
        $mainMeta = MainMeta::all(); 
    
        // Note: $mainMeta is a Collection object 
        //(returning a 'collection' of data from using 'all()' function), 
        //so can be passed in below. 
        $this->createCsv($mainMeta, 'main_meta'); 
    } 
    

    当您创建一个路径来调用此函数时,它将在您的浏览器中下载您选择的模型集合/数据的CSV文件。

  5. 创建应用程序的路由\ HTTP \ routes.php文件如下所示:

    Route::get(
        '/data/download/main_meta', 
        [ 
         'as' => 'data/download/main_meta', 
         'uses' => '[email protected]' 
        ] 
    ); 
    
  6. (可选)在一个刀片视图文件(例如data.blade.php),包括一个链接或按钮这样你就可以轻松地访问下载网址/路径:

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

    当你点击链接时,CSV文件将在您的浏览器下载。在我已编码的应用程序中,您将保留在您点击此链接的页面上。

当然,这取决于您自己的应用程序。你可以用这个软件包做更多的事情(完整文档在http://csv.thephpleague.com/)。我正在使用的这个项目在https://github.com/rattfieldnz/bitcoin-faucet-rotator--几个月后我又开始编码了,所以仍然有一些重构/测试/整理工作要做:)。

1

试试这个:

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

} 
+0

* Array to string conversion * at'fputcsv($ FH,$ row);' –

+0

hello @HoàngĐăng,它在我的项目,也许是以前的PHP/Laravel版本,如果你发现问题,你可以更正答案谢谢 –