Lucas Campos Lucas Campos - 29 days ago 8
PHP Question

How do I redirect after download in Laravel?

I'm using maatwebsite/excel library to create excel files then download my file

in my controller I do like this:

public function todas()
{
$input = Input::all();

if(isset($input['todos'])&&($input['todos']!=0))
{
set_time_limit(0);
$datainicio = DB::table('tb_periodo')->where('cod', $input['todos'])->pluck('periodo_inicio');
$datafinal = DB::table('tb_periodo')->where('cod', $input['todos'])->pluck('periodo_fim');
$mes = DB::table('tb_periodo')->where('cod', $input['todos'])->pluck('mes_referencia');

$horarioQuery = $this->horario->with(array('funcionario', 'item_contabil'))
->whereBetween('data', array($datainicio, $datafinal))
->whereNull('deleted_at')
->orderBy('cod_funcionario')
->orderBy('data', 'ASC')
->get();

$horarios = reset($horarioQuery);

$count = count($horarios);

if($horarios==null)
return Redirect::route('relatorios.todas')->withErrors(['não existem marcações para este período']);

$funcionarios = $this->funcionario->all();

$datainicio = Carbon::createFromFormat('Y-m-d H:i:s', $datainicio);
$datafinal = Carbon::createFromFormat('Y-m-d H:i:s', $datafinal);

$nome = 'Marcações'.$mes.'-'.Carbon::now()->year;
$this->horario->allToExcel($nome, $horarios);

return View::make('relatorios.todashow', compact('funcionarios', 'datainicio', 'datafinal', 'horarios', 'count', 'nome'));
}
else
{
return Redirect::route('relatorios.todas')->withErrors(['Selecione um período!']);
}
}


that is my function to generate excel file :

public static function allToExcel($nome, $horarios)
{
Excel::create($nome , function ($excel) use ($horarios) {

$excel->sheet('Marcações', function ($sheet) use ($horarios) {

$sheet->row(1, array(

'Unidade',
'Nome',
'Função',
'Data',
'Hora Faturada',
'Hora Contratada',
'Horas Trabalhadas',
'Horas Extras',
'Tempo Exposicao',
'Atividade',
'Item Contabil',
'Observacoes'
));

$sheet->row(1, function($row) {
$row->setBackground('#2A8005');
$row->setFontColor('#ffffff');
$row->setFontWeight('bold');
});

$i = 2;
foreach ($horarios as $horario) {

if($horario->funcionario->funcao_qt != null)
$funcao = $horario->funcionario->funcao_qt;
else
$funcao = $horario->funcionario->funcao_a5;

$sheet->row($i, array(
$horario->unidade,
$horario->funcionario->nome,
$funcao,
$horario->data->format('d/m/Y'),
$horario->hora_faturada->format('H:i'),
$horario->hora_contratada,
$horario->getWorkedHours()->format('H:i'),
$horario->getExtraHours()->format('H:i'),
$horario->tempo_exposicao ?: "-",
$horario->atividade,
$horario->item_contabil->CTD_DESC01,
$horario->observacoes
));
if($i % 2 != 0)
{
$sheet->row($i, function($row) {
$row->setBackground('#D1D1D1');
});
}

$i++;
}
});

})->download('xls');
}


but after I download the excel file I cant redirect to a route or view and I Also tried to use :

routes:

Route::post('relatorios/todas', array('as' => 'relatorios.todas', 'after' => 'voltar', 'uses' => 'ReportsController@todas'));


filter:

Route::filter('voltar', function()
{
return Redirect::back()->with('message', '<p class="bg-success"><b>Relatório gerado com sucesso</b></p>');
});


but didnt work anyway, have another way to redirect after download my file ??!

thx in advance!

Answer

It cannot be done. The problem is that if you send a download instruction to the user browser, you are, as a matter of fact, sending a response and you can send only one response back.

What you could do is to, first redirect your user to the "final" page and in that page start the download. The code would be something like:

Session::flash('download.in.the.next.request', 'filetodownload.pdf');

return Redirect::to('/whatever/page');

Then in your new page you'll have some options:

So you can in your layout do something like:

<html>
  <head>
      @if(Session::has('download.in.the.next.request'))
         <meta http-equiv="refresh" content="5;url={{ Session::get('download.in.the.next.request') }}">
      @endif
   <head>

   <body>
      ...
   </body>
</html>

Also, take a look at this answer: PHP generate file for download then redirect

Comments