在YUI3下打印Panel内容

最近在用YUI3.5制作一个报表网站,遇到个问题,需要打印报表,但是YUI下我是通过model化panel来显示报表内容的,一打印就把整个网页打出来,结果是背景完全是乱的,样式也不正常

YUI3的panel也是通过div实现的,于是想是否能通过只打印div内容方式实现

在网上搜索了下,打印div本身还是比较容易的,代码是这样的:

<script language="javascript">
function printdiv(printpage)
{
  var headstr = "<html><head><title></title></head><body>";
  var footstr = "</body>";
  var newstr = document.all.item(printpage).innerHTML;
  var oldstr = document.body.innerHTML;
  document.body.innerHTML = headstr+newstr+footstr;
  window.print(); 
  document.body.innerHTML = oldstr;
  return false;
}
</script>

好吧,看起来很简单,其实就是把当前网页的innerHTML设置成div的内容,打印完后再设置回去
试了下,document.all.item有点问题,改成

<script language="javascript">
function printdiv(printpage)
{
  var headstr = "<html><head><title></title></head><body>";
  var footstr = "</body>";
  var newstr = document.getElementById(printpage).innerHTML;
  var oldstr = document.body.innerHTML;
  document.body.innerHTML = headstr+newstr+footstr;
  window.print(); 
  document.body.innerHTML = oldstr;
  return false;
}
</script>

 

打印是成功了,但是YUI3下这个代码是有着严重问题的:

网页所有的YUI代理、事件什么的在页面打印完恢复后全部被破坏了,执行完后,panel的关闭按钮,panel上的按钮什么的所有操作都完蛋了,也就是说,恢复后只剩了个页面的壳了

于是想新的办法处理,就是弹出一个新的窗口,然后把内容设置到新窗口打印完后关闭

代码是这样的

        printdiv: function(e, printpage) {
            var headstr = '<html><head></head><body>';
            var footstr = "</body>";
            var contentstr = document.getElementById(printpage).innerHTML;
var openwindow = window.open('', 'newwindow', 'height=100, width=100, top=0, left=0,toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, status=no') openwindow.document.body.innerHTML = contentstr;
openwindow.print(); openwindow.close(); }

结果是打印出来了,但是打印出来的样式完全不正确

试了几种方法,最后确认以上代码有几点问题:

1、据说最好不要使用document.body.innerHTML,这个东西不是所有浏览器都支持

2、怎么设置innerHTML都不行,无法实现样式,最后是通过document.write方法才能实现

3、head里需要设置和要打印页面一样的css才行

4、document.write后面需要跟document.close来关闭输出流,一开始没写这个,导致页面打印不出来(但是刷新这个新页面,然后就会弹出打印对话框了)

 

最后的代码是这样的:

        printdiv: function(e, printpage) {
            var headstr = '<html><head><title></title><link rel="stylesheet" href="../YUI3/cssreset/cssreset.css" type="text/css" /><link rel="stylesheet" href="../YUI3/cssfonts/cssfonts.css" type="text/css" /><link rel="stylesheet" href="../YUI3/cssgrids/cssgrids.css" type="text/css" /><link rel="stylesheet" href="../config/project.css" type="text/css" /></head><body id="doc" class="yui3-skin-sam">';
            var footstr = "</body></html>";
            var contentstr = document.getElementById(printpage).innerHTML;
            var openwindow = window.open('', 'newwindow', 'height=100, width=100, top=0, left=0,toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, status=no')

            openwindow.document.write(headstr + contentstr + footstr);
            openwindow.document.close();
            openwindow.print();
            openwindow.close();
        }

 

 然后外面调用的方法是:

        Y.one('#v2012-print').on('click', Y.ActionHandler.printdiv, Y.one('#v2012-print'), 'v2012-content');

我这里是把printdiv放到了ActionHandler模块里,传递事件时需要额外的参数,第三个参数是事件对象本身,第四个参数是打印的div名称

 

最后要说的是,这个打印div最后还是有以下两点问题:

1、因为只打印div,当此div有由父级继承或通过对象层次实现的CSS时,此CSS在新窗口是无效的,如果想生效,必须在外层进行CSS包装

2、如果div里有ActiveX控件,ActiveX控件的展现内容是无法保持和原本div里的展现相同的,这个要解决的话必须自行通过ActiveX控件实现数据或图像复制

posted @ 2012-07-31 13:29  Zux  阅读(303)  评论(0编辑  收藏  举报