主页:http://www.maxss.net邮件:maxchou@163.com
自从Microsoft公司在2001推出.NET平台后,在网络时代中基于BS结构的应用开发已经达到了新的高潮。而.NET这种以事件驱动来进行Web开发的模式更把原始的BS开发模式带到一个全新的领域中,让程序员和开发商更有效和快速的开发和部署更安全的企业应用。虽然.NET这个新一代的开发平台具有各样的优势,但仍然存在一些还不够完善和不尽人意的地方。但一点肯定的是Microsoft一定会继续不断地为其注入源源的新动力。
现回到本篇文章的正题,目前在Web环境下的打印对于MIS系统来说是必要的一项功能,一般情况下是通过IE的直接打印或导出成其它格式(如Word格式)再进行打印。但客户的需求总是千变万化,前段时间里在我在一家从事基于.NET平台开发OA产品的公司要在其产品中增加新的打印功能。需求当然是来自客户了,客户的核心的要求是打印DataGrid显示的数据(当然不是就这么简单了,接着看吧)。要求一:对于指定要打印的DataGrid中可以控制每页打印特定条数的记录;要求二:如果记录数根据前面的条件超出一页的话,要实现逐页自动打印,不需要人工干预;要求三:可以自定义报表头信息(打印日期、标题等)并进行格式控制(字体大小、对齐方式、表格的显示样式等)。
当我接到该需求时就开始琢磨,在应用程序中实现这些功能确实问题不是很难,但在Web环境中可以就不是一件那么轻松的事了,更何况客户的要求是这么的苛刻。最关键的问题是要解决要求一和要求二,其实它们可以综合成文章标题所提的问题,就是如何实现自定义及自动逐页打印DataGrid显示的内容。
开始我是希望可以通过利用新的.NET的技术来寻求解决方法,在探讨过Cystal Reports(水晶报表)、PrinterController及PrintDocument等技术后发现这些技术目前对客户的需求好像都还不太成熟和合适。对水晶报表它可以生成报表后在客户端导出成其它格式的文档(如doc,pdf)后再进行打印;而对于PrinterController和PrintDocument则只能应用于服务器端,这好像就更难于实现了。
经过几天努力后发现好像只剩下一种方案可以一试,那就是利用JavaScript + WebBrowser控件在客户端实现打印。但问题马上就出来了,该如何通过JavaScript来操作DataGrid所绑定的数据呢?如果要用户一页一页的翻页再进行打印的话就没有必要专门来开发这个功能了,通过IE的打印菜单就可以轻松完成。现在.NET中DataGrid可以轻松实现分页显示,我们可以直接利用这个现成的功能来展开思考,这样剩下的关键问题就是如何让DataGrid自动转入第二页及其它页了。首先当然就是分析DataGrid在客户端生成的HTML代码了,后来在一堆密密麻麻的代码中找到了一个重要的突破口——我自己的理解就是所谓服务器端事件的触发其实基本上都是通过在客户端页面中生成特定的JavaScript函数并通过与用户的交互来实现的。这些函数都是以javascript:__doPostBack('一级控件名:_二级控件名:_三级控件名...', '')等的格式出现,当然包括显示在DataGrid下面分页显示时的页码链接了,在.NET中每个页码链接都作为一个三级控件来对待,这些控件的名称都是由系统自动生成的,命名格式形如“_ctl0, _ctl1, _ctl3...”。
现假设与DataGrid绑定的数据被分成三页显示,它相应在客户端生成的JS脚本基本形状如下:
第一页:javascript:__doPostBack('DataGrid1:_ctl11:_ctl_2:_ctl0', '')
第二页:javascript:__doPostBack('DataGrid1:_ctl11:_ctl_2:_ctl1', '')
第三页:javascript:__doPostBack('DataGrid1:_ctl11:_ctl_2:_ctl2', '')
这样我们的问题就清晰了,只要找到一个页码所对应的脚本就可以动态地生成其它后续的脚本并执行之,这样我们就可以自由灵活地控制DataGrid在各分页中的切换了。
接下来就要解决第二个问题了,该如何对打印当前在DataGrid中显示信息呢?以前我看过一些别的系统的做法就是重新打开一个新的页面,再执行一次数据库的读取操作来生成要打印的内容。这样效率是可想而知的,更何况在.NETk中DataGrid所显示的数据是通过绑定来得到的,而且在很多情况下用户会对某些字段进行筛选显示,如果按照旧有的做法明显是不现实的和难以实现的。既然要打印的数据就是在DataGrid中显示的数据,我们为什么不直接利用它们呢?同样的处理手法法,DataGrid在客户端是生成<tabel>来显示数据的,它们的id属性就是在设计阶段DataGrid的Name属性。这样我们就可以通过JavaScrip把这个表格的outerHTML值取出就是它当前要显示的内容了。当取出这些内容后再写入一个width和height都为0的<iframe>+<frame>的document对象中就可以实现隐藏打印了。而且还可以利用JavaScript来对DOM(文档对象模型)进行其它所需的操作,实现对自定义字体大小、表格样式等。
对以上设计思路的扩充还可以为做出更强大的功能。这些多细节的问题是需要注意和解决的。目前我已经实现只是我对大概的设计思路及开发的小结,真正编码实现过程中还要有很了客户提出的需求,并且还增加对打印范围和打印超时检测与恢复等的增强功能,现在的版本运行得很稳定。如果你有更好的想法可以与我交流,如想获得有关的源码请直接与我联系。
支持的功能特性:
自定义报表头信息及格式
自定义报表样式
自动分页打印
自定义打印范围
打印预览
页面设置
打印超时检测与恢复
自动逐页打印支持的检测
模块化
以下列出在程序中用到的关键技术及函数以供参考:
JavaScript/JScript
DOM
CSS
WebBrowser
setTimeout()
正则表达式
csdn上的有关贴子:
http://expert.csdn.net/Expert/topic/1972/1972703.xml?temp=.7686121
了解更多有关Maxspace Studio,请访问 www.maxss.net