调用浏览器的打印预览

时间:2023-01-09 17:11:47

最近改一个页面,想要做一个打印功能,而且需要打印预览,我还没处理过这种需求,特此记录一下。

要打印是比较简单的,js中使用window.print()函数就可以打印,内容为body的内容,兼容IE10以下的浏览时可以引入WebBrowser对象,然后调用WebBrowser.ExecWB(7,1)进行打印预览,调用WebBrowser.ExecWB(6,1)进行打印。

主要的问题是何时调用,因为是局部打印,所以如果在原页打印的话,有两种方法:隐藏不需要打印的内容或者提取出想打印的内容替换进body中,两种方法都涉及比较多的DOM操作,而且原有的样式会对打印造成影响。所以我打算新开页面,把需要的内容填进去,另外创建一个打印专用的css文件引入,再调用打印,得到了比较好的展示效果。

有个注意的点是,注入css文件之后,页面需要一点时间进行渲染,下面这个情况会在未渲染完成的时候进行打印:

var newWin=window.open('');//新开页面
var print=document.getElementById("print");//提取要打印的内容
newWin.document.write(print.outerHTML);//输入要打印的内容
var link=newWin.document.createElement("link");//插入新样式文件
link.href="style/print.css";
link.type="text/css";
link.rel="stylesheet";
newWin.document.head.appendChild(link);
newWin.print();

如何解决呢?办法是使用setTimenOut()函数,把延迟时间设定为0,再在里面调用print()就能实现一个延迟的效果,让页面先渲染再打印出正确的样式。这里涉及到浏览器解释js的原理,在浏览器有一个Task Queue,执行setTimenOut(fun,0)的时候会把fun推到Task Queue中去,等待浏览器的执行栈空了之后(代入上面的例子就是样式载入之后),Task Queue中的内容才会被推入执行栈中执行,从而达到一种延时效果。

另外,需要打印的页面往往会有比较多的表格和表单,需要针对性地改写样式,例如清除表单组件的默认样式。textarea会随着内容的增加而产生滚动条,在打印之前需要先把textarea改为p标签(或者别的),这也是不选择在原页上面调用print()的原因。

(另外吐槽一下CSDN的编辑器,自动换行真是太非人类了)