Printing a (part of) webpage with Javascript
Solution 1
I've tested different ways of printing part of webpage across browsers:
Chrome, Firefox, Opera (12 and new), IE11, 10, 9 and 8. I've tried to create new window
, new iframe
, or use existing iframe
on the page. And then tried .print()
and .execCommand('print')
.
Note: Keep in mind that .print() is called on window, and .execCommand() is called on document.
Code used for testing can be found here
Correct me if my testing code is wrong, I just wanted to find the clearest way to do the job. My conclusions:
- Opera 12 can not print part of a webpage (?)
- IEs don't
print()
iframes and windows, except current window. - Calling
print()
ondocuments
inside iframes or created windows in IEs breaks theprint()
on currentdocument
. Be careful! - jQuery plugin printThis uses tricks for IE to do the job, and it just works. The only exception is Opera 12. By the way, this plugin uses
print()
. -
execCommand('print')
works almost everywhere and with any approach (iframes, window). It's not supported by Firefox though. -
execCommand()
returnsfalse
if call was unsuccessful, so if you don't want to use plugins and magic tricks, create window or iframe, callexecCommand('print')
and if it returnsfalse
, callprint()
.
One more thing:
Creating an iframe
is tricky: you can't access its window or document directly (yes, you have ContentDocument property, which behaves differently across browsers). You should name it and then call window.frames[name]
to get window object from that iframe. Do not try to call window.frames(id)
- it will return the iframe.
Solution 2
That last method mentioned in the accepted answer, then, ends up looking like this:
iframe = document.getElementById('iframe-id');
var printed = iframe.contentWindow.document.execCommand('print', false, null);
if (!printed) window.print();
alternative:
try {
iframe = document.getElementById('iframe-id');
iframe.contentWindow.document.execCommand('print', false, null);
}
catch(e) {
window.print();
}
similar method used by printThis
if (document.queryCommandSupported("print")) {
$iframe[0].contentWindow.print();
$iframe[0].contentWindow.document.execCommand("print", false, null);
} else {
$iframe[0].contentWindow.focus();
$iframe[0].contentWindow.print();
}
Rast
Updated on June 14, 2022Comments
-
Rast almost 2 years
I am aware of two ways of calling the "print" dialog of browser (I used the Search, of course):
- document.print()
- document.execCommand('print', false, null)
What is the difference between them? Support across browsers? Papers, docs or standards? Which is more correct thing to use?
Another question: what is the most straight way to print given part of a webpage? I know we can create new window or iframe to call any of two print methods above. Which one has less pitfalls?
-
Admin over 8 yearsOn an Android browser,
window[iframeName].document.execCommand('print')
seems to print the entire page. Have you seen that? -
Admin over 8 yearsNote that according to caniuse.com/#feat=document-execcommand, this is not supported on Android 5-6 (Lollipop-Marshmallow).
-
Rast almost 8 years@torazaburo No, my interest was only of desktop broswers.
-
Rast over 7 yearsthis question is about sending a page to printer, not about saving it as a file
-
Raj almost 7 years@torazaburo I'm getting the same issue. Android chrome prints the entire page and not just the iframe. Did you get any workaround this? Appreciate if anybody can help.
-
Admin almost 7 years@Rajkishore This is a known bug which is still outstanding, unfortunately I'm too lazy to track down the link at the moment.
-
Saif about 4 years+1, this is the most elaborate answer I can find on SO so far. I ended up using execCommand('print') method because I'm trying to print part of an iframe. Also I'm unable to get a hold of window object inside the iframe. I'm not sure about the reason why its not accessible, probably because parent frame uses srcdoc in combination with sandbox to render iframe or may be due to something else. The only thing concerning is I'm supposed to add support for tablet as well, so might have to look into the issue mentioned above by @user663031.