11

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

ashvin
  • 2,020
  • 1
  • 16
  • 33
Vishal
  • 7,113
  • 6
  • 31
  • 61

3 Answers3

37

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 :)

Vishal
  • 7,113
  • 6
  • 31
  • 61
  • Thank you very much for this – catu Oct 24 '17 at 08:36
  • 2
    It is important to note, this doesn't work on Microsoft browsers (IE and Edge). [Here](https://stackoverflow.com/questions/50685552/print-pdf-report-in-ie-11) is a question on how to solve that issue. If you simply want to open on save the blob you can reference [this](https://stackoverflow.com/questions/24007073/open-links-made-by-createobjecturl-in-ie11) – rmlarsen Jul 18 '18 at 15:08
  • Thanks, Is it any solution to print without print dialog box? – Sam khan Feb 26 '19 at 15:24
  • 1
    I think this will not work with firefox. See more: https://stackoverflow.com/questions/33254679/print-pdf-in-firefox – Shmarkus Jul 24 '19 at 07:35
  • how can I print multiple files in one click – Sunil Garg Jul 31 '20 at 06:50
3

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

-3

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

simple and nice implementation.

Harish
  • 25
  • 6