I had issues with all of the above solutions in IE8, have found a decent workaround that is tested in IE 8+9, Chrome, Safari and Firefox. For my situation i needed to print a report that was generated dynamically:
// create content of iframe
var content = '<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">'+
'<head><link href="/css/print.css" media="all" rel="stylesheet" type="text/css"></head>'+
'<body>(rest of body content)'+
'<script type="text/javascript">function printPage() { window.focus(); window.print();return; }</script>'+
'</body></html>';
Note the printPage() javascript method before the body close tag.
Next create the iframe and append it to the parent body so its contentWindow is available:
var newIframe = document.createElement('iframe');
newIframe.width = '0';
newIframe.height = '0';
newIframe.src = 'about:blank';
document.body.appendChild(newIframe);
Next set the content:
newIframe.contentWindow.contents = content;
newIframe.src = 'javascript:window["contents"]';
Here we are setting the dynamic content variable to the iframe's window object then invoking it via the javascript: scheme.
Finally to print; focus the iframe and call the javascript printPage() function within the iframe content:
newIframe.focus();
setTimeout(function() {
newIframe.contentWindow.printPage();
}, 200);
return;
The setTimeout is not necessarily needed, however if you're loading large amounts of content i found Chrome occasionally failed to print without it so this step is recommended. The alternative is to wrap 'newIframe.contentWindow.printPage();' in a try catch and place the setTimeout wrapped version in the catch block.
Hope this helps someone as i spent a lot of time finding a solution that worked well across multiple browsers. Thanks to SpareCycles.
EDIT:
Instead of using setTimeout to call the printPage function use the following:
newIframe.onload = function() {
newIframe.contentWindow.printPage();
}