How to Print Pdf in Angular 2 - javascript

I have URL of pdf file for exa url is "test.example.com/incoice/1/download?auth_token="some_token", when I visit this url, url will show me PDF in browser.
Now I want to open this pdf with print function, I mean user do not have to press CTRL+P I want to do this from my side.
I tried iframe but it gives me error of cross origin.
This is demo code which i used
//first try
let _printIframe;
var iframe = _printIframe;
if (!_printIframe) {
iframe = _printIframe = document.createElement('iframe');
document.body.appendChild(iframe);
iframe.style.display = 'none';
iframe.id = "printf";
iframe.name = "printf";
iframe.onload = function() {
setTimeout(function() {
iframe.focus();
iframe.contentWindow.print();
}, 1);
};
}
// second try
// SRC of pdf
iframe.src = "Some API URl " + "/download?access_token=" +
this.authenticationService.currentTokenDetails.access_token;
let url = iframe.src + "&output=embed";
window.frames["printf"].focus();
window.frames["printf"].print();
var newWin = window.frames["printf"];
newWin.document.write('<body onload="window.print()">dddd</body>');
newWin.document.close();
I created a demo in plunker for print pdf. http://embed.plnkr.co/WvaB9HZicxK6tC3OAUEw/ In this plunker i open pdf in new window but i want to directly print that pdf. how can i do that ?
Any suggestion will be appreciate, and you can correct if I am wrong.
Thanks

So here I got the solution for my problem
In my situation my API was returning binary data of pdf, and browser did not print that binary data into window.print, so for this first I convert binary data in blob data and then create Iframe for print
Following is code for it.
const url = request URL // e.g localhost:3000 + "/download?access_token=" + "sample access token";
this.http.get(url, {
responseType: ResponseContentType.Blob
}).subscribe(
(response) => { // download file
var blob = new Blob([response.blob()], {type: 'application/pdf'});
const blobUrl = URL.createObjectURL(blob);
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = blobUrl;
document.body.appendChild(iframe);
iframe.contentWindow.print();
});
Here you go!!
I hope this can help anyone have this problem :)

The previous solution may cause some security issues in newer browsers so we need to use the DOMSanitizer to make it a safe resource.
export class PrintPdfService {
constructor(protected sanitizer: DomSanitizer) {}
printPdf(res) {
const pdf = new Blob([res], { type: 'application/pdf' });
const blobUrl = URL.createObjectURL(pdf);
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = this.sanitizer.sanitize(SecurityContext.RESOURCE_URL, this.sanitizer.bypassSecurityTrustResourceUrl(blobUrl));
document.body.appendChild(iframe);
iframe.contentWindow.print();
}
}
Angular DOMSanitizer

Look at https://github.com/devintyler/real-time-angular2/tree/master/plugin/print-pdf
simple and nice implementation.

Related

cannot download file from BlobUrl (using MediaReader)

I have the following code:
let self = this;
this.chunks = [];
const canvas2 = document.getElementById("self-canvas");
let recordStream = canvas2.captureStream(1);
var options;
options = {mimeType: 'video/webm; codecs=vp9'};
this.recorder = new MediaRecorder(recordStream, options);
this.recorder.ondataavailable = function(evt) {
self.chunks.push(evt.data);
};
this.recorder.onstop = function(evt) {
console.log("recorder stopping");
const link = document.createElement('a');
const videoBlob = new Blob(self.chunks, { type: "video/webm" });
console.log("file size: " + videoBlob.size);
const url = URL.createObjectURL(videoBlob);
link.href = url;
link.download = "sample.webm";
document.body.append(link);
link.click(); //if I comment out here I can see the video
};
console.log("finished setting controller")
console.log("recorder starting");
this.recorder.start(10000);
// the recorder.stop is called somewhere else
What it is supposed to do is pretty simple:
I have the element with id "self-canvas" that is showing my camera.
Now I am trying to record the camera and download the video from the browser using MediaRecorder, but for some reason I am unable to download the file.
I am sure that the file is being recorded, and console.log("file size: " + videoBlob.size); does not return empty.
But when I let the code run, instead of downloading the file, it tries to open it on the same window, and I cannot even see the video because the previous window disappears with the data of the recording.
However if I comment out the link.click(); I am able to see the video by opening the link on a new page (without closing the previous one). But it still doesn't download...
I used this as example, what am I doing wrong?
For heaven's sake...
I just added target blank and it worked.
link.href = url;
link.download = "sample.webm";
link.target = '_blank';
Probably because the resources are lost if it tries to open on the same page, and because it doesn't actually download the file if it is not a link "click".
Still, I never saw anyone having to add target blank in their examples like this one.
So I wonder why this is the case only for me...

How to print untrusted html blob in Javascript

I am loading a blob from an API with content type text/html, this blob is completely based on user-input and therefore not trusted, it may contain e.g malicious script that grabs the access_token from local_storage and sends it to some web server.
What's the best practice for safely printing such a blob?
My code currently loads the blob in a hidden sandboxed iFrame and calls print(). However a perfect sandbox will prevent calling print() on the iFrame content, so I had to add 'allow-same-origin' and 'allow-modals' exceptions to the sandbox. But I am not sure if or how those exceptions compromise security:
/**
* Attaches the given blob in a hidden iFrame and calls print() on
* that iFrame, and then takes care of cleanup duty afterwards.
* This function was inspired from MDN: https://mzl.la/2YfOs1v
*/
export function printBlob(blob: Blob): void {
const url = window.URL.createObjectURL(blob);
const iframe = document.createElement('iframe');
iframe.onload = setPrintFactory(url);
iframe.style.position = 'fixed';
iframe.style.right = '0';
iframe.style.bottom = '0';
iframe.style.width = '0';
iframe.style.height = '0';
iframe.style.border = '0';
iframe.sandbox.add('allow-same-origin');
iframe.sandbox.add('allow-modals');
iframe.src = url;
document.body.appendChild(iframe);
}
function setPrintFactory(url: string): () => void {
// As soon as the iframe is loaded and ready
return function() {
this.contentWindow.__container__ = this;
this.contentWindow.__url__ = url;
this.contentWindow.onbeforeunload = closePrint;
this.contentWindow.onafterprint = closePrint;
this.contentWindow.focus(); // Required for IE
this.contentWindow.print();
};
}
function closePrint() {
// Cleanup durty once the user closes the print dialog
document.body.removeChild(this.__container__);
window.URL.revokeObjectURL(this.__url__);
}
Thanks for your help,

render blob to popup div instead of opening in new window

Currently I can download a blob and render it in a new window like this:
const blob = new Blob([downloadEvent.response], { type: mimeType });
const URL = window.URL || (window as any).webkitURL;
const blobUrl = URL.createObjectURL(blob);
window.open(blobUrl);
Is it possible to somehow open the blob in a popup div instead of a new window.
Using an iframe should work:
const iframe = document.createElement("iframe");
iframe.src = blobUrl;
/*your favorite DOM node */.appendChild(iframe);

Open Play Store on component load in Mobile Browser

I want to open Play Store on ngOnInit.
I have tried every combination but host name is added automatically.
myComponent.ts
var url1 = 'market.android.com/details?id=com.test&referrer=' + sponser;
window.open(url1, '_blank') //try1
$.get(url1, function () { /!*callback*!/
}); //try2
const link = document.createElement('a');
link.target = '_top';
link.href = url;
link.setAttribute('visibility', 'hidden');
link.click();//try3
But none of them are working. Thanks in advance.

display byte array as pdf in browser i tried several options from stack overflow but it did not work for me

I am getting following response which is in json format
{"filename":"copyofabc.pdf","filedata":[37,80,68,70,45,49,46,53,13,10,37,-75,-75,-75,-75,13,10,49,32,48,32,111,98,106,13,10,60,60,47,84,121,112,101,47,67,97,116,97,108,111,103,47,80,97,103,101,115,32,50,32,48,32,82,47,76,97,110,103,40,101,110,45,73,78,41,32,47,83,116,114,117,99,116,84,114,101,101,82,111,111,11.....]}
enter code here
var blob = new Blob($(this).attr('filedata'), {
type: 'application/pdf'
});
var objectURL = URL.createObjectURL(blob);
// Create an iframe to demonstrate it:
var iframe = document.createElement('iframe');
iframe.className = 'sample-iframe';
iframe.src = objectURL;
document.body.appendChild(iframe);
above code i am using to display pdf from byte array
This works for me on Chrome, but not on IE:
// base64DataFromWebAPI comes from a Web API, in the form of base 64 string
var pdfData = base64DataFromWebAPI;
var x = window.open();
var iframe = x.document.createElement('iframe')
iframe.width = '100%'
iframe.height = '100%'
iframe.frameBorder = 0
iframe.style = "border: 0"
iframe.src = "data:application/pdf;base64, " + pdfData
x.document.body.appendChild(iframe);
I got it from the following Stack Oveflow question: JsPDF - Not allowed to navigate top frame to data URL
Using Chrome*, you can also simply paste the following code in the address bar:
data:application/pdf;base64, YOUR_PDF_DATA_HERE
It will open it in the included PDF viewer of the browser.
*didn't tested other browsers

Categories