Laravel 5.1 - how to download pdf file from S3 bucket

11,407

Solution 1

I think something like this will do the job in L5.2:

public function download($path)
{
    $fs = Storage::getDriver();
    $stream = $fs->readStream($path);
    return \Response::stream(function() use($stream) {
        fpassthru($stream);
    }, 200, [
        "Content-Type" => $fs->getMimetype($path),
        "Content-Length" => $fs->getSize($path),
        "Content-disposition" => "attachment; filename=\"" .basename($path) . "\"",
        ]);
}

Solution 2

you can create a download url, using the getObjectUrl method

somthing like this:

$downloadUrl = $s3->getObjectUrl($bucketname, $file, '+5 minutes', array(
            'ResponseContentDisposition' => 'attachment; filename=$file,'Content-Type' => 'application/octet-stream',
    ));

and pass that url to the user. that will direct the user to an amzon page which will start the file download (the link will be valid for 5 minutes - but you can change that)

another option, is first saving that file to your server, and then let the user download the file from your server

Solution 3

You can do with this code (replace with your directory and your file name) ....

Storage::disk('s3')->download('bucket-directory/filename');

Solution 4

If your bucket is private, this is the way to obtain a url to download the file.

$disk = \Storage::disk('s3');
if ($disk->exists($file)) {
   $command = $disk->getDriver()->getAdapter()->getClient()->getCommand('GetObject', [
       'Bucket'                     => \Config::get('filesystems.disks.s3.bucket'),
       'Key'                        => $file,
       'ResponseContentDisposition' => 'attachment;'
   ]);
   $request = $disk->getDriver()->getAdapter()->getClient()->createPresignedRequest($command, '+5 minutes');
   $url = (string)$request->getUri();
   return response()->json([
       'status' => 'success',
       'url' => $url
   ]);
}

Solution 5

In Laravel 5.7 it can be done with streamDownload:

        return response()->streamDownload(function() use ($attachment) {
            echo Storage::get($attachment->path);
        }, $attachment->name);
Share:
11,407
Joel Joel Binks
Author by

Joel Joel Binks

PHP/MySQL/Node/JS/JQuery/HTML/CSS/Java/Python

Updated on June 28, 2022

Comments

  • Joel Joel Binks
    Joel Joel Binks almost 2 years

    I am using Laravel's Storage facade and I am able to upload the pdf to S3 and I am also able to get() its contents but I cannot display or download it to the end user as an actual pdf file. It just looks like raw data. Here is the code:

    $file = Storage::disk($storageLocation)->get($urlToPDF);
    header("Content-type: application/pdf");
    header("Content-Disposition: attachment; filename='file.pdf'");
    echo $file;
    

    How can this be done? I have checked several articles (and SO) and none of them have worked for me.