Error. Failed to load pdf document in laravel - php

I want to load pdf file in html but i got an error.
here is my function
public function getDocument($file){
$filePath = 'app/final/attachments/AA-19-4-2019-18123/'.$file;
$type = Storage::mimeType($filePath);
$pdfContent = Storage::get($filePath);
return Response::make($pdfContent, 200, [
'Content-Type' => $type,
'Content-Disposition' => 'inline; filename="'.$file.'"'
]);
}
here is my route
Route::get('/documents/pdf-document/{file}', 'inboxController#getDocument');
and here is my code in blade
<embed src="{{ action('inboxController#getDocument', ['file'=> basename($attach)]) }}" style="width:100%;height:auto;overflow: hidden;" frameborder="0" allowfullscreen>
it seems like, the error is because of the filename of the file. When i changed it to asdf.pdf, it loaded the file, but when i change its filename i wont loaded anymore. Images doesnt have really a problem. only pdf files. Please help me
edit
when i tried to use this static code, then remove {file} from route and also in blade, then pdf will loaded. i cant figure it out why.
public function getDocument(){
$filePath = 'app/final/attachments/AA-19-4-2019-18123/my.pdf';
$type = Storage::mimeType($filePath);
$pdfContent = Storage::get($filePath);
return Response::make($pdfContent, 200, [
'Content-Type' => $type,
'Content-Disposition' => 'inline; filename="'.$file.'"'
]);
}

You can do it this way :
php artisan storage:link
Next Go to the storage folder under 'public', and create a Folder 'FOLDER_NAME'
Your function :
public function getDocument($filename){
return response()->file('storage/FOLDER_NAME/'.$filename);
}
In your routes, web.php :
Route::get('/pdf/{filename}', ['as' => 'filename', 'uses' => 'ControllerName#getDocument' ]);
Then you can call it from your blade :
See PDF File:

Related

Laravel 8 download PDF with Livewire

On my page I am making an invoice that is fully compatible with Livewire. I use this package: https://github.com/LaravelDaily/laravel-invoices to generate my invoice and everything works fine. But their is one problem I ran into. I can't download my PDF with Livewire.
Here is a basic example to generate a PDF and download it:
public function invoice()
{
$customer = new Buyer([
'name' => 'John Doe',
'custom_fields' => [
'email' => 'test#example.com',
],
]);
$item = (new InvoiceItem())->title('Service 1')->pricePerUnit(2);
$invoice = Invoice::make()
->buyer($customer)
->discountByPercent(10)
->taxRate(15)
->shipping(1.99)
->addItem($item);
return $invoice->download();
}
Whenever I click on a button
<a role="button" class="pdf-download cursor-pointer" wire:click="invoice">download</a>
Nothing happens. So the problem is that Livewire doesn't support this download method. And this download method looks like this:
public function download()
{
$this->render();
return new Response($this->output, Response::HTTP_OK, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="' . $this->filename . '"',
'Content-Length' => strlen($this->output),
]);
}
$this->render(); Renders a template in a specific folder
Is their a work around for this? Where I can download my pdf with a template or maybe a different strategy. I allready tried one thing. I stored the invoice into a session, like so:
Session::put('invoice', $invoice);
Session::save();
And in a different controller I have.
if ($invoice = Session::get('invoice')) {
$invoice->download();
}
But that gives me this error:
serialization of 'closure' is not allowed
And I tried some stuff I found here: https://github.com/livewire/livewire/issues/483
But nothing works. Can someone give me a direction on where to look or how to fix this? Thanks!
return response()->streamDownload(function () use($invoice) {
echo $invoice->stream();
}, 'invoice.pdf');
Seems to do the trick.

Get / Read laravel 5.8 Storage non public Folder files to View?

Try to access 'storage/app/folder1/a.png' from my view
public function viewStorageFiles()
{
$fileFullPath = Storage::disk('local')->path('folder1/a.png');
$fileUrl = Storage::disk('local')->url('app/folder1/a.png');
$storage_path = storage_path('app/folder1/a.png');
return view('email.fileDownload')->with([
'fileFullPath' => $fileFullPath,
'fileUrl' => $fileUrl,
'storage_path' => $storage_path,
]);
}
In view : email.fileDownload
<div>
<p> asset($fileUrl) ==> {{asset($fileUrl)}}</p>
<img src="{{asset($fileUrl)}}"/>
</div>
<div>
<p> url($fileUrl) ==> {{url($fileUrl)}}</p>
<img src="{{url($fileUrl)}}"/>
</div>
<div>
<p> storage_path($fileUrl) ==> {{storage_path($fileUrl)}}</p>
<img src="{{storage_path($fileUrl)}}"/>
</div>
the result is :
There could be many answers to this!
You could create a symbolic link from "public/storage" to "storage/app/public" using the following command:
php artisan storage:link
Above command will map your storage/app/public directory to public directory.
Now let's consider you have user1.jpg and user2.jpg files in your storage/app/public directory, you can access them in the following way:
http://your-domain.com/storage/user1.jpg
http://your-domain.com/storage/user2.jpg
* Updated my answer based on your comment: *
You can return a file response from a route that is protected by some middleware!
For example - following route returns file response from storage/app/uploads directory that is not accessible publicly:
Route::get('storage/{file}', function ($file) {
$path = storage_path('app' . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . $file);
return response()->file($path);
});
You could secure above route in anyway and use it in your views..
I hope that helped..
Go to config/filesystems add this array
'public_site' => [
'driver' => 'local',
'root' => public_path('storage'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
]
then your function could be like this
public function viewStorageFiles()
{
$fileFullPath = Storage::disk('public_site')->path('folder1/a.png');
$fileUrl = Storage::disk('public_site')->url('app/folder1/a.png');
$public_path = public_path('storage/app/folder1/a.png');
return view('email.fileDownload')->with([
'fileFullPath' => $fileFullPath,
'fileUrl' => $fileUrl,
'storage_path' => $public_path,
]);
}

Display pdf file from local disk in Laravel 5?

I have a Laravel 5.5 app where users with administrator privileges can upload files. After they upload the files I'd like them to be able to view the file in the administrator dashboard.
I have a DocumentController.php that handles the file upload to the local disk:
public function store(Request $request)
{
// check to make sure user is an admin
$request->user()->authorizeRoles('admin');
// validate that the document is a pdf and
// that required fields are filled out
$this->validate($request, [
'title' => 'required',
'description' => 'required',
'user_id' => 'required|exists:users,id',
'document_path' => 'required|mimes:pdf'
]);
$file = $request->file('document_path');
$path = $file->store('documents/' . $request->user_id);
$document = Document::create([
'user_id' => $request->user_id,
'title' => $request->title,
'description' => $request->description,
'file_path' => $path
]);
return redirect($document->path());
}
This method takes the file from the form, makes sure it is a pdf and then saves the file to storage/app/documents/{user_id}. It then creates a Document record in the database and forwards to the URL based on the document id: /admin/document/{ $document->id }
That route is defined as Route::get('/admin/document/{document}', 'DocumentController#show');
Where in the controller I pass the document to the view:
public function show(Document $document, Request $request)
{
// check to make sure user is an admin
$request->user()->authorizeRoles('admin');
$storagePath = Storage::disk('local')->getDriver()->getAdapter()->getPathPrefix();
return view('admin.document', compact('document', 'storagePath'));
}
On that page I would like to display the pdf document.
resources/views/admin/document.blade.php
#extends('layouts.app')
#section('content')
<div class='container'>
<div class='row'>
<div class='col-sm-2'>
<a href='/admin'>< Back to admin</a>
</div>
<div class='col-sm-8'>
{{ $document }}
<embed src="{{ Storage::url($document->file_path) }}" style="width:600px; height:800px;" frameborder="0">
</div>
</div>
</div>
#endsection
I have tried using the $storagePath variable and Storage methods but cannot get the pdf file to display within the iframe.
Using local file storage how would I display the file in the browser? Also, I've protected the route so that only admins can view the document's page but what is the best way to secure the path to the document itself?
If you want your files to be protected (only admin can access them), then you need to create a new route and new DocumentController method getDocument
Add new route
Route::get('documents/pdf-document/{id}', 'DocumentController#getDocument');
In DocumentController, add
use Storage;
use Response;
Add new method that will read your pdf file from the storage and return it back
public function getDocument($id)
{
$document = Document::findOrFail($id);
$filePath = $document->file_path;
// file not found
if( ! Storage::exists($filePath) ) {
abort(404);
}
$pdfContent = Storage::get($filePath);
// for pdf, it will be 'application/pdf'
$type = Storage::mimeType($filePath);
$fileName = Storage::name($filePath);
return Response::make($pdfContent, 200, [
'Content-Type' => $type,
'Content-Disposition' => 'inline; filename="'.$fileName.'"'
]);
}
In your view you can show the document like this
<embed
src="{{ action('DocumentController#getDocument', ['id'=> $document->id]) }}"
style="width:600px; height:800px;"
frameborder="0"
>
Shorter version of that Response::make() from #ljubadr answer:
return Storage::response($document->file_path)
<embed
src="{{ url('/filepath') }}"
style="width:600px; height:800px;"
frameborder="0">

Laravel 5.4 Response File -> Error in File

I am working with Laravel 5.4 and save some JPEG-Files to Storage with
`Storage::disk('local')->put('upload/pictures/full-size/'.$filename ,$picture);`
And now i try to get this pictures again which i tryed like
...
Routes:
Route::get('pictures/full/{filename}', ['as' => 'picture_full', 'uses' => 'ImageController#getFull']);
...
Image Controller:
public function getFull(Image $image)
{
$path = storage_path('app/'.Config::get('pictures.icon_size').$image->filename);
$handler = new \Symfony\Component\HttpFoundation\File\File($path);
$header_content_type = $handler->getMimeType();
$header_content_length = $handler->getSize();
$headers = array(
'Content-Type' => $header_content_type,
'Content-Length' => $header_content_length
);
return response()->file($path, $headers);
}
So now my Problem is, that the file can't be shown.
The Browser says the File contains an Error.
Tryed a lot, but just don't see what I am making wrong.
Anyone has an idea?

Download CSV from serverside to browser in Laravel 4

I'm using Laravel 4 framework, I have a function that creates a csv file called data_78888.csv the number 78888 changes everytime the function is run to generate a csv file. That function returns a string like that : "Download/78888"
The folder where my csv files are created is called "outputs" and is located in my project folder where the app folder is located to, (it is not in the public folder).
What I would like to do is to create a route that points to my Process controller like that :
Route::get('Download/{token}', array('uses' => 'ProcessController#downloadCSV'));
In my controller I would like to send that csv file to the browser to download it , I'm doing like that :
<?php
class ProcessController extends BaseController {
public function downloadCSV($token){
$fileToDownload = "data_".$token.".csv";
$filePath = "outputs/";
return Response::download($filePath, $fileToDownload, array(
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment;filename="'.$fileToDownload
));
}
}
The issue is that this is not working and I get an html file called 78888.htm and an error on the server.
How can I make this working please?
The path to the file has to include the name and file extension of the file.
So try this;
$fileToDownload = "data_".$token.".csv";
$filePath = base_path() . "outputs/" . $fileToDownload;
return Response::download($filePath, $fileToDownload, array(
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment;filename="'.$fileToDownload
));
Also make sure the file exists, before downloading.

Categories