Express

I have a PDF file and I am trying to print it via Javascript. I have tried this embed trick: Silent print a embedded PDF however, the print function never becomes available, it is always undefined. I have tried the Iframe trick with this code:

(pdfDocument is the ID of the iframe) This does pop up the print dialogue, but printing a blank page. I would love the embed tag way to work. But why is the print function never becoming available? Most of the posts on this subject are quite old. What is the best HTML5/jQuery way to do it? (or just regular JS at this point) EDIT: here is the JS code for the embed tag:

function printPDF() < alert(document.getElementById("pdfDocument").print); //Wait until PDF is ready to print if (typeof document.getElementById("pdfDocument").print == 'undefined') < setTimeout(function(), 1000); > else < var x = document.getElementById("pdfDocument"); x.print(); >> 

I know this is very old, but. did anyone else notice that setInterval(printPDF(), 1000); is setting the interval to the return result of printPDF()? It happens to work since you’ve created a recursive function, but it’s not actually utilizing the interval.

4 Answers 4

I put a bounty on this questions a week or so ago and it’s expired. I’m going to post what I learned here after a lot of research for anyone in the future who might find this.

PDF’s are displayed differently based on browser, browser version, browser configuration, and Operating System. There are a lot of variables so I’ll talk about the most common situations here.

  • On all browsers I was unable to call any sort of print() method through Javascript, I was only able to use PdfActions. The OPENACTION would call print. I embedded these into the PDF using iText.
  • Chrome uses Adobe’s viewer, which doesn’t give access to any sort of print() method but does execute PdfActions embedded in the PDF. So you can embed an ‘OpenAction’ in a PDF and have the PDF call print whenever it’s opened from any application that looks at those actions.
  • Firefox (above a certain version, all recent versions though) uses the Adobe viewer in Windows, which also recognizes PdfActions. However, in OSX it loses support for the Adobe viewer and switches to the baked in Firefox viewer (pdf.js). Which does not support PdfActions.
  • IE: I didn’t really test much on IE. Mostly because I gave up on printing PDF’s from Javascript after Firefox didn’t work on OSX (a req. for me).

My PDF’s were being generated by a server that I control so I ended up making service changes in my server and adding a get PNG service that generated a PNG based on the same markup that the PDF generation uses. Browsers handle images much better than PDFs, which I knew going in, but hoped that I would just be able to re-use the PDF generation service since it’s used elsewhere in my code.

It doesn’t answer the question, but it’s all the information I have. My suggestion to anyone who might find this in the future: ditch PDF if possible in this case and go simpler. Otherwise, please update this question if you know how to call print() through Javascript in FF preview pdf viewer in OSX.

Читайте также:  Prime code in java

Источник

A tiny javascript library to help printing from the web.

PDF Printing

Print.js was primarily written to help us print PDF files directly within our apps, without leaving the interface, and no use of embeds. For unique situations where there is no need for users to open or download the PDF files, and instead, they just need to print them.

One scenario where this is useful, for example, is when users request to print reports that are generated on the server side. These reports are sent back as PDF files. There is no need to open these files before printing them. Print.js offers a quick way to print these files within our apps.

PDF files must be served from the same domain as your app is hosted under. Print.js uses iframe to load files before printing them, therefore, it is limited by the Same Origin Policy. This helps preventing Cross-site scripting (XSS) attacks.

Example

Add a button to print a PDF file located on your hosting server:

For large files, you can show a message to the user when loading files.

Print Large PDF ( 5mb file ) Print Extra Large PDF ( 16mb file )

The library supports base64 PDF printing:

HTML Printing

Sometimes we just want to print selected parts of a HTML page, and that can be tricky. With Print.js, we can easily pass the id of the element that we want to print. The element can be of any tag, as long it has a unique id. The library will try to print it very close to how it looks on screen, and at the same time, it will create a printer friendly format for it.

Example

Add a print button to a HTML form:

Print.js accepts an object with arguments. Let’s print the form again, but now we will add a header to the page:

Image Printing

Print.js can be used to quickly print any image on your page, by passing the image url. This can be useful when you have multiple images on the screen, using a low resolution version of the images. When users try to print the selected image, you can pass the high resolution url to Print.js.

Example

Load images on your page with just the necessary resolution you need on screen:

In your javascript, pass the highest resolution image url to Print.js for a better print quality:

 printJS('images/print-01-highres.jpg', 'image') 

Источник

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) 
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 = $('', < 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.

Читайте также:  Console log function in javascript

So if I understand correctly you don’t want to show the PDF but still print it . so just download it with other words? Or just do as you normally would and hide that section.

@Jorrex No, open it in a hidden iframe, and open the print dialog in the context of that iframe. The iframe is not a requirement, but it was my first attempt. I’m not sure if there are other ways to do that. In short: when I click the button, the print dialog should open and print that pdf.

3 Answers 3

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

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

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

Tested in Chrome, IE, Firefox.

Pdf.js is definitely a thing. In terms of compatibility it works well on modern browsers. The nasty part is that it has printing bugs (pixelated output, wrong fonts etc). I did try that too.

Читайте также:  Объявление массива массивов javascript

True that. To keep things moving forward i conceded and accommodated the flaws in Pdf.js where possible. One of these years pdf printing will be made easy.

Can you please add in your answer that this solution works? Browsers execute js put there, so by adding window.print() in the pdf solves the issue.

I’ve been looking for a solution to this forever! Thank you! FYI, I had to change your if statement slightly: if (typeof PDFViewerApplication !== ‘undefined’ && PDFViewerApplication.initialized)

A further check to build on @scolja’s, to make it work on Safari too, is to use if (typeof PDFViewerApplication !== ‘undefined’ && PDFViewerApplication.initialized && PDFViewerApplication.pdfViewer.pageViewsReady)

After spending the past couple of hours trying to figure this one out and lots of searching here is what I have determined.

The HTML5 Web API spec for Printing indicates that one of the printing steps must fire beforeprint, a simple event (an event that is non-cancelable), to the window object of the Document being printed (as well as any nested browsing contexts, this relates to iframes) to allow for changes to the Document prior to printing. This step is internal to the browser and not something you’ll be able to adjust. During this process, the browser’s print dialog sometimes shows a preview of the file (Chrome does this). so if your goal is to never display the file to the viewer you might be stuck.

The closest to achieving this I came was by creating an index.html file which has a button containing data-* attributes which provided context. Change the path/filename.ext in the data-print-resource-uri attribute to a local file of your own.

     

Express

Welcome to Express

Then in the print.js file, I tried a few things, but never quite got it working (leaving different things I had played with in the comments).

// Reference vars var printButton = document.getElementById('printFile'); var printFrame = document.getElementById('printf'); // onClick handler printButton.onclick = function(evt) < console.log('evt: ', evt); printBlob('printf', printButton.getAttribute('data-print-resource-uri'), printButton.getAttribute('data-print-resource-type')); >// Fetch the file from the server function getFile( fileUri, fileType, callback ) < var xhr = new XMLHttpRequest(); xhr.open('GET', fileUri); xhr.responseType = 'blob'; xhr.onload = function(e) < // Success if( 200 === this.status ) < // Store as a Blob var blob = new Blob([this.response], ); // Hang a URL to it blob = URL.createObjectURL(blob); callback(blob); > else < console.log('Error Status: ', this.status); >>; xhr.send(); > function printBlob(printFrame, fileUri, fileType) < // Debugging console.log('inside of printBlob'); console.log('file URI: ', fileUri); console.log('file TYPE: ', fileType); // Get the file getFile( fileUri, fileType, function(data) < loadAndPrint(printFrame, data, fileType); >); > function loadAndPrint(printFrame, file, type) < // Debugging console.log('printFrame: ', printFrame); console.log('file: ', file); window.frames[printFrame].src = file; window.frames[printFrame].print(); /* // Setup the print window content var windowContent = ''; windowContent += '' windowContent += ''; windowContent += '' windowContent += ''; windowContent += ''; windowContent += ''; // Setup the print window var printWin = window.open('','','width=340,height=260'); printWin.document.open(); printWin.document.write(windowContent); printWin.document.close(); printWin.focus(); printWin.print(); printWin.close(); */ > 

I think that if you can get it working properly using the Blob might work the best in the cross-browser method you wanted.

I found a few references about this topic which might be helpful:

Источник

Оцените статью