利用WebBrowser彻底解决Web打印问题(包括后台打印)


Posted in Javascript onJune 22, 2009

抱着“取之于众 服务于众”的思想,我总结了一下,把它拿到网上来与大家分享,希望能帮助遇到类似问题的朋友。
我主要使用了IE内置的WebBrowser控件,无需用户下载和安装。WebBrowser有很多功能,除打印外的其他功能就不再赘述了,你所能用到的打印功能也几乎全部可以靠它完成,下面的问题就是如何使用它了。先说显示后打印,后面说后台打印。
1.首先引入一个WebBrowser在需要打印的页面,可以直接添加:
<object id="WebBrowser" classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height="0" width="0">
</object>
到页面,或者使用JavaScript在需要的时候临时添加也可以:

document.body.insertAdjacentHTML("beforeEnd",
"<object id=\"WebBrowser\" width=0 height=0 \
classid=\"clsid:<st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="8856" unitname="F" w:st="on">8856F</st1:chmetcnv>961<st1:chmetcnv tcsc="0" numbertype="1" negative="True" hasspace="False" sourcevalue="340" unitname="a" w:st="on">-340A</st1:chmetcnv>-11D0-A96B<st1:chmetcnv tcsc="0" numbertype="1" negative="True" hasspace="False" sourcevalue="0" unitname="C" w:st="on">-00C</st1:chmetcnv>04FD<st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="705" unitname="a" w:st="on">705A</st1:chmetcnv>2\">");

2 .页面设置和打印预览
如下所示,直接调用即可

document.all.WebBrowser.ExecWB(6,6) 直接打印
document.all.WebBrowser.ExecWB(8,1) 页面设置
document.all.WebBrowser.ExecWB(7,1) 打印预览
或者:
execScript("document.all.WebBrowser.ExecWB 7, 1","VBScript");

3 隐藏不打印的页面元素和分页
CSS 有个Media 属性,可以分开设置打印和显示的格式。
如 <style media="print" type="text/css"> …</style> 中间的格式将只在打印时起作用,不会影响显示界面。
所以可以设定
<style media="print" type="text/css">
.Noprint{display:none;}
.PageNext{page-break-after: always;}
</style>
然后给不想打印的页面元素添加: class="Noprint" ,那就不会出现在打印和打印预览中了。
想分页的地方添加: <div class="PageNext"></div> 就可以了。

4.打印页面的特定部分
我是通过将需要打印的特定部分另建一个页面,然后装入主页面的一个IFrame中,再调用IFrame的打印方法,只打印IFrame中的内容实现的。
如:
<iframe style="visibility: visible" name="FrameId" width="100%" height="30%" src="NeedPrintedPage.asp"></iframe>
下面的pringFrame js函数将只打印Iframe中的内容,可以直接引用使用,如printFrame(FrameId);

window.print = printFrame;
// main stuff
function printFrame(frame, onfinish) {
if ( !frame ) frame = window;
function execOnFinish() {
switch ( typeof(onfinish) ) {
case "string": execScript(onfinish); break;
case "function": onfinish();
}
if ( focused && !focused.disabled ) focused.focus();
}
if (( frame.document.readyState !== "complete") &&( !frame.document.confirm("The document to print is not downloaded yet! Continue with printing?") ))
{
execOnFinish();
return;
}

var eventScope = printGetEventScope(frame);
var focused = document.activeElement;
window.printHelper = function() {
execScript("on error resume next: printWB.ExecWB 6, 1", "VBScript");
printFireEvent(frame, eventScope, "onafterprint");
printWB.outerHTML = "";
execOnFinish();
window.printHelper = null;
}
document.body.insertAdjacentHTML("beforeEnd",
"<object id=\"printWB\" width=0 height=0 \
classid=\"clsid:8856F961-340A-11D0-A96B-00C04FD705A2\">");
printFireEvent(frame, eventScope, "onbeforeprint");
frame.focus();
window.printHelper = printHelper;
setTimeout("window.printHelper()", 0);
}

// helpers
function printIsNativeSupport() {
var agent = window.navigator.userAgent;
var i = agent.indexOf("MSIE ")+5;
return parseInt(agent.substr(i)) >= 5 && agent.indexOf("5.0b1") < 0;
}
function printFireEvent(frame, obj, name) {
var handler = obj[name];
switch ( typeof(handler) ) {
case "string": frame.execScript(handler); break;
case "function": handler();
}
}
function printGetEventScope(frame) {
var frameset = frame.document.all.tags("FRAMESET");
if ( frameset.length ) return frameset[0];
return frame.document.body;
}
Iframe中所装载页面的打印效果在所装载页面设置就可以了,如分页等。
5.后台打印
我是通过建一个隐藏Iframe实现的,当然仍然会有页面装载的过程。
下面的函数创建Iframe装载页面并打印。如 printHidden(url) //url为页面地址
function printHidden(url) {
document.body.insertAdjacentHTML("beforeEnd",
"<iframe name=printHiddenFrame width=0 height=0></iframe>");
var doc = printHiddenFrame.document;
doc.open();
doc.write("<body onload=\"parent.onprintHiddenFrame()\">");
doc.write("<iframe name=printMe width=0 height=0 src=\"" +
url + "\"></iframe>");
doc.write("</body>");
doc.close();
}
function onprintHiddenFrame() {
function onfinish() {
printHiddenFrame.outerHTML = "";
if ( window.onprintcomplete ) window.onprintcomplete();
}
printFrame(printHiddenFrame.printMe, onfinish);
}
它用到了printFrame,所以别忘了引用前面的函数。

总之,WebBroswer已经为我们提供了解决方案,我们只要结合需求把它应用好就行了

Javascript 相关文章推荐
Javascript 面试题随笔
Mar 31 Javascript
JS高级拖动技术 setCapture,releaseCapture
Jul 31 Javascript
jquery设置元素的readonly和disabled的写法
Sep 22 Javascript
JS跨域问题详解
Nov 25 Javascript
javascript操作数组详解
Dec 17 Javascript
基于PHP和Mysql相结合使用jqGrid读取数据并显示
Dec 02 Javascript
快速解决select2在bootstrap模态框中下拉框隐藏的问题
Aug 10 Javascript
微信二次分享报错invalid signature问题及解决方法
Apr 01 Javascript
小程序中设置缓存过期的实现方法
Jan 14 Javascript
js实现鼠标拖拽div左右滑动
Jan 15 Javascript
微信小程序8种数据通信的方式小结
Feb 03 Javascript
简单了解前端渐进式框架VUE
Jul 20 Javascript
实现超用户体验 table排序javascript实现代码
Jun 22 #Javascript
js 单引号 传递方法
Jun 22 #Javascript
使弱类型的语言JavaScript变强势
Jun 22 #Javascript
Javascript 代码也可以变得优美的实现方法
Jun 22 #Javascript
PNG背景在不同浏览器下的应用
Jun 22 #Javascript
JavaScript 新手24条实用建议[TUTS+]
Jun 21 #Javascript
ExtJS扩展 垂直tabLayout实现代码
Jun 21 #Javascript
You might like
配置PHP使之能同时支持GIF和JPEG
2006/10/09 PHP
隐性调用php程序的方法
2009/03/09 PHP
PHP批量删除、清除UTF-8文件BOM头的代码实例
2014/04/14 PHP
PDO预处理语句PDOStatement对象使用总结
2014/11/20 PHP
PHP两种快速排序算法实例
2015/02/15 PHP
PHP实现的微信公众号扫码模拟登录功能示例
2019/05/30 PHP
写自已的js类库需要的核心代码
2012/07/16 Javascript
转义字符(\)对JavaScript中JSON.parse的影响概述
2013/07/17 Javascript
禁用Tab键JS代码兼容Firefox和IE
2014/04/18 Javascript
javascript实现动态改变层大小的方法
2015/05/14 Javascript
js实现适配不同的屏幕大小
2017/04/10 Javascript
vue修改vue项目运行端口号的方法
2017/08/04 Javascript
Angular2整合其他插件的方法
2018/01/20 Javascript
vue写一个组件
2018/04/09 Javascript
JS文件中加载jquery.js的实例代码
2018/05/05 jQuery
解决vue数组中对象属性变化页面不渲染问题
2018/08/09 Javascript
vue实现路由懒加载及组件懒加载的方式
2019/06/11 Javascript
vue遍历生成的输入框 绑定及修改值示例
2019/10/30 Javascript
[42:27]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#2Fnatic VS OG第三局
2016/03/05 DOTA
[48:31]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第一场 2月2日
2021/03/11 DOTA
Python实现多进程共享数据的方法分析
2017/12/04 Python
Python爬虫天气预报实例详解(小白入门)
2018/01/24 Python
Python 实现在文件中的每一行添加一个逗号
2018/04/29 Python
python3.6生成器yield用法实例分析
2019/08/23 Python
如何使用Python破解ZIP或RAR压缩文件密码
2020/01/09 Python
Python 实现递归法解决迷宫问题的示例代码
2020/01/12 Python
西班牙太阳镜品牌:Hawkers
2018/03/11 全球购物
经贸日语毕业生自荐信
2013/11/03 职场文书
鸿星尔克广告词
2014/03/21 职场文书
四风剖析查摆对照检查材料思想汇报
2014/09/24 职场文书
小学班主任自我评价
2015/03/11 职场文书
拾金不昧通报表扬范文
2015/05/05 职场文书
2015年度内部审计工作总结
2015/05/20 职场文书
导盲犬小Q观后感
2015/06/11 职场文书
高中信息技术教学反思
2016/02/16 职场文书
openstack中的rpc远程调用的方法
2021/07/09 Python