theUnforgiven's avatar

Opening files online using Laravel

Hi all,

I have built a small app that allows file uploads, but I want to be able to click a link that either opens in the browser (for example if the file is PDF) otherwise if it's a Word Document it should be downloaded.

Is there any package to do this, or is there a way to do this?

0 likes
16 replies
bashy's avatar

Just add some header content-types? By default browsers will show PDFs and download docx and doc etc

xingfucoder's avatar

Hi @lstables, you could use something like this in your controller method:

$file = 'yourfilename.pdf' 
// check if the file exists
if (file_exists($file)) {
    // Get the file content to put into your response
    $content = file_get_contents($file);
    //Build your Laravel Response with your content, the HTTP code and the Header application/pdf
    return Response::make($content, 200, array('content-type'=>'application/pdf'));
}

Here you have content type list:

http://webdesign.about.com/od/multimedia/a/mime-types-by-content-type.htm

Hope it helps you.

bashy's avatar
bashy
Best Answer
Level 65

Could use a more Laravel way

if (File::isFile($file))
{
    $file = File::get($file);
    $response = Response::make($file, 200);
    // using this will allow you to do some checks on it (if pdf/docx/doc/xls/xlsx)
    $response->header('Content-Type', 'application/pdf');

    return $response;
}

// Or to download

if (File::isFile($file))
{
    return Response::download($file, $file_name);
}

Some content types

$content_types = [
    'application/octet-stream', // txt etc
    'application/msword', // doc
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document', //docx
    'application/vnd.ms-excel', // xls
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // xlsx
    'application/pdf', // pdf
];
6 likes
theUnforgiven's avatar

@bashy not quite sure where to put what you said, here I have a table that loops through and all i want to do is add an extra link to say 'view' then the customer can view or download accordingly.

<table class="table d">
           <!-- List all documents based on authenticated user -->
            @foreach($docs as $doc)
            <tr>
                <td><a href="/document/edit/{{ $doc->id }}">{{ $doc->document }}</a></td>
                <td><a href="document/remove/{{ $doc->id }}" class="btn btn-sm btn-danger">Remove</a></td>
            </tr>
            @endforeach
        </table>
theUnforgiven's avatar

Ok added a new method within my controller like so:

public function view()
    {
        $doc = Data::where('user_id','=', Auth::user()->id)->first();
        $file = $doc->document;

        if (File::isFile($file))
        {
            $file = File::get($file);
            $response = Response::make($file, 200);
            $content_types = [
                'application/octet-stream', // txt etc
                'application/msword', // doc
                'application/vnd.openxmlformats-officedocument.wordprocessingml.document', //docx
                'application/vnd.ms-excel', // xls
                'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // xlsx
                'application/pdf', // pdf
            ];
            // using this will allow you to do some checks on it (if pdf/docx/doc/xls/xlsx)
            $response->header('Content-Type', $content_types);

            return $response;
        }
    }

But nothing is been returning on this example txt file I have.

1 like
xingfucoder's avatar

Hi, you only need to pass one content-type because your reaponse cannot be different file type.

1 like
kwolniak's avatar

You can't pass the whole $content_type array to header() method. You have to check what type of file you get (for example by extension) and then choose one of the mime type and pass it to header method.

@bashy only showed you what mime type is for popular files.

1 like
theUnforgiven's avatar

Yes realised this after i posted all fixed now and working thanks guys.

bashy's avatar

Yeah, I store the extension separate (or maybe you can get it from filename). Then I can use the array to pick out one depending on the type I want.

mohammadelkoumi's avatar

brothers

I follow the steps

and I get this message in pdf viewer

'failed to load pdf document'

my function

public function uploadBook(Request $request)
{
  $extension = $request->file('file')->getClientOriginalExtension();
  $filename = $request->book_name.'.'. $extension;
  $request->file('file')->move(storage_path().'/books/', $filename);
  $fullPath = storage_path().'/books/'. $filename;
  //
  if(file_exists($fullPath)) {
    // return 'YES ITS HERE';
    // return Response::download($fullPath, $filename);
            $response = Response::make(storage_path().'/books/'. $filename, 200);
            $response->header('Content-Type', 'application/pdf');
            return $response;
  } else {
      return 'NOT HERE';
  }
}
1 like
mohammadelkoumi's avatar

Yah ...

ok I got it ...

  //
  if(file_exists($fullPath)) {
        $contentType = mime_content_type($fullPath);
        return Response::make(file_get_contents($fullPath), 200, [
        'Content-Type' => $contentType,
        'Content-Disposition' => 'inline; filename="'.$fullPath.'"']);
  } else {
      return 'NOT HERE';
  }
1 like

Please or to participate in this conversation.