3

I'm using following package: https://github.com/Maatwebsite/Laravel-Excel at version 2 with Laravel version 5.1

I've have got controller method with following code:

....
return Excel::create('List', function($excel) use ($list)
{
  $excel->sheet('List', function($sheet) use ($list)
  {
    $sheet->fromModel($list);
  });
})
->download('csv');  

and simple test like this:

$this->call('GET', 'route/to/csv', [
    'param' => 'value',
]);

$this->dump();

Above test outputs [ERROR]: Headers already sent from this line of the package.

Controller method works fine, but can't test it.

I've tried to run phpunit with --stderr param. In that case, no error is thrown, but it just dumps output of CSV file to console and exits. I've also tried to run test with @runInSeparateProcess annotation and got errors like:

PHPUnit_Framework_Exception: PHP Notice:  Constant LARAVEL_START already defined in bootstrap/autoload.php on line 3
....
PHP Fatal error:  Uncaught exception 'ReflectionException' with message 'Class env does not exist' in vendor/laravel/framework/src/Illuminate/Container/Container.php:736

Could this be a bug in Laravel-Excel package or I'm testing it wrong?

Azamat
  • 435
  • 5
  • 13

1 Answers1

2

Thats because the way the download method works in laravel-excel is by setting headers. You want to avoid that, and instead do all the work your self by returning laravel Responses.

Try this instead:

$file = Excel::create('List', function($excel) use ($list) {
  $excel->sheet('List', function($sheet) use ($list)
  {
    $sheet->fromModel($list);
  });
})->string('xls');

return new Response($file, 200, [
            'Content-Type' => 'application/vnd.ms-excel; charset=UTF-8',
            'Content-Disposition' => 'attachment; filename="' . $file->filename . '.' . $file->ext . '"',
            'Expires' => 'Mon, 26 Jul 1997 05:00:00 GMT', // Date in the past
            'Last-Modified' => Carbon::now()->format('D, d M Y H:i:s'),
            'Cache-Control' => 'cache, must-revalidate',
            'Pragma' => 'public',
        ]);

The key difference is to use the string() method which will return the binary data for the excel file and allows you to pass it as the data for a response.

Kirill Fuchs
  • 13,446
  • 4
  • 42
  • 72