1 问题描述
在web项目,打印功能一直是一个老大难问题,而想进行套打,则更加上难上加难。而我在最近的项目中就遇到的条形码打印的需求,需要调用客户端的打印机发送指令进行打印。在由于该项目的用户在地域分布上比较广,就要求功能的实现对用户来说要尽可能简单,而目前主流的解决方案主要有以下的几种
-
- 使用浏览器本身的打印功能
这种方案的优势是简单,不需要对浏览器做任何的扩充,但是问题也很多,如
-
-
- 不能精确分页。浏览器一般是根据用户设置的页面大小,web页面的内容多少,来自行决定分页位置,程序员很难控制。会有页脚页眉干扰。
- 不能准确对齐边边距及打印文字。
- 不能解决连续打印。比如,不是仅打印一张票据,而是连续一次打印若干个票据。
- 使用webbrowser控件+ javascript
-
这种方式实际上是使用js来调用浏览器的打印功能,实际上和第一种方式没有太大的区别,只不过是用户不用再去点击浏览器的打印,而是直接在网页中点击一个按钮罢了了,仍然解决不了第一种方式中的问题
-
- 使用print css
这是一种最理想的实现web套打的方法。这种方法通过在html文档中,嵌入打印相关的css样式,来实现对html文档输出打印的控制,比 如设置纸张大小,纸张纵横方向,打印边距,分页等。显而易见,这种方式成本小,不需要下载任何插件,而且跨平台性非常好。print css推出已经有些时日,但遗憾的是,至今没有一个厂商的浏览器很好地实现了这些标准,这使得程序员目前还不能利用print css进行实际的开发。
-
- 使用PDF文件
将待打印的目标在程序中格式化后输出成一个PDF文件,用户需要打印的时候下载这个PDF文件,使用阅读器的打印功能进行打印,这种方式需要下载一个浏览器的插件。
-
- 使用activeX控件方式
这种方案就是下载一个控件,票据的数据不再以html方式呈现,而是呈现在ActiveX中。这种方案的优点是打印的精确度高,分页的可控性 好,但缺点也是很明显的,
-
-
- 嵌入ActiveX控件破坏了web应用的整体html风格,
- ActiveX是微软所开发的,IE之外的浏览器要想使用,都是不支持ActiveX控件的
- 控件一般都比较大,下载会比较耗时
- ActiveX已经过时,微软自己现在也已经不在推广该技术
- 控件的开发成本巨大
- 使用applet方式
-
在java项目中常被采用,采用Applet方式,分页或精确打印,都可以做到完美,但缺点也很明显,表现在:
-
-
- Applet的运行依赖于JRE,所以需要在客户端上安装JRE
- 程序一般较大,下载很耗时
- 技术已经过时,现在主流的浏览器都已经不支持applet
- Applet的开发成本比较大
- 利用第三方的打印服务
-
主要是利用市面上已经的很多付费的,免费的打印控件,同样可以做到精确的分页和文字对齐,同时开发也很方便,但是缺点也存在
-
-
- 需要在所在的客户端安装打印服务
- 需要在代码中控制格式
-
- 案例分析
在拿到需求后,经过对上面多种打印方式的学习,优缺点分析,尝试,项目的实际情况的考虑,最终选择了第七种方式,原因在于
-
- 项目需求是进行条形码打印,在打印的时候需要将生成的条码传输到条码打印机,而条码打印机的标签是有大小限制的,这就类似于套打
- 项目属于公益性项目,如果购买第三方付费的打印插件,成本较高(一般按ip或者是客户端数据购买licence)
- 自己开发打印插件在时间上不允许
- 条码打印机不同于普通打印机,对传输的数据编码方式有严格的要求
3 解决方案
经过对多个打印插件的对比,选择了lodop插件,国产,小巧,简单上手,开发难度低是选择它的理由,下面以lodop进行条形码打印为例子进行说明。
-
- 到lodop官网下载lodop服务www.lodop.net/download.html,根据自己的浏览器来选择进行安装,安装完后启动服务即可,同时官网上还有lodop的开发手册,也下载一份
- 在项目中使用lodop。在下载的开发手册中,有很多Lodop提供的开发样例,参考其中的开发样例进行开发,找到LodopFuns.js,将js拷贝到项目中
-
- HTML文件的head标签中加载lodop控件
<object id="LODOP_OB" classid="clsid:2105C259-1E0C-4534-8141-A753534CB4CA" width=0 height=0> |
-
- 引入lodopFuns.js,在object标签的后面引入
|
-
- 声明一个全局的lodop对象,并操作打印服务,lodop提供了很多不同形式的打印功能,对应不同的打印函数,具体的函数的使用,可查看lodop提供的打印样例
//获取lodop实例 Var LODOP=getLodop(document.getElementById('LODOP1'),document.getElementById('LODOP_EM1')); //将条码的数据输出到Lodop设计器 LODOP.ADD_PRINT_BARCODE(28,34,307,47,"128A","123456789012"); //启动lodop的条码设计器进行打印预览 LODOP.PREVIEW(); |
-
- 调用LODOP.PREVIEW();方法将会弹出lodop打印预览窗口,在打印预览窗口可以进行各种打印的设置,选择指定的打印机进行打印就可以看到效果了
- 以上的打印是基于lodop提供的打印设计功能进行打印的,存在两个缺点
- 需要预先对条码进行定位,点阵计算复杂
- 在打印前会启动lodop的设计器,无形中增加了一步操作,对用户来说并不友好
在我们项目中使用的斑马GK888T打印机是支持ZPL指令进行条形码打印的,查看lodop文档,发现lodop也支持直接将打印指令打住发送到打印机
/* 直接发送指令进行打印将不会弹出lodop的设计器,因此用户无法在发送指令前选择打印机,所以需要先让用户选择打印机,然后再发送指令,该方法将会弹出lodop的打印机选择窗口,用户选择打印机,将会一直生效到下一次选择打印机之前。 */ LODOP.SELECT_PRINTER(); |
//设置传输指令的格式 LODOP.SET_PRINT_MODE("SEND_RAW_DATA_ENCODE","UTF-8"); if (LODOP.CVERSION) { LODOP.On_Return=function(TaskID,Value){ if (Value) alert("发送命令成功"); else alert("发送命令失败!"); }; //发送打印指令 LODOP.SEND_PRINT_RAWDATA(strData); return; }; |
---------------------
原文来自【学领未来】,转载时请保留原文链接。
链接:http://bbs.learnfuture.com/topic/290