Print PDF directly from JavaScript

JavascriptPdf

Javascript Problem Overview


I am building a list of PDFs in HTML. In the list I'd like to include a download link and a print button/link. Is there some way to directly open the Print dialog for the PDF without the user seeing the PDF or opening a PDF viewer?

Some variation of downloading the PDF into a hidden iframe and triggering it to print with JavaScript?

Javascript Solutions


Solution 1 - Javascript

Based on comments below, it no longer works in modern browsers
This question demonstrates an approach that might be helpful to you: https://stackoverflow.com/questions/975652/silent-print-a-embedded-pdf

It uses the <embed> tag to embed the PDF in the document:

<embed
    type="application/pdf"
    src="path_to_pdf_document.pdf"
    id="pdfDocument"
    width="100%"
    height="100%" />

Then you call the .print() method on the element in Javascript when the PDF is loaded:

function printDocument(documentId) {
    var doc = document.getElementById(documentId);

    //Wait until PDF is ready to print    
    if (typeof doc.print === 'undefined') {    
        setTimeout(function(){printDocument(documentId);}, 1000);
    } else {
        doc.print();
    }
}

You could place the embed in a hidden iframe and print it from there, giving you a seamless experience.

Solution 2 - Javascript

Here is a function to print a PDF from an iframe.

You just need to pass the URL of the PDF to the function. It will create an iframe and trigger print once the PDF is load.

Note that the function doesn't destroy the iframe. Instead, it reuses it each time the function is call. It's hard to destroy the iframe because it is needed until the printing is done, and the print method doesn't has callback support (as far as I know).

printPdf = function (url) {
  var iframe = this._printIframe;
  if (!this._printIframe) {
    iframe = this._printIframe = document.createElement('iframe');
    document.body.appendChild(iframe);

    iframe.style.display = 'none';
    iframe.onload = function() {
      setTimeout(function() {
        iframe.focus();
        iframe.contentWindow.print();
      }, 1);
    };
  }
  
  iframe.src = url;
}

Solution 3 - Javascript

You can use Print.js (npm install print-js). It's 128kB unpacked and you can find the docs at http://printjs.crabbly.com/.

It doesn't print on IE though, in those cases you'll have to download the PDF instead.

$http({
    url: "",
    method: "GET",
    headers: {
        "Content-type": "application/pdf"
    },
    responseType: "arraybuffer"
}).success(function (data, status, headers, config) {
    var pdfFile = new Blob([data], {
        type: "application/pdf"
    });
    var pdfUrl = URL.createObjectURL(pdfFile);
    //window.open(pdfUrl);
    printJS(pdfUrl);
    //var printwWindow = $window.open(pdfUrl);
    //printwWindow.print();
}).error(function (data, status, headers, config) {
    alert("Sorry, something went wrong")
});

Solution 4 - Javascript

https://github.com/mozilla/pdf.js/

for a live demo http://mozilla.github.io/pdf.js/

it's probably what you want, but I can't see the point of this since modern browsers include such functionality, also it will run terribly slow on low-powered devices like mobile devices that, by the way, have their own optimized plugins and apps.

Solution 5 - Javascript

Cross browser solution for printing pdf from base64 string:

  • Chrome: print window is opened
  • FF: new tab with pdf is opened
  • IE11: open/save prompt is opened

.

const blobPdfFromBase64String = base64String => {
   const byteArray = Uint8Array.from(
     atob(base64String)
       .split('')
       .map(char => char.charCodeAt(0))
   );
  return new Blob([byteArray], { type: 'application/pdf' });
};

const isIE11 = !!(window.navigator && window.navigator.msSaveOrOpenBlob); // or however you want to check it

const printPDF = blob => {
   try {
     isIE11
       ? window.navigator.msSaveOrOpenBlob(blob, 'documents.pdf')
       : printJS(URL.createObjectURL(blob)); // http://printjs.crabbly.com/
   } catch (e) {
     throw PDFError;
   }
};

printPDF(blobPdfFromBase64String(base64String))

BONUS - Opening blob file in new tab for IE11

If you're able to do some preprocessing of the base64 string on the server you could expose it under some url and use the link in printJS :)

Solution 6 - Javascript

I used this function to download pdf stream from server.

function printPdf(url) {
        var iframe = document.createElement('iframe');
        // iframe.id = 'pdfIframe'
        iframe.className='pdfIframe'
        document.body.appendChild(iframe);
        iframe.style.display = 'none';
        iframe.onload = function () {
            setTimeout(function () {
                iframe.focus();
                iframe.contentWindow.print();
                URL.revokeObjectURL(url)
                // document.body.removeChild(iframe)
            }, 1);
        };
        iframe.src = url;
        // URL.revokeObjectURL(url)
    }

Solution 7 - Javascript

You can download the pdf file using fetch, and print it with Print.js

fetch("url").then(function (response) {
    response.blob().then(function (blob) {
        var reader = new FileReader();
        reader.onload = function () {

            //Remove the data:application/pdf;base64,
            printJS({
                printable: reader.result.substring(28),
                type: 'pdf',
                base64: true
            });
        };
        reader.readAsDataURL(blob);
    })
});

Solution 8 - Javascript

Simplification of @Nicolas BADIA's answer:

function printPDF (url)
{
    let pdfFrame = document.body.appendChild(document.createElement('iframe'));
    pdfFrame.style.display = 'none';
    pdfFrame.onload = () => (void pdfFrame.contentWindow.print());
    pdfFrame.src = url;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCraig CelesteView Question on Stackoverflow
Solution 1 - JavascriptnullabilityView Answer on Stackoverflow
Solution 2 - JavascriptNicolas BADIAView Answer on Stackoverflow
Solution 3 - Javascriptuser1892203View Answer on Stackoverflow
Solution 4 - Javascriptuser2311177View Answer on Stackoverflow
Solution 5 - JavascriptPapiView Answer on Stackoverflow
Solution 6 - JavascriptAdnanView Answer on Stackoverflow
Solution 7 - JavascriptDiegoView Answer on Stackoverflow
Solution 8 - Javascripttrinalbadger587View Answer on Stackoverflow