How to download image using vue js and laravel - php

I have a hyperlink button on click of this, i want to fetch image from database and get it downloaded on user side with use of laravel and vue js. Below is my code for script file
getImage: function() {
axios.get('/getImage/' + this.form.cashout_id )
.then(function (r)
{
const url = window.URL.createObjectURL(new Blob([r.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.'+r.headers.ext); //or any other extension
document.body.appendChild(link);
link.click();
//hide loader
i.loader = false
})
.catch(function (error) {
alert('Error');
});
},
and now this is my controller code where image is being fetched.
public function getimage($id)
{
$cashout = CashOutDetail::findorfail($id);
$storage_date = Carbon::parse($cashout['recorded_date']);
return response()->download(
storage_path('app/cashoutdetails/'. $storage_date->year .'/' . $storage_date->format('M') . '/'. $cashout->bank_receipt),
'filename.jpg',
['Content-Type' => 'image/jpg']
);
}
Issue is that my image is being fetched and displayed in console window but unable to download. Can anybody help?

You should try:
axios({
method: 'GET',
url: '/getImage/123.jpg',
responseType: 'blob', // <-<<<<<<<<<<
}).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', '123.jpg');
document.body.appendChild(link);
link.click();
});

Related

React native upload image or file via php

i am using document picker to upload an image via php.
this is my js code:
const [singleFile, setSingleFile] = useState(null);
const uploadImage = async () => {
// Check if any file is selected or not
if (singleFile != null) {
// If file selected then create FormData
const fileToUpload = singleFile;
const data = new FormData();
data.append('name', 'imgup');
data.append('attachement_file', fileToUpload);
axios.post(''+ALL.API_URL+'/sellwithus/upload.php', data, {
headers: {
'Content-Type': 'multipart/form-data; ',
}
})
.then((response) => {
console.log(response);
})
} else {
// If no file selected the show alert
alert('Please Select File first');
}
};
the select code:
const selectFile = async () => {
// Opening Document Picker to select one file
try {
const res = await DocumentPicker.pick({
// Provide which type of file you want user to pick
type: [DocumentPicker.types.images],
// There can me more options as well
// DocumentPicker.types.allFiles
// DocumentPicker.types.images
// DocumentPicker.types.plainText
// DocumentPicker.types.audio
// DocumentPicker.types.pdf
});
// Printing the log realted to the file
console.log('res : ' + JSON.stringify(res));
// Setting the state to show single file attributes
setSingleFile(res);
} catch (err) {
setSingleFile(null);
// Handling any exception (If any)
if (DocumentPicker.isCancel(err)) {
// If user canceled the document selection
alert('Canceled');
} else {
// For Unknown Error
alert('Unknown Error: ' + JSON.stringify(err));
throw err;
}
}
};
this is the res result:
console.log(JSON.stringify(res));
res
:[{"size":1454366,"fileCopyUri":null,"name":"D0BED0E3-4567-41DA-9B21-8C409E355A87.JPG","uri":"file:///Users/saeedmatar/Library/Developer/CoreSimulator/Devices/098A7371-530E-4667-AAAF-80EAE97F9A9E/data/Containers/Data/Application/06A2878B-D812-4B3C-BEF0-2E40DBFE9A27/tmp/org.reactjs.native.example.JelApp-Inbox/D0BED0E3-4567-41DA-9B21-8C409E355A87.JPG"}]
this is my php code:
$_POST = json_decode(file_get_contents("php://input"),true);
$imageData=$_POST["_parts"][1][1][0];
file_put_contents('uploads/image.JPG', $imageData["uri"]);
the image that uploaded is 0 mb and not appearing.
how can i use uri to upload the image?
File uri returned by react-native-document-picker is a reference in the device app local cache and can't be used to upload data.
Fetch and upload document BLOB data.
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
};
xhr.onerror = function (e) {
reject(new TypeError("Network request failed"));
};
xhr.responseType = "blob";
xhr.open("GET", [DOCUMENT_PATH_URI_HERE], true);
xhr.send(null);
});
// code to submit blob data
// We're done with the blob, close and release it
blob.close();

Laravel How to create and download PDF from view on same route

I have a laravel-application where I want to generate a PDF from the values, the user has entered in some input fields. So when the user has entered the data, he clicks a button which generates the PDF and downloads it immediately afterwards automatically. All this should happen on the same route/view. The PDF should not be stored somewhere.
So right now, when I click the button, the entered Data gets through, e.g. stored in the DB, and it seems that a PDF is created, but I can't see or find it, and my browser does not inform me that there is a PDF available for download.
Before I started, I installed the laravel-dompdf-plugin, and followed the instructions.
So my route look like this
Route::view('formpage', 'app.statement')->name('statement'); // The blade view with the Form
Route::post('statement', 'MyController#generatePDF')->name('generatePDF'); // this is where I post the form
This is my controller
use PDF;
class MyController extends Controller {
public function generatePDF(Request $request){
$statement = Statement::create([
'name' => $validated['name'],
'email' => $validated['email'],
'phone' => $validated['phone'],
'declaration_date' => $validated['declaration_date'],
]);
$pdf = PDF::loadView('pdf.statement', $statement);
return $pdf->download('File__'.$statement->name.'.pdf');
}
}
I posting the form with javascript by using axios by simply doing this:
$('#submitBtn').click(function(e) {
const formData = new FormData();
formData.append(
"name",
$("#statement")
.find('input[name="name"]')
.val()
);
...etc with all other fields
axios.post($("#statement form").attr("action"), formData)
.then(response => {
$('#submitBtn')
.attr("disabled", "disabled")
.addClass("disabled")
.html('<i class="fas fa-fw fa-check"></i> Success'); */
$("#statement form")[0].reset();
})
.catch(error => {
console.log("ERR: ", error); // DEBUG
$("#statement .text-danger").show();
$('#sworn-statement button[type="submit"]')
.removeAttr("disabled")
.removeClass("disabled")
.html("Send");
});
}
What am I doing wrong?
UPDATE
I tried to do this:
const FileDownload = require("js-file-download");
axios.post($("#statement form").attr("action"), formData)
.then(response => {
FileDownload(response.data,"File.pdf");
}).catch(error => {
console.log('error:', error);
});
which gives me a blank page.
So as I said in the comments your problem is that the file is in the response you get from the axios POST request. If you don't handle the filedownload after you get the response nothing will happen.
You can use the js-file-download module. After you've installed this module you can modify your code to something like this:
const FileDownload = require('js-file-download');
axios.get(YOUR_URL)
.then((response) => {
FileDownload(response.data, YOUR_FILE_NAME);
});
There's also an another solution with JQuery which I got from that answer:
$.ajax({
type: "POST",
url: url,
data: params,
success: function(response, status, xhr) {
// check for a filename
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
var type = xhr.getResponseHeader('Content-Type');
var blob = new Blob([response], { type: type });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
window.navigator.msSaveBlob(blob, filename);
} else {
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
if (filename) {
// use HTML5 a[download] attribute to specify filename
var a = document.createElement("a");
// safari doesn't support this yet
if (typeof a.download === 'undefined') {
window.location = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
}
} else {
window.location = downloadUrl;
}
setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
}
}
});
Just replace the url and params attributes with your stuff. This creates also a POST request and handles the incomming PDF file as filedownload after the response arrives.

docx file download system using laravel - vuejs

I want to send a docx file to the client in the response of a get request:
Here's the Laravel controller code:
public function file($id)
{
$dlink = resource_path('temp/' . $id . '.docx');
$headers = [
'Content-Type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
];
return response()->download($dlink, $id . '.docx', $headers);
}
VueJS code:
axios.get(`${location.protocol}//${location.host}/api/download/${response.data}`,
{ responseType: "arraybuffer" }
)
.then(response => {
this.downloadFile(response);
})
.catch(err => alert(err));
downloadFile(response) {
var newBlob = new Blob([response.body], {
type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
});
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(newBlob);
return;
}
const data = window.URL.createObjectURL(newBlob);
var link = document.createElement("a");
link.href = data;
link.download = "resume.docx";
link.click();
setTimeout(function() {
window.URL.revokeObjectURL(data);
}, 100);
}
It doesn't show any error. but downloads a corrupted 9bytes docx file.
changing response.body to response.data did the job.

Angular 6 CSV download

I'm new to angular, currently i'm working in a project which needs an csv export. Here i'm using Angular 6 as frontend and laravel as backend
This is how i wrote laravel function using mattwebsite/excel
// Lead export to csv
public function downloadExcel(Request $request)
{
$credentials = $request->only('token');
$token = $credentials['token'];
$userid = $this->getUseridFromToken($token);
$type = "xls";
$data = DB::table('user_mailbox AS A')
->select('A.id', 'A.name', 'A.email', 'A.phone', DB::raw('DATE_FORMAT(A.send_on, "%d / %b / %Y") as send_on'), 'B.listing_heading','B.listing_id','B.listing_heading', 'C.name')
->leftjoin('broker_listing AS B', 'B.listing_id', '=', 'A.listing_id')
->leftjoin('users AS C', 'C.id', '=', 'A.sent_by')
->where('A.sent_to', $userid)
->where('A.user_type', '1')
->orderBy('A.id', 'desc')->get()->toArray();
Excel::create('Lead_Export', function($excel) use ($data) {
$excel->sheet('Lead_Export', function($sheet) use ($data)
{
$sheet->fromArray($data);
});
})->download($type);
}
This is how i wrote function in angular component
// Download leads as excel
download_excel(){
const fd = new FormData();
fd.append('token',this.token);
this.brokerleads.downloadLeads(fd).subscribe(
data => this.handleResponsedwnload(data),
error => this.handleErrordwnload(error)
);
}
handleResponsedwnload(data){ console.log('test');
const blob = new Blob([data], { type: 'text/xls' });
const url= window.URL.createObjectURL(blob);
window.open(url);
}
handleErrordwnload(data){
}
service is like this
// Download as excel
downloadLeads(data):Observable<any>{
return this.http.post(`${this.baseUrl}downloadExcel`, data);
}
view
<a class="export-leads" href="javascript:void(0);" (click)="download_excel()" >EXPORT LEADS</a>
while doing this i'm getting response like this but file is not downloading
You need to navigate the browser to the route where the Excel file is made on the backend (in a new tab) either with a link <a href="path" target="_blank"> or with window.open
The ->download() function sets headers so that the file will be automatically downloaded.
When you fetch this data with an AJAX call (which is what HttpClient does) you simply get the binary data returned (which is what you see in your Response tab in Chrome developer tools).
(There are front-end hacks to download a file retrieved by ajax such as creating a link element and clicking it with JavaScript (see below), but they can not be recommended):
let fileName = 'filename.xlsx';
let a = document.createElement('a');
a.href = window.URL.createObjectUrl(responseData);
a.download = fileName;
a.click();
This can also be done using file-saver:
import * as FileSaver from 'file-saver';
this.http.post(`${this.baseUrl}downloadExcel`, data, { responseType: 'blob' })
.subscribe((resp: any) => {
saveAs(resp, `filename.csv`)
});
This function working for me to export csv,
downloadFile(data: any) {
const replacer = (key, value) => value === null ? '' : value; // specify how you want to handle null values here
const header = Object.keys(data[0]);
let csv = data.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','));
csv.unshift(header.join(','));
let csvArray = csv.join('\r\n');
var a = document.createElement('a');
var blob = new Blob([csvArray], {type: 'text/csv' }),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = "myFile.csv";
a.click();
window.URL.revokeObjectURL(url);
a.remove();
}

Download pdf vuejs from API Laravel

hello I have a frontend with VUEJS and backend Laravel 5.4.
I would download a pdf saved in storage/folder/file.pdf
Now I make a ajax call from VUEJS:
downloadAttachment(){
axios.get('/url/attachment/' + this.resource.id)
.then(function (response) {
})
.catch(function (error) {
});
}
and in backend I have a function that return pdf file:
public function download(){
$headers = array(
'Content-Type: application/pdf'
);
return response()->download(storage_path('folder/file.pdf'), 'namefile.pdf' , $headers)->setStatusCode(200);
}
But now How Can i show an Iframe for download in frontend?
I tried with:
var blob = new Blob([response.data],{type:headers['content-type']});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = "Filename";
link.click();
But it doesn't work, How can i show in frontend iframe with pdf file download?
Try this: window.open(URL).
Here the "URL" should be the actual URL string so probably you will have to change the response of the controller to something like: return response()->json(<url string>)

Categories