I am using maatwebsite to export the records to CSV file. Using php laravel for backend.
Here is my following code:
Controller code:
public static function exportCsvReport($params){
header('Content-Encoding: UTF-8');
header('Content-type: text/csv; charset=UTF-8');
return Excel::download(new UsersExport, 'invoices.xlsx');
}
UserExport model:
<?php
namespace App\Exports;
use App\Models\Api\v1\Tbcall;
use Maatwebsite\Excel\Concerns\FromCollection;
class UsersExport implements FromCollection
{
public function collection()
{
return Tbcall::where('Row_Id',14407)->get();
}
}
?>
React code:
exportReporttoCsv(params){
this.setState({ isDataFetched: true }, async () => {
let productsData = await this.apiService.exportCsvReport(params);
const url = window.URL.createObjectURL(new Blob([productsData.data]));
const link = document.createElement('a');
link.setAttribute('href', 'data:text/csv');
link.href = url;
link.setAttribute('download', 'aaa1.csv'); //or any other extension
document.body.appendChild(link);
link.click();
});
}
Output:
Tried in notepad as well. Still shows the encoded data.
File is getting downloaded but when opening the file shows like these.
Not getting what is going wrong. What changes are needed here ? Any answers will be appreciated. Thanks
#Nkunj Can you open in notepad and see, issue must be in your excel settings.
ok you can try this :
http://danml.com/download.html
Related
this question is related to: Laravel - Force download with response()->download($fileLocation) not working
The problem is, that I use a axios GET request (as mentioned in that thread) to initiate the browser download but it is not working. My Controller works perfectly and it returns the file correctly as I can see in the browser console:
The request:
The response
The image
But the browser is not starting any download.
I am using Vue/Nuxt on client-side and the axios request is called like this:
download ({
dispatch,
commit,
rootState,
rootGetters
}) {
this.$axios.get('api/download',
{
params: {
filenames: rootGetters['files/getDownloadFilenames'],
mode: rootState.config.mode
}
}).then((response) => {
console.log(response)
}).catch((error) => {
console.log(error)
})
}
And the controller #laravel is called with the "getFileDownload" function:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
class DownloadController extends Controller
{
public function getFileDownload(Request $request) {
$filenames = $request->input('filenames');
$mode = $request->input('mode');
$filePaths = [];
foreach($filenames as $filename) {
if ($mode == 'clean') {
array_push($filePaths, $request->user()->getName() . config('filesystems.transfer_out_clean') . '/' . $filename);
return response()->download($filePaths[0]);
}
}
}
}
The reason I am using an array here is that later on I want to return a ZIP file containing multiple files, but as you can see I am just using the first path to return a single file for testing purposes.
So my question is: Why isn't this request starting a download of that image file on the client even if I use a GET request?
Any help much appreciated!
I have a file download function that works well on Firefox and Safari, but if I try to download the same file on Chrome or MS Edge, the file is downloaded without an extension.
Here's the function
public function download_chapter_file(Downloadable $downloadable, Request $request): StreamedResponse
{
if (!$request->hasValidSignature()) abort(401);
$headers = ['Content-Type' => 'application/'.$downloadable->type];
return Storage::download($downloadable->path,$downloadable->title,$headers);
}
$downloadable->type is either excel or pdf.
$downloadable->path is the full file path. eg storage/app/public/downloadable/chapters/9/ycCjt0K911x3b1aFjX8i0S9Jj8.pdf
I have tried using
return response()->download(); but it does not solve the problem.
I'd appreciate your help.
try this , it work with me :-
$headers = array(
'Content-Type: application/pdf',
);
return Response::download($downloadable->path,$downloadable->title,$headers);
After hours of trials. I finally got a working solution.
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\StreamedResponse;
class StorageController extends Controller
{
public function download_chapter_file(Downloadable $downloadable, Request $request):StreamedResponse
{
if (!$request->hasValidSignature()) abort(401);
$extension = File::extension(storage_path('app/'. $downloadable->path));
$filename = $downloadable->title.'.'.$extension;
return Storage::download($downloadable->path,$filename);
}
}
Thank you all for trying
I'm working on a laravel project and inside the project i store .pdf files to my local phpmyadmin and retrieve it back to display in the browser.
I see some applications but they're saving the .pdf files locally while uploading it to DB. And then it becomes so easy to display with <img src=""> but i don't want to use this.
These are my routes;
Route::get('/users/{user}/posts', 'PostController#index');
Route::get('/posts/create', 'PostController#create');
Route::post('/posts', 'PostController#store');
And index function;
public function index(User $user, Post $posts)
{
$posts = DB::table('posts')
->where('userId', '=', $user->id)
->get();
return view('post.index', compact('posts'));
}
I can upload and store .pdf files that OK but cannot display in the browser.
So I want to get the record with index function in PostController(which is done already) and display the .pdf file in index.blade.php file which comes from db.
like this: http://localhost/test.pdf
When i display it in the browser i can see only it's name. How can i read the file that i get it from db?
Thank you for your answers.
First of all, in my opinion, you should store the files into the storage system of laravel and not in the database.
But if you want to do it with the database here is an example to output a file which is stored into a blob field of the database (for example in the content field of the files table).
Another not-so-pretty method is to convert the file into a base64 string and store in a text field, see more here.
Schema for 'db_files' table
field | type
----------|-------------
id | BIGINT
name | VARCHAR(255)
content | BLOB
mime_type | VARCHAR(255)
Routes
Route::get('/files/{id}', 'FileController#show')->name('file.show');
DbFile Model
use Illuminate\Database\Eloquent\Model;
class DbFile extends Model {
// ...
}
FileController
public function show($id) {
$dbFile = DbFile::firstOrFail($id);
// the $dbFile->mime_type should be 'application/pdf' for pdf files
// the $dbFile->name should be in this schema 'document.pdf'
return response($dbFile->content)
->withHeaders([
'Content-type: ' . $dbFile->mime_type,
'Content-Disposition: attachment; filename=' . $dbFile->name
]);
}
View
Show Document
I can't test the code right now. Let me know if something goes wrong.
There is a way worked with me to solve this problem by change the extension of file from
pdf to pdfz or any else extension and use this code
$realPath="path file with pdfz extension";
if(file_exists($realPath)){
$realPath=str_replace(".pdf",".pdfz",$realPath);
$file =$realPath;
$filename = $realPath;
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
header('Accept-Ranges: bytes');
#readfile($file);
exit;
}else{
echo "$realPath:No File Exist";
}
the goal of changing of extension is to protect from force downloading by IDM
$(function() {
let pdfDoc = null,
pageNum = 1,
pageRendering = false,
pageNumPending = null;
const scale = 5.0,
canvas = document.getElementById('pdf-canvas'),
pnum = document.getElementById('page-num')
ctx = canvas.getContext('2d');
/**
* Get page info from document, resize canvas accordingly, and render page.
* #param num Page number.
*/
function renderPage(num) {
pageRendering = true;
// Using promise to fetch the page
pdfDoc.getPage(num).then(function(page) {
const page_viewport = page.getViewport(scale);
canvas.height = page_viewport.height;
canvas.width = page_viewport.width;
// Render PDF page into canvas context
const renderContext = {
canvasContext: ctx,
viewport: page_viewport
};
const renderTask = page.render(renderContext);
// Wait for rendering to finish
renderTask.promise.then(function() {
pageRendering = false;
if (pageNumPending !== null) {
// New page rendering is pending
renderPage(pageNumPending);
pageNumPending = null;
}
});
});
// Update page counters
$(pnum).text(num);
}
/**
* If another page rendering in progress, waits until the rendering is
* finised. Otherwise, executes rendering immediately.
*/
function queueRenderPage(num) {
if (pageRendering) {
pageNumPending = num;
} else {
renderPage(num);
}
}
/**
* Displays previous page.
*/
$(".carousel-control-prev").click(function() {
if (pageNum > 1) {
pageNum--;
queueRenderPage(pageNum);
}
});
/**
* Displays next page.
*/
$(".carousel-control-next").click(function() {
if (pageNum < pdfDoc.numPages) {
pageNum++;
queueRenderPage(pageNum);
}
});
/**
* Asynchronously downloads PDF.
*/
(function() {
const url = $(canvas).data("file");
pdfjsLib.getDocument(url).then(function(pdfDoc_) {
pdfDoc = pdfDoc_;
$("#page-count").text(pdfDoc.numPages);
// Initial/first page rendering
renderPage(pageNum);
});
})();
});
I have a few lines of code which is written in express js, I want to convert into the laravel code,
app.get('/*', function(req, res) {
var jsonResponse = [];
jsonResponse.push({ "text": "Hi. 3 is a lucky number..." });
res.send(jsonResponse);
});
Is there anyway? Please guide me.
Here is my tried , don't know correct or not.
public function json_test(){
$message =["text" => "Hi. is a lucky number..."];
return $message;
}
Long story short
I think everything is correct. You just have to change your return value to be a json response.
A bit more detailed
You must first define a route in api.php:
Route::get('/some/url', 'ExampleController#jsonTest');
Next you must define a controller and inside the controller the functions that you need:
<?php
namespace App\Http\Controllers;
class ExampleController extends Controller
{
public function jsonTest(){
$message =["text" => "Hi. is a lucky number..."];
return response()->json($message);
}
}
In case you don't need an entire controller for this you can simply place the functionality in the api.php file like so:
Route::get('/some/url', function () {
$message =["text" => "Hi. is a lucky number..."];
return response()->json($message);
});
Hope this helps.
this is a call to a controllers function :
function downloadFile(fn,con)
{
var loadUrl = "/Fast-Docs/index.php/Docs/downloadFile";
alert('hi');
$.post(
loadUrl,
{content: con, filename: fn});
}
controllers function :
public function downloadFile()
{
$this->load->helper('download');
$content=$this->input->post('content');
$fn=$this->input->post('filename');
return force_download($fn,$content);
}
but file is not downloading.
i know the reason why its not working but i dnt know how to fix it. so whats the solution. you need some more info , feel free to ask.
I don't completely understand what you are trying to do. Anyway, there is a fundamental problem in your code.
You are doing an ajax request to the "/Fast-Docs/index.php/Docs/downloadFile" URL, but you are ignoring the response.
My suggestion is: forget about ajax and use a simple link.
Download file
Then in the controller:
public function downloadFile($filename)
{
//Validate file name
if($filename != 'validFileName') die('Invalid file name');
//Set headers
$this->load->helper('download');
$content = file_get_contents('/images/' . $filename);
force_download($filename, $content);
}
If for some reason you can't use a link, you can redirect to the download page (by setting window.location).
If you really need to use ajax, give a look at this.