Ionică Bizău Ionică Bizău - 2 months ago 65
jQuery Question

Print a pdf without visually opening it

The thing I want to build is that by clicking a button I want to trigger the print of a PDF file, but without opening it.

+-----------+
| Print PDF |
+-----------+
^ Click *---------> printPdf(pdfUrl)


The way how I first tried it is to use an iframe:

var $iframe = null;

// This is supposed to fix the onload bug on IE, but it's not fired
window.printIframeOnLoad = function() {
if (!$iframe.attr("src")) { return; }
var PDF = $iframe.get(0);
PDF.focus();

try {
// This doesn't work on IE anyways
PDF.contentWindow.print();

// I think on IE we can do something like this:
// PDF.document.execCommand("print", false, null);
} catch (e) {
// If we can't print it, we just open it in the current window
window.location = url;
}
};

function printPdf(url) {

if ($iframe) {
$iframe.remove();
}

$iframe = $('<iframe>', {
class: "hide",
id: "idPdf",
// Supposed to be a fix for IE
onload: "window.printIframeOnLoad()",
src: url
});

$("body").prepend($iframe);
}


This works on Safari (desktop & iOS) and Chrome (can we generalize it maybe to webkit?).

On Firefox,
PDF.contentWindow.print()
ends with a
permission denied
error (even the pdf is loaded from the same domain).

On IE (11), the
onload
handler is just not working.




Now, my question is: is there another better way to print the pdf without visually opening it to the user?

The cross browser thing is critical here. We should support as many browsers as possible.

What's the best way to achieve this? Is my start a good one? How to complete it?

We are now in 2016 and I feel like this is still a pain to implement across the browsers.

Answer

UPDATE: This link details an elegant solution that involves editing the page properties for the first page and adding an action on Page Open. Works across all browsers (as browsers will execute the JavaScript placed in the actions section). Requires Adobe Acrobat Pro.


It seems 2016 brings no new advancements to the printing problem. Had a similar issue and to make the printing cross-browser I solved it using PDF.JS but had to make a one-liner addition to the source (they ask you to build upon it in anyways).

The idea:

  • Download the pre-built stable release from https://mozilla.github.io/pdf.js/getting_started/#download and add the "build" and "web" folders to the project.
  • The viewer.html file is what renders out PDFs with a rich interface and contains print functionality. I added a link in that file to my own JavaScript that simply triggers window.print() after a delay.

The link added to viewer:

    <script src="viewer.js"></script>
    <!-- this autoPrint.js was added below viewer.js -->
    <script src="autoPrint.js"></script>
</head>

The autoPrint.js javascript:

(function () {
    function printWhenReady() {
        if (PDFViewerApplication.initialized) {
            window.print();
        }
        else {
            window.setTimeout(printWhenReady, 3000);
        }
    };

    printWhenReady();
})();
  • I could then put calls to viewer.html?file= in the src of an iframe and hide it. Had to use visibility, not display styles because of Firefox:

    <iframe src="web/viewer.html?file=abcde.pdf" style="visibility: hidden">
    

The result: the print dialog showed after a short delay with the PDF being hidden from the user.

Tested in Chrome, IE, Firefox.

Comments