How to Download a PDF file in the background - javascript

How do I download a file in the background of a mobile browser without leaving the current page.
I've taken a look at this StackOverflow post: easiest way to open a download window without navigating away from the page
which works for displaying the file( in this case a pdf) in the same window using this code:
var file_path = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf';
var a = document.createElement('A');
a.href = file_path;
a.download = file_path.substr(file_path.lastIndexOf('/') + 1);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
This works fine if you want to display the PDF immediately in the current window.
However, how can you keep the current view and have the file download/display a dialogue showing a download in progress?
The goal is to not open a new tab or window to keep the user engaged with the current page. I've looked through S/O & on the web but haven't found a solution to this. Thanks for any solutions to this issue.

you can use HTML web worker https://www.w3schools.com/html/html5_webworkers.asp
var w;
function stopWorker() {
w.terminate();
w = undefined;
}
function downloadPDFBackground() {
if (typeof(Worker) !== "undefined") {
if (typeof(w) == "undefined") {
w = new Worker("pdf_workers.js");
}
w.onmessage = function(event) {
var file_path = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf';
var a = document.createElement('A');
a.href = file_path;
a.download = file_path.substr(file_path.lastIndexOf('/') + 1);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
stopWorker();
};
} else {
document.getElementById("result").innerHTML = "Sorry! No Web Worker support.";
}
}

Related

chart js download to png with canvas.toDataURL() not working in IE and firefox

I am using canvas.toDataURL() to download chart.js chart ,it is perfectly working with chrome but not working with IE and Firefox.here is my code
var link = document.createElement('a');
var canvas = document.getElementById('canvasId');
link.href = canvas.toDataURL("image/png");
link.download = 'IMAGE.png';
link.click();
Thank you.
var canvas = document.getElementById('canvasId');
if(canvas.msToBlob){
var blob = canvas.msToBlob();
window.navigator.msSaveBlob(blob, 'image.png');
}
else{
var link = document.createElement('a');
link.href = canvas.toDataURL("image/png");
link.download = 'IMAGE.png';
document.body.append(link);
link.click();
}
The anchor tag you are creating also needs to be added to the DOM in Firefox and IE, in order to be recognized for click events.
In Firefox, you need to do the link.click (though you may not want to do that in Chrome as it results in a double download). However, IE (except for the latest versions of Edge) doesn't support the "download" attribute on the a tag, and you need to save the canvas slightly differently.
var canvas = document.getElementById('canvasId');
var isIE = !!navigator.userAgent.match(/Trident/g) || !!navigator.userAgent.match(/MSIE/g);
if (!isIE) {
let image = canvas.toDataURL("image/jpeg", 1.0);
// we are getting the a tag to add the 'download' attribute and the file contents
let downloadLink = document.getElementById("download");
downloadLink.setAttribute("download", downloadFileName);
downloadLink.setAttribute("href", image);
// For some reason, we need to click the button again in firefox for the download to happen
if (navigator.userAgent.match(/Firefox/g)) {
downloadLink.click();
}
}
if (isIE) {
var blob = canvas.msToBlob();
window.navigator.msSaveBlob(blob, downloadFileName);
}
In the Chart.js API documentation there is a built in function called .toBase64Image() which you may wish to use instead, as you've outlined your file extension as being .png.
As Becky stated above, in Firefox, link.click() needs to be used in order for the file to download. However, the element we created (link) needs to be appended to the body of your HTML document in order for link.click() to function as required. It is important that once this statement has been executed, to remove the link element from your HTML document, so your HTML body doesn't accumulate these elements every time you try to download a chart. IE requires the canvas to be saved differently through the blob functions.
let canvas = document.getElementById('canvasId');
let chart_name = = new Chart(canvas, config);
var isIE = !!navigator.userAgent.match(/Trident/g) || !!navigator.userAgent.match(/MSIE/g);
if (!isIE) {
// Create a hyperlink element.
let link = document.createElement('a');
// Set image URL and filename.
link.href = chart_name.toBase64Image();
link.download = 'IMAGE.png';
// If browser is Firefox, the element we created above must be appended to the
// body of the HTML document & therefore removed after.
if (navigator.userAgent.match(/Firefox/g)) {
document.body.append(link);
link.click();
document.body.removeChild(link);
}
}
if (isIE) {
var blob = canvas.msToBlob();
window.navigator.msSaveBlob(blob, 'IMAGE.png');
}

html2canvas combined with watermarkjs

currently I am making a download button on my page via html2canvas, which I successfully got working. But now I want to add a watermark to it before I download it. After a quick google search the watermarkjs library popup, which adds a watermark to image, but I want to add it to a dataURL or canvas before I transform it. Is there a way to do it?
My not functional code:
var watermarkImage = "https://pravdaovode.cz/wp-content/uploads/2018/07/vodoznak.png";
function getScreen() {
html2canvas(div_box).then(function(canvas) {
if ('msToBlob' in canvas) {
var blob = canvas.msToBlob();
navigator.msSaveBlob(blob, 'pravda_o_vode_cenova_mapa.jpg');
}
else {
var a = document.createElement('a');
a.setAttribute('href', watermark([canvas.toDataURL("image/jpeg").replace("image/jpeg", "image/octet-stream"), watermarkImage]));
a.setAttribute('target', '_blank');
a.setAttribute('download', 'pravda_o_vode_cenova_mapa.jpg');
a.style.display = 'none';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
});
}

Save high-res image html5/threejs-canvas

I found and edited below code to save my html5 canvas as a .png-image. The canvas is generated by Three.js/Potree.
This code works perfectly. But, I want a higher resolution image as an output. Usually, the THREEjs renderer is sized according to the clients browser size. I have already manually enlarged it to 3000x2000. This edit will give a higher-resolution image, but when increasing more no effects are visible anymore.
Is there a simple (I'm not that into javascript..) workaround for downloading a high-resolution output image?
At first, the images are just for me. No user needs to download it or needs to pass it onto the server. Although, if its a neat solution, I'd like to give the user the possibility to save their image as well.
function saveAsImage() {
var strDownloadMime = "image/octet-stream";
//alert("function saveimage")
var imgData, imgNode;
try {
var strMime = "image/png";
imgData = viewer.renderer.domElement.toDataURL(strMime);
saveFile(imgData.replace(strMime, strDownloadMime), "test.png");
} catch (e) {
console.log(e);
return;
}
}
var saveFile = function (strData, filename) {
//alert("savefilefunction");
var link = document.createElement('a');
if (typeof link.download === 'string') {
document.body.appendChild(link); //Firefox requires the link to be in the body
link.download = filename;
link.href = strData;
link.click();
document.body.removeChild(link); //remove the link when done
} else {
location.replace(uri);
}
}
THREE Renderer settings:
let width = 3000;
let height= 2000;
this.renderer = new THREE.WebGLRenderer({premultipliedAlpha: false, preserveDrawingBuffer: true});
this.renderer.setSize(width, height);

Three JS Javascript Save Canvas as JPG with EXIF Colorspace

This function works great in three.js for saving a canvas image as a JPG snapshot. A few issues though. The image doesn't save with any exif data, no colorspace ect so browsers treat the image colors randomly when uploaded, it often looks very desaturated when uploaded to the web. Is there an easy way to add the exif data to the .jpg image when saving it to add the color profile sRGB IEC61966-2.1? Also, for some reason this doesn't work at all in IE? Throws the error uri is undefined, which it is. Can't figure out what uri should be. Thanks for any help!
function saveAsImage() {
var imgData, imgNode;
try {
var strMime = "image/jpeg";
imgData = renderer.domElement.toDataURL(strMime);
saveFile(imgData.replace(strMime, "image.jpg");
} catch (e) {
alert(e);
console.log(e);
return;
}
}
var saveFile = function (strData, filename) {
var link = document.createElement('a');
if (typeof link.download === 'string') {
document.body.appendChild(link); //Firefox requires the link to be in the body
link.download = filename;
link.href = strData;
link.click();
document.body.removeChild(link); //remove the link when done
} else {
location.replace(uri);
}
}

How to prevent blob + guid in browser title

Basically, what I am doing is generating a PDF file on the server and showing it in the browser via javascript like this:
file = new window.Blob([data], { type: 'application/pdf' });
var fileUrl = URL.createObjectURL(file);
var wnd = window.open(fileUrl, "_blank", "location=no, fullscreen=yes, scrollbars=auto, width=" + screen.width + ",height=" + screen.height);
All this works fine but every browser is showing an ugly subtitle (something like this): blob:2da57927-311e-4b3d-a261-d2679074802c
Is there any way to get rid of this subtitle or to replace it with something meaningful?
Edited:
Here is a screen capture of the improved code (after applying VisioN's suggestion):
As I mentioned in the comments, one possible way is to make an <iframe> in the popup window, that displays the current Blob data, and to style the popup as you wish:
var win = open('', 'name', 'height=300, width=300'),
iframe = document.createElement('iframe'),
title = document.createElement('title'),
file = new Blob([data], { type: 'application/pdf' }),
fileUrl = URL.createObjectURL(file);
title.appendChild(document.createTextNode('Nice title :)'));
iframe.src = fileUrl;
iframe.width = '100%';
iframe.height = '100%';
iframe.style.border = 'none';
win.document.head.appendChild(title);
win.document.body.appendChild(iframe);
win.document.body.style.margin = 0;
DEMO: http://jsfiddle.net/MeY9e/
You can simply add a settimeout to change the page title after the blob has been loaded in the new tab like this -
newTab.location.href = URL.createObjectURL(blob);
setTimeout(function() {
newTab.document.title = blob.name;
}, 10);

Categories

Resources