Programmatically download the QR image - javascript

I tried to create a QR code with QRcode.js library. As of the UI, I can manually click on the button download to download it but I would to download automatically without clicking the button.
Base on my code bellow.
function genQR(link_string){
let qr_code_element = document.querySelector(".qr-code");
if (link_string != "") {
if (qr_code_element.childElementCount == 0) {
generate(qr_code_element, link_string);
} else {
qr_code_element.innerHTML = "";
generate(qr_code_element, link_string);
}
} else {
alert("not valid QR input");
qr_code_element.style = "display: none";
}
}
function generate(qr_code_element, link_string) {
qr_code_element.style = "";
var qrcode = new QRCode(qr_code_element, {
text: link_string,
width: 200,
height: 200,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel: QRCode.CorrectLevel.H
});
let download = document.createElement("button");
// qr_code_element.appendChild(download);
let download_link = document.createElement("a");
download_link.setAttribute("download", "qr.png");
download_link.setAttribute("id", "downloadbtn");
download_link.innerText = "Download";
// download.appendChild(download_link);
let qr_code_img = document.querySelector(".qr-code img");
let qr_code_canvas = document.querySelector("canvas");
if (qr_code_img.getAttribute("src") == null) {
setTimeout(() => {
download_link.setAttribute("href", `${qr_code_canvas.toDataURL()}`);
}, 300);
} else {
setTimeout(() => {
download_link.setAttribute("href", `${qr_code_img.getAttribute("src")}`);
}, 300);
}
var clickEvent = new MouseEvent("click", {
"view": window,
"bubbles": true,
"cancelable": false
});
//I expect the below line will automatically download the QR but nothing fires.
download_link.dispatchEvent(clickEvent);
}
If I use button to click and download by hand will works fine for me but I want to reduce too many steps.
I think I almost done here but failed.
Could anyone show me how to automatic download?
Thank you in advance.

I've had this issue in the past, and I've worked around it by creating a small util function I can invoke upon button pressing. But invoking it directly at the end of your function should have the same result as a user click, effectively automatically downloading the QR code without user input.
export function download(blob, filename) {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = filename
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}
I'm guessing you could try passing generate as the first parameter if the object you're getting is a Blob. Otherwise, you'll probably need to convert it before.

I done my target by adding the source you shared at the bottom of my code and then added this function to convert dataURL to Blob
function dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
var blob = new Blob([ab], {type: mimeString});
return blob;
}
Thank you very much #Gianmarco Rengucci
I rate for you

Related

How to fix string saving as code to word?

I have the following code:
function downloadNotes() {
var information = document.getElementById("text").innerHTML;
var textToBLOB = new Blob([information], { type: 'text/plain' });
var sFileName = 'formData = document.doc';
var newLink = document.createElement("a");
newLink.download = sFileName;
if (window.webkitURL != null) {
newLink.href = window.webkitURL.createObjectURL(textToBLOB);
}
else {
newLink.href = window.URL.createObjectURL(textToBLOB);
newLink.style.display = "none";
document.body.appendChild(newLink);
}
newLink.click();
}
When I save my notes, it successfully saves it to word, but when I open it, it shows the code all compressed rather than the string output:
Here.
Change this line:
var information = document.getElementById("text").innerHTML;
To this:
var information = document.getElementById("text").innerText;
Your code was reading the HTML content of the element instead of the Text value of the element. If this doesn't work you may need to code it to cut out the HTML.

window.open(url) only open new window with raw text instead of downloading

When I use the following method :
downloadFile(){
const blob = this.b64toBlob(this.formGroup.value.attachment);
const url = window.URL.createObjectURL(blob);
window.open(url);
}
I'm expected it to open a new tab and download the file.
But it's only opening a new tab with raw text content inside.
This is the result I get.
But if I copy/paste the content of the page as an URL, it's working great and my download is starting as expected.
What am I suppose to do to start the download directly.
PS: this is the b64toBlob() method :
b64toBlob(b64Data: string, contentType = '', sliceSize = 512): Blob {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
return new Blob(byteArrays, {type: contentType});
}
Instead of using URL, create a href out of it and you can use the respective click function. Please change the below function of yours something like below and hopefully, you can download the file.
downloadFile(){
var a: any = document.createElement("a");
a.setAttribute('style', 'display:none;');
const blob = this.b64toBlob(this.formGroup.value.attachment);
const url = window.URL.createObjectURL(blob);
a.href = url;
a.click();
}
Sometimes this click won't work properly in IE. In that case you can use msSaveBlob function. The whole function can be changed like,
downloadFile() {
var a: any = document.createElement("a");
a.setAttribute('style', 'display:none;');
document.body.appendChild(a);
const blob = this.b64toBlob(this.formGroup.value.attachment);
const url = window.URL.createObjectURL(blob);
a.href = url;
var isIE = /*#cc_on!#*/false || !!(<any>document).documentMode;
if (isIE) {
var retVal = navigator.msSaveBlob(blob, "test"+ '.txt');
}
else {
a.download = "test" + '.txt';
}
a.click();
}
So after few more hours of research...
I managed to get this to work as expected.
Posting the answer if someone end up with the same issue :
downloadFile() {
const blob = this.b64toBlob(this.formGroup.value.attachment);
blob.text().then(result => { // waiting for blob content to be available...
const a: any = document.createElement('a');
a.download = 'test.pdf'; // or whatever your file name is
a.href = result;
a.click();
});
}
The line a.download = 'test.pdf' seem mandatory on chrome but working fine without it for Firefox.
Hope this will help others.

using web-dictaphone need to save audio to server

I have the web-dictaphone working: https://github.com/mdn/web-dictaphone/
My goal is to have it work just like it does by default, but I want to add a save button that will save the recorded file onto the wordpress server.
Anyone have any suggestions on how to do this? Here is the code that executes after recording,
I imagine I need to do something with the audioURL and use something like file_put_contents() in php. I'm not sure if I need to convert to base64 or anything? Any help is appreciated, thanks.
mediaRecorder.onstop = function(e) {
console.log("data available after MediaRecorder.stop() called.");
const clipName = prompt('Enter a name for your sound clip?','My unnamed clip');
const clipContainer = document.createElement('article');
const clipLabel = document.createElement('p');
const audio = document.createElement('audio');
const deleteButton = document.createElement('button');
clipContainer.classList.add('clip');
audio.setAttribute('controls', '');
deleteButton.textContent = 'Delete';
deleteButton.className = 'delete';
if(clipName === null) {
clipLabel.textContent = 'My unnamed clip';
} else {
clipLabel.textContent = clipName;
}
clipContainer.appendChild(audio);
clipContainer.appendChild(clipLabel);
clipContainer.appendChild(deleteButton);
soundClips.appendChild(clipContainer);
audio.controls = true;
const blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
chunks = [];
const audioURL = window.URL.createObjectURL(blob);
audio.src = audioURL;
console.log("recorder stopped");
deleteButton.onclick = function(e) {
let evtTgt = e.target;
evtTgt.parentNode.parentNode.removeChild(evtTgt.parentNode);
}
clipLabel.onclick = function() {
const existingName = clipLabel.textContent;
const newClipName = prompt('Enter a new name for your sound clip?');
if(newClipName === null) {
clipLabel.textContent = existingName;
} else {
clipLabel.textContent = newClipName;
}
}
}
It is not needed to convert to base64, just append blob to an instance of the FormData class and send.
var formData = new FormData();
formData.append('attachment', blob);
var request = new XMLHttpRequest();
request.open('POST', 'URL', true); // edit URL
request.onload = function() { console.log("Status: %s", request.responseText) };
request.send(formData);
On the backend side, receiving can be archived with $_FILES and move_uploaded_file() like a normal upload procedure.

How to convert base64 byte data into downloadable pdf file?

I have an encoded base64 data from an API response and stored in a variable encodedBase64.
let encodedBase64 = 'some base64 encoded long data';
function base64ToArrayBuffer(base64) {
var binaryString = window.atob(base64);
console.log('binaryString ', binaryString);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes;
}
function saveByteArray(reportName, byte) {
var blob = new Blob([byte], {type: "application/pdf"});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
var fileName = reportName;
link.download = fileName;
link.click();
};
var sampleArr = base64ToArrayBuffer(encodedBase64);
saveByteArray("Sample Report", sampleArr);
after executing this code i am able to download pdf file names SampleReport.pdf but when i open this it is showing Failed to load PDF document. error
what is the wrong in my code ?
difficult to get it done using front end side
but it can be done easily using Nodejs using the following code.
fs.writeFile('pdfFileName.pdf', base64DataString, {encoding: 'base64'}, error => {
if (error) {
throw error;
} else {
console.log('buffer saved!');
}
});

Blob download not triggered on Windows Phone

I'm currently creating something that generates a PDF / CSV file on local and makes it available to download. My current code is working everywhere except on Windows Phone (especially Lumia) which seems to not handle BLOB Url.
How could I fix this issue and force the download?
vm.showPdf = function (documentKey) {
var requestPayloadForShowPdf = {
"DocumentList": documentKey,
"AccountNumber": selectedAccountNumber
};
documentsService.getPdf(requestPayloadForShowPdf).then(function (obj) {
if (!obj.HasErrors) {
vm.isdispalyApiErrorMessage = false;
var byteCharacters = atob(obj.PdfDocument);
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
var byteArray = new window.Uint8Array(byteNumbers);
var blob = new Blob([byteArray], {
type: 'application/pdf'
});
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, "Statements(" + utilService.getLastFourDigits(selectedAccountNumber) + ").pdf");
} else {
var url = window.URL.createObjectURL(blob);
window.open(url);
}
} else {
vm.isdispalyApiErrorMessage = true;
vm.dispalyApiErrorMessage = utilService.getLiteralFromTranslate('stndrdAPIErrorMsg');//documentsResponse.Errors[0].Description;
}
});
};

Categories

Resources