Download files in laravel using Response::download - php

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:
<i class="icon-download-alt"> </i> Download Brochure
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);
}

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);

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:
File Name // 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') !!}

In the accepted answer, for Laravel 4 the headers array is constructed incorrectly. Use:
$headers = array(
'Content-Type' => 'application/pdf',
);

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

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);
}

HTML href link click:
<a ="{{ route('download',$name->file) }}"> Download </a>
In controller:
public function download($file){
$file_path = public_path('uploads/cv/'.$file);
return response()->download( $file_path);
}
In route:
Route::get('/download/{file}','Controller#download')->name('download');

I think that you can use
$file= public_path(). "/download/info.pdf";
$headers = array(
'Content-Type: ' . mime_content_type( $file ),
);
With this you be sure that is a pdf.

// Try this to download any file. laravel 5.*
// you need to use facade "use Illuminate\Http\Response;"
public function getDownload()
{
//PDF file is stored under project/public/download/info.pdf
$file= public_path(). "/download/info.pdf";
return response()->download($file);
}

HTML link click
<a class="download" href="{{route('project.download',$post->id)}}">DOWNLOAD</a>
// Route
Route::group(['middleware'=>['auth']], function(){
Route::get('file-download/{id}', 'PostController#downloadproject')->name('project.download');
});
public function downloadproject($id) {
$book_cover = Post::where('id', $id)->firstOrFail();
$path = public_path(). '/storage/uploads/zip/'. $book_cover->zip;
return response()->download($path, $book_cover
->original_filename, ['Content-Type' => $book_cover->mime]);
}

This is html part
<a href="{{route('download',$details->report_id)}}" type="button" class="btn btn-primary download" data-report_id="{{$details->report_id}}" >Download</a>
This is Route :
Route::get('/download/{id}', 'users\UserController#getDownload')->name('download')->middleware('auth');
This is function :
public function getDownload(Request $request,$id)
{
$file= public_path(). "/pdf/"; //path of your directory
$headers = array(
'Content-Type: application/pdf',
);
return Response::download($file.$pdfName, 'filename.pdf', $headers);
}

you can use simply inside your controller:
return response()->download($filePath);
Happy coding :)

If you want to use the JavaScript download functionality then you can also do
<a onclick="window.open('info.pdf) class="btn btn-large pull-right"><i class="icon-download-alt"> </i> Download Brochure </a>
Also remember to paste the info.pdf file in your public directory of your project

Related

How to convert json data in json file in Laravel 5.6

I need convert my json data in file .json. I parsing data to array of json in this code
$movies = Movie::all();
return response()->json($movies);
I need create movies.json file. Where my file must be, which folder? And how to it?
use
use Illuminate\Support\Facades\Storage;
and then
Storage::disk('public')->put('movies.json', response()->json($movies));
and this file will be save in public folder
According to the fact that you want to create the file on the server, maybe you can use the file-storage functions in Laravel like this
use Illuminate\Support\Facades\Storage;
$movies = Movie::all();
Storage::put('Movies.json', $movies);
return true;
In the future, if you want to offer it as a download you can create a response macro. I've done the same for a HTML download
File: App\Providers\AppServiceProvider#boot
\Response::macro('attachment', function ($content) {
$headers = [
'Content-type' => 'text/json',
'Content-Disposition' => "attachment; filename='Movies.json'",
];
return \Response::make($content, 200, $headers);
});
And call it as
return response()->attachment($movies); //App\Providers\AppServiceProvider
in your web.php
Route::get('/download','MoviesController#downloadJSON')->name('download_movies');
paste below code in your controller :
public function downloadJSON(Request $request){
$table = Movie::all();
$filename = "movies.json";
$handle = fopen($filename, 'w+');
fputs($handle, $table->toJson(JSON_PRETTY_PRINT));
fclose($handle);
$headers = array('Content-type'=> 'application/json');
return response()->download($filename,'movies.json',$headers);
}
read more about Response download

Laravel: Refresh response()->file

In Laravel I use this route
Route::get('admin/showBill/{file}','Admin\FileController#showBill');
and this code
class FileController extends AuthController
{
public function showBill($file)
{
$path = storage_path('app/bills/' . basename($file) );
if(!\File::exists($path)) return back();
return response()->file($path);
}
to display a pdf from my storage folder.
So if I have the pdf bill-1.pdf in my /storage/app/bills/ folder, then I can view it with the url
example-domain.com/admin/showBill/bill-1.pdf
The problem is that if I open that pdf with the browser, replace it, and refresh (F5) the page, then the old bill is shown. I guess its because its stored in the cache. Can I force Laravel to show the new replaced file?
I tried
public function showBill($file)
{
$path = storage_path('app/bills/' . basename($file) );
if(!\File::exists($path)) return back();
$path .= '?v='. time();
return response()->file($path);
}
But then Laravel tells me that this file does not exist. I am looking for a solution where I have not to rename the pdf file.
Are you sure you're replacing the right file?
If so, place this dd(). I've created an endpoint, response an empty pdf file - viewed it - replaced it with a content-filled pdf file and it works just fine when I replace it.
Edit: Also, you should validate the $file variable, using either a formrequest or validating in the controller.
public function showBill($file)
{
$path = storage_path('app/bills/' . basename($file));
if(!\File::exists($path)) {
dd("Quite possibly the problem is here, on the redirect back");
}
return response()->file($path);
}

How to hide directory while giving directory Link?

I have build a laravel application where I have some files on public/files directory. if I give this link to others such as download Link, they have chance to know my directory ..
Suppose the link i have to give download link as
www.abc.com/files/45454553535.zip
But i don't want to let Users know that it's there in files directory. So How Do i hide the directory?
Keep your files in the storage directory. That way you can serve the file to the users through code.
Try to follow the documentation: https://laravel.com/docs/5.4/filesystem
I don't know whether this would work or not but giving you an idea. Create a php file use like this:
header('Content-Type: application/zip');
$a=file_get_contents(file.zip)
echo $a;
From this user will not know from where the contents are fetched.
Try this.
public function getDownload()
{
$filename='45454553535.zip'
$file= public_path(). "/files/".$filename;
$headers = array(
'Content-Type: application/zip',
);
return Response::download($file, $filename, $headers);
}
".files/45454553535.zip"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.
return response()->download($file, $filename, $headers);
You can just create a your controller and route.
Route::get('files/{filename}', [
'as' => 'file.get',
'uses' => 'FileController#get',
]);
Controller should check your proper directory. Try to keep your files in storage path, not public.
class FileController extends Controller
{
private $path;
public function __construct()
{
$path = storage_path()
. '/your-valid-directory/';
}
public function get($filename)
{
$file_path = $this->path
. filter_var($filename, FILTER_SANITIZE_STRING);
if (file_exists($file_path) && is_readable($file_path)) {
return response(file_get_contents($file_path), 200, [
'Content-Type: application/zip',
]);
} else {
abort(404);
}
}
}
Now you can get access to specific file by:
{{ route('file.get', ['filename' => '45454553535.zip') }}
This action generate link looks like: your-domain.com/files/45454553535.zip. :)
Anyway in my opinion - in the future just make file factory with specific headers, directories.
Good luck!

Laravel File Downloaded from storage folder gets corrupted

I tried to download jpg/png image from storage folder its gets corrupted after downloaded.
This is my controller
public function download($filename) {
$headers = array(
'Content-Type: image/png',
);
return response()->download(storage_path() . '/'.$filename, 'final.png', $headers);
}
after open it look like this
Even i used core php script to download still iam facing same problem.
I believe that the Laravel framework might be introducing whitespace which might be ruining the header() function.
Use ob_end_clean() before your first header() call to remove any extra whitespace.
add this method before like this
ob_end_clean();
$headers = array(
'Content-Type: image/png',
);
return response()->download(storage_path() . '/'.$filename, 'final.png', $headers);
!enjoy
After Download .jpg,png,gif and .xlsx
Yes ! Its working;
I was reading this problem for 15 days and finally got the solution
Larabel 5.8 & PHP 7.3
public function download_user_photo($id) {
ob_end_clean();
$photo = UserGallery::find($id);
$path = 'storage/users/'.$photo->image_url;
enter code here
if (\File::exists($path)) {
return response()->download($path);
} else {
return redirect()->back()->with('danger', 'Image does not exist.');
}
}

Laravel Response::download not working and pdf file not downloaded when clicked button

I'm trying to achieve a link in a menu bar, such that when a user clicks on the link, a pdf file will be downloaded automatically, and it should not navigate to other pages.
Inside my main.blade.php, consists of a menu bar, I have this link:
Help
where $_SERVER['SERVER_NAME'] is localhost.
Inside my routes.php:
Route::get('/download', array('uses'=>'MainController#getDownloadHelp'));
Inside my controller called MainController:
public function getDownloadHelp()
{
$file= public_path(). "/public/download";
$filename = 'help.pdf';
$headers = array(
'Content-Type' => 'application/pdf',
);
return Response::download($file, $filename, $headers);
}
The PDF file is stored under /public/download/help.pdf
The problem I'm facing right now is, when I clicked the 'Help' link on the menu bar, it redirects me to localhost/download which is not what I wanted. And also, the pdf is not downloaded.
I really need some help here! Where and what did I went wrong?
You can try to use {{ URL::to('/download') }} instead of $_SERVER['SERVER_NAME']...
or in your blade
echo link_to('download', $title, $attributes = array(), $secure = null);
it will write all the <a></a> thing
for the path in the controller maybe you can remove the public in the path of the file like this
public_path() . '/download/';

Categories