Download files in laravel using Response::download

297,524

Solution 1

Try this.

public function getDownload()
{
    //PDF file is stored under project/public/download/info.pdf
    $file= public_path(). "/download/info.pdf";

    $headers = array(
              'Content-Type: application/pdf',
            );

    return Response::download($file, 'filename.pdf', $headers);
}

"./download/info.pdf"will not work as you have to give full physical path.

Update 20/05/2016

Laravel 5, 5.1, 5.2 or 5.* users can use the following method instead of Response facade. However, my previous answer will work for both Laravel 4 or 5. (the $header array structure change to associative array =>- the colon after 'Content-Type' was deleted - if we don't do those changes then headers will be added in wrong way: the name of header wil be number started from 0,1,...)

$headers = [
              'Content-Type' => 'application/pdf',
           ];

return response()->download($file, 'filename.pdf', $headers);

Solution 2

File downloads are super simple in Laravel 5.

As @Ashwani mentioned Laravel 5 allows file downloads with response()->download() to return file for download. We no longer need to mess with any headers. To return a file we simply:

return response()->download(public_path('file_path/from_public_dir.pdf'));

from within the controller.


Reusable Download Route/Controller

Now let's make a reusable file download route and controller so we can server up any file in our public/files directory.

Create the controller:

php artisan make:controller --plain DownloadsController

Create the route in app/Http/routes.php:

Route::get('/download/{file}', 'DownloadsController@download');

Make download method in app/Http/Controllers/DownloadsController:

class DownloadsController extends Controller
{
  public function download($file_name) {
    $file_path = public_path('files/'.$file_name);
    return response()->download($file_path);
  }
}

Now simply drops some files in the public/files directory and you can server them up by linking to /download/filename.ext:

<a href="/download/filename.ext">File Name</a> // update to your own "filename.ext"

If you pulled in Laravel Collective's Html package you can use the Html facade:

{!! Html::link('download/filename.ext', 'File Name') !!}

Solution 3

In the accepted answer, for Laravel 4 the headers array is constructed incorrectly. Use:

$headers = array(
  'Content-Type' => 'application/pdf',
);

Solution 4

Quite a few of these solutions suggest referencing the public_path() of the Laravel application in order to locate the file. Sometimes you'll want to control access to the file or offer real-time monitoring of the file. In this case, you'll want to keep the directory private and limit access by a method in a controller class. The following method should help with this:

public function show(Request $request, File $file) {

    // Perform validation/authentication/auditing logic on the request

    // Fire off any events or notifiations (if applicable)

    return response()->download(storage_path('app/' . $file->location));
}

There are other paths that you could use as well, described on Laravel's helper functions documentation

Solution 5

While using laravel 5 use this code as you don`t need headers.

return response()->download($pathToFile); .

If you are using Fileentry you can use below function for downloading.

// download file
public function download($fileId){  
    $entry = Fileentry::where('file_id', '=', $fileId)->firstOrFail();
    $pathToFile=storage_path()."/app/".$entry->filename;
    return response()->download($pathToFile);           
}
Share:
297,524
DPP
Author by

DPP

Software Developer &amp; Project/Delivery Manager.

Updated on December 04, 2021

Comments

  • DPP
    DPP over 2 years

    In Laravel application I'm trying to achieve a button inside view that can allow user to download file without navigating to any other view or route Now I have two issues: (1) below function throwing

    The file "/public/download/info.pdf" does not exist
    

    (2) Download button should not navigate user to anywhere and rather just download files on a same view, My current settings, routing a view to '/download'

    Here is how Im trying to achieve:

    Button:

      <a href="/download" class="btn btn-large pull-right"><i class="icon-download-alt"> </i> Download Brochure </a>
    

    Route :

    Route::get('/download', 'HomeController@getDownload');
    

    Controller :

    public function getDownload(){
            //PDF file is stored under project/public/download/info.pdf
            $file="./download/info.pdf";
            return Response::download($file);
    }
    
  • Justin
    Justin about 10 years
    Any way to return a file download AND update the view?
  • Eswara Reddy
    Eswara Reddy over 9 years
    Can I change the file permissions while downloading only? @Anam
  • Anam
    Anam over 9 years
    @EswaraReddy, You mean on fly? I don't think so.
  • itsazzad
    itsazzad about 9 years
    How can I download anytype of file?
  • Anam
    Anam about 9 years
    @SazzadTusharKhan you only need to change Content-type, file name and file path to do that.
  • itsazzad
    itsazzad about 9 years
    @Anam How will I know the content type where I may have any type of file?
  • Anam
    Anam about 9 years
    @SazzadTusharKhan just use return Response::download($pathToFile);
  • Khan Shahrukh
    Khan Shahrukh about 9 years
    @Anam is there any way we can pass remote url as filepath ?
  • DutGRIFF
    DutGRIFF over 8 years
    This answer would be helpful if it left out the unnecessary parts or even just expanded on them below the pure answer. Fileentry is a different feature not needed for this question. Edit answer and I will upvote because the mentioning of LV5s response()->download().
  • Prasad Patel
    Prasad Patel almost 7 years
    Worked like a charm, Thanks a lot @DutGRIFF, You saved my day. I tried this download thing for 5 hours but didn't work though, I didn't get any solution but when I tried your solution it worked like a charm. Laravel rocks.
  • ShaneMit
    ShaneMit over 6 years
    the difference in the instantiation of the array is likely because of a PHP version, not laravel version ;)
  • Redgren Grumbholdt
    Redgren Grumbholdt almost 6 years
    Thank you for your contribution. I was getting an Http 500 error but this worked for my case.
  • Faiyaj
    Faiyaj over 2 years
    this is the perfect code ! works like charming!
  • Grizzly Bear
    Grizzly Bear over 2 years
    how can you make this dynamic like get the id of a certain table and download the image in it?