Print PDF in Firefox
Solution 1
Firefox: Permission denied to access property "print"
This is a bug in firefox. Locally it can be disabled by going to about:config
and set the property of pdfjs.disabled
to true. Only possible workaround is to use a server-side script and modify the pdf. Using php you could use fpdf and embed extensions to implement js (inclunding the print()
function) or simply convert the pdf to an image, return the url and print it. You could use FPDI to modify the existing pdf. I will give you an example on how I got it to work with PHP.
Generating a PDF file with inline javascript (autoprint) using FPDI and PDF_JS
require_once('fpdf.php');
require_once('fpdi.php');
class PDF_JavaScript extends FPDI {
var $javascript;
var $n_js;
function IncludeJS($script) {
$this->javascript=$script;
}
function _putjavascript() {
$this->_newobj();
$this->n_js=$this->n;
$this->_out('<<');
$this->_out('/Names [(EmbeddedJS) '.($this->n+1).' 0 R]');
$this->_out('>>');
$this->_out('endobj');
$this->_newobj();
$this->_out('<<');
$this->_out('/S /JavaScript');
$this->_out('/JS '.$this->_textstring($this->javascript));
$this->_out('>>');
$this->_out('endobj');
}
function _putresources() {
parent::_putresources();
if (!empty($this->javascript)) {
$this->_putjavascript();
}
}
function _putcatalog() {
parent::_putcatalog();
if (!empty($this->javascript)) {
$this->_out('/Names <</JavaScript '.($this->n_js).' 0 R>>');
}
}
}
class PDF_AutoPrint extends PDF_JavaScript
{
function AutoPrint($dialog=false)
{
//Open the print dialog or start printing immediately on the standard printer
$param=($dialog ? 'true' : 'false');
$script="print($param);";
$this->IncludeJS($script);
}
function AutoPrintToPrinter($server, $printer, $dialog=false)
{
$script = "document.contentWindow.print();";
$this->IncludeJS($script);
}
}
$pdf=new PDF_AutoPrint();
$pdf->setSourceFile("mozilla.pdf");
//Open the print dialog
$tplIdx = $pdf->importPage(1, '/MediaBox');
$pdf->addPage();
$pdf->useTemplate($tplIdx, 10, 10, 90);
$pdf->AutoPrint(true);
$pdf->Output('generated.pdf', 'F');
Now you can simply append the generated pdf to your page and the included javascript will call the print()
function. You do not even have to call it manually anymore. However, in firefox this will only work with visibility: hidden
and not with display: none
.
function print_pdf(url){
var iFrameJQueryObject = $('<iframe id="iframe" src="'+url+'" style="visibility: hidden"></iframe>');
$('#foo').append(iFrameJQueryObject);
}
print_pdf('mozilla_generated.pdf');
Chrome: Security Error (cross-origin)
The pdf should be located at the same host. Firefox was okay with other domains in my tests, but chrome gave me cross-origin errors.
Firefox: Printed page includes about:blank
only
You will get an empty page in firefox (jsfiddle), because it will print the iframe before it has loaded any content. Mentioned methods like $(document).onload()
won't help, since they only wait for the DOM to load and setTimeout()
can still result in errors, since you do not know how long it takes the iFrame to load.
You can simply resolve this issue by using jQuery's load()
. (doc) This will give you the possibility to use a callback function as parameter.
if a "complete" callback is provided, it is executed after post-processing and HTML insertion has been performed. The callback is fired once for each element in the jQuery collection, and
this
is set to each DOM element in turn.
Code Example 1
function print_pdf(url){
var id = 'iframe', html = '<iframe id="'+id+'" src="'+url+'" style="display:none"></iframe>';
$('body').append(html);
// wait for the iFrame to fully load and call the print() function afterwards
$('#' + id).load(function () {
document.getElementById(id).contentWindow.print();
});
}
Alternatively you could directly create an jQuery object and use jQuery's on()
(doc) to attach any event handler.
Code Example 2 (jsfiddle)
function print_pdf(url){
var iFrameJQueryObject = $('<iframe id="iframe" src="'+url+'" style="display:none"></iframe>');
$('body').append(iFrameJQueryObject);
iFrameJQueryObject.on('load', function(){
$(this).get(0).contentWindow.print();
});
}
Solution 2
Edit, Updated
Try using window.onload
event , document.createElement()
, onload
event , setTimeout()
with duration
set to 2000
, setting src
of iframe
after appending element to document
window.onload = function() {
function print_pdf(url){
var id = "iframe", frame = document.createElement("iframe");
frame.setAttribute("id", id);
frame.setAttribute("width", "800px");
frame.setAttribute("height", "600px");
frame.setAttribute("allowfullscreen", "true");
frame.setAttribute("name", "printframe");
document.body.appendChild(frame);
frame.onload = function() {
this.requestFullScreen = this.mozRequestFullScreen
|| this.webkitRequestFullScreen;
this.requestFullScreen();
setTimeout(function() {
print()
},2000)
}
frame.setAttribute("src", url);
}
print_pdf("http://zeitreisen.zeit.de/wp-content/uploads/2014/09/pdftest2.pdf");
}
plnkr http://plnkr.co/edit/mHBNmc5mdM0YJRwRbYif?p=preview
Solution 3
PDFs have Javascript support. I needed to have auto print capabilities when a PHP-generated PDF was created and I was able to use FPDF to get it to work:
http://www.fpdf.org/en/script/script36.php
Related videos on Youtube
clarkk
https://dynaccount.dk https://dynaccount.dk/bogfoeringsprogram/ https://dynaccount.dk/regnskabsprogram/
Updated on July 09, 2022Comments
-
clarkk almost 2 years
How to print a PDF in Firefox?
This function works in Chrome but not in Firefox
function print_pdf(url){ var id = 'iframe', html = '<iframe id="'+id+'" src="'+url+'" style="display:none"></iframe>'; $('#main').append(html); $('#'+id).load(function(){ document.getElementById(id).contentWindow.print(); } }
error
Error: Permission denied to access property "print"
-
sailens over 8 yearsIt doesn't just work or it shows some error? Can you provide a jsfiddle for us to take a look?
-
clarkk over 8 yearsThe printed page is empty.. Like an empty webpage with URL in the header and date in the footer
-
clarkk over 8 yearsTypeError: document.frames is undefined
-
sailens over 8 yearsI just noticed, you have
style="display:none"
. If the item is not showing, it won't get printed. Think as if the printed page is a screen. If there is no item showing, it won't get printed. -
Aidas Bendoraitis over 8 yearsthe DOM variable/object is undefined.
-
james emanon over 8 yearsI'd try wrapping a setTimeout around the "print()".. ala.. setTimeout(function() {document.getElementById(id).contentWindow.print();}, 2000);
-
Jacobi over 8 yearsHi @clarkk, you wan't to open the page preview or just send to the printer?
-
clarkk over 8 yearsI just want to send to the printer..
-
Ultimater over 8 yearsWhy can't you use display:block and just position the iframe absolutely in some negative coordinates?
-
Jay over 8 years@clarkk check this out, it may help : developer.mozilla.org/en-US/docs/Printing
-
-
clarkk over 8 yearsThe code triggers an
alert
before the print dialog comes up saying: pdf.js is not fully loaded -
guest271314 over 8 years@clarkk "The code triggers an alert before the print dialog comes" Adjust individual firefox browser print preferences for default action at print ? "and the PDF has to be hidden " Not certain interpret "PDF has to be hidden" ? Load iframe with
display:none
adjustiframe
todisplay:block
before calling.print()
? Ififrame
is loaded and.print()
called immediately print window should displayiframe
contents and have immediate focus before parentwindow
regains focus when print dialog canceled or documented printed to filesystem. -
Paul Allsopp over 8 yearsYou would be better off creating the iframe as a JS object instead of as a string. That way you can add event handlers, such as onload, to it before you add it to the page.
-
guest271314 over 8 years@HoschNok Can create stacksnippets , jsfiddle jsfiddle.net to demonstrate approach at solution ?
-
oshell over 8 yearsjsfiddle will have x-origin problems when using iframes, so this is inconvenient. I still got it to work, by using just the same url as url.
-
clarkk over 8 yearsI get this error in Firefox:
Error: Permission denied to access property "print"
-
oshell over 8 yearsIn the jsfiddle too? only on localhost? make sure you use same protocol like http:// and not file://
-
clarkk over 8 yearsIf you put an actual PDF file into the function it does not work jsfiddle.net/zrp6sd6h/4
Error: Permission denied to access property "print"
-
clarkk over 8 years- and i think it has something to do with Firefox uses its own javascript PDF viewer
pdf.js
-
guest271314 over 8 years@clarkk Can a server side solution be used to meet requirement ?
-
clarkk over 8 yearsI would prefer a javascript solution.. But show me what you had in mind
-
guest271314 over 8 years@clarkk See updated post , added
window.onload
event , addedduration
of2000
tosetTimeout
. Tried at nightly, chromium ; appear to return same results at each. -
oshell over 8 yearswhich os/browser version are you using? I am currently using Ubuntu.
-
oshell over 8 yearsI have posted a working workaround in PHP. Seems pretty much overkill, you might consider using another approach such as simply downloading/open the PDF and let the user print it manually.
-
clarkk over 8 yearsCreating the PDF on client side is not an option.. Then you have to maintain both the serverside PDF genereator and the client side PDF generator.. The client side PDF generator is the primary
-
George Plamenov Georgiev over 8 yearsYes you are right but in little information i can tell you that it is super fast. Also it relay on html5 and when you want a cross browser compatibility is great, Also it is a free library and you do not support anything everything is done by the guys you need only to replace the library so it is not a big deal of support.
-
oshell over 8 yearsI tried this and it returns an empty page in chrome on my machine.
-
guest271314 over 8 years@HorstJahns " tried this and it returns an empty page in chrome on my machine." Were plugins allowed for page ?
-
DoctorDestructo over 8 yearsThis appears to be printing the iframe rather than the pdf. That means the pdf will get cut off if it's larger than the dimensions of the iframe. Also, triggering the print dialog after some arbitrary timeout will be very unreliable since the pdf's load time could vary greatly depending on its size, the user's connection speed, system resources, etc.
-
guest271314 over 8 years@DoctorDestructo There is not actually a
.pdf
file displayed , but a rendering of.pdf
file ashtml
by either firefox or chromejs
plugin. Yes,setTimeout
is not optimal solution , without adjustingjs
that renders.pdf
ashtml
; which appears slightly different for each browser -
DoctorDestructo over 8 years@guest271314 My point was that you're printing the iframe (or rather, its parent window) instead of the iframe's content. Doesn't matter if the content is html or pdf; if it's larger than the iframe, it will get cut off. That's the consequence of using
print()
instead offrame.documentWindow.print()
. -
guest271314 over 8 years@DoctorDestructo "My point was that you're printing the iframe (or rather, its parent window) instead of the iframe's content." , "That's the consequence of using print() instead of frame.documentWindow.print()" Good points. Approach is to avoid
Uncaught SecurityError: Blocked a frame with origin "http://run.plnkr.co" from accessing a frame with origin "http://zeitreisen.zeit.de". Protocols, domains, and ports must match.
Can dynamically adjustwidth
,height
ofiframe
, orparent
to address possible clipping of print job. -
DoctorDestructo over 8 years@guest271314 I don't think Firefox allows JavaScript to access most of the properties and methods of the iframe's contentWindow or any of its descendants, so you probably couldn't use JS to determine the pdf's size. If you could measure it server-side somehow, then you'd be in business.
-
guest271314 over 8 years@DoctorDestructo Since no
.pdf
is actually displayed atdocument
,html
rendering of.pdf
could be adjusted, or "resized" based on screen. Used arbitrarywidth
,height
athtml
at post , and attempted to incorporaterequestFullScreen
to cover viewport of user. Could determine user screen size before creating or settingiframe
src
, then renderiframe
to fillviewport
without clipping document. This is , perhaps, fine-tuning portion ; beyond scope of Question. Solution at post printedwindow
at chrome / chromium , firefox ; have not yet tried at mac or opera -
DoctorDestructo over 8 years@guest271314 Were you actually able to reference and manipulate elements of the converted pdf via JavaScript? If you can do that, then you might as well just do a simulated
click()
on the pdf viewer's built-in print button, or just run itsonclick
function directly. In my testing, though, Firefox denied access to everything within the iframe once the pdf was loaded. If you have a workaround, you should incorporate it into your post. Your current solution prints the iframe's parent window, which isn't the same thing as printing its content document. -
guest271314 over 8 years@DoctorDestructo "Were you actually able to reference and manipulate elements of the converted pdf via JavaScript?" This is more involved. If open plnkr at firefox, open
console
and navigate toScript
tab, should observe thatpdf.js
is loaded. This can also be viewed atcss
tab as well, whereviewer.css
is listed as<System>
. This presents at least two challenges; 1) accessing cross-domainiframe
, 2) accessing<System>
resources. Source of bothviewer.css
andpdf.js
can be viewed at GitHub. Firefox and chrome appear to implement rendering.pdf
documents differently. -
guest271314 over 8 years@DoctorDestructo Stopped short of modifying
pdf.js
for this specific Question, as users at large browsers' would not have same resources available natively. Simplest approach would be to usepdftohtml
or similar library to render.pdf
ashtml
, adjuststyle
as necessary - without browser attempting to render.pdf
. That is, save.pdf
locally, render tohtml
, adjust styles , when user visits page display.pdf
ashtml
without browser plugins automatically trying to load plugin and render.pdf
ashtml
-
Hengjie over 7 years
contentWindow.print()
does not work in Firefox because it returnsError: Permission denied to access property "print"
-
Gary over 7 yearsIt is because of your firefox default pdfjs config. It is a known issue. bugzilla.mozilla.org/show_bug.cgi?id=911444 Please try this. stackoverflow.com/questions/15011799/… or this stackoverflow.com/questions/15011799/…