首先给出结论,如果要采用标准web技术实现无预览打印或者称之为静默打印是行不通的。
无论是chrome系的浏览器还是FireFox浏览器,调用print方法对目标内容进行打印时要么显示一个打印预览窗口,要么显示一个传统的打印配置窗口,且这个窗口无论如何配置都会存在,这样就使得我们使用标准浏览器技术将打印内容直接交给打印机打印的希望成为泡影。
标准浏览器技术无法实现点击后直接打印的目的,那只能换个思路,比如开发一个浏览器插件,但现代浏览器基本上都已经不再支持插件,即使某些浏览器勉强支持,升级到下一个版本,也极有可能运行不了,所以浏览器插件这条路基本上也是不可行的。
WebSocket
是的,我们想到了WebSocket。
WebSocket 协议在2008年诞生,2011年成为HTML5标准,目前在所有浏览器都可以直接发起一个WebSocket请求。
这就意味着我们可以在浏览器中向目标WebSocket Server发送请求,从而将我们需要打印的数据传递给目标WebSocket Server,然后这个WebSocket Server在收到打印数据后,调用本地打印机,实现我们想要的打印功能。
无预览静默打印实现
在明确可以借助WebSocket实现无预览静默打印的功能后,接下来,我们只需要使用某种我们为熟悉的语言开发一个WebSocket Server的桌面应用即可。
开发一个WebSocket Server的桌面应用,选择很多,比如我们可以使用Java、C#、C++...。在这个WebSocket Server中,通过访问本地打印机,在收到合法的打印请求后即可将请求发送的内容交由打印机直接打印,而不用显示打印配置或打印预览窗口之类,从而实现无预览静默打印需求。
这个WebSocket Server的桌面应用开发完成后,只需要让其运行于可以连接到打印机的服务器上即可。考虑到市面上多数打印机都只提供了Windows的驱动,所以我们的WebSocket Server的桌面应用也只需要支持Windows,不需要考虑跨平台运行的问题。
当我们在浏览器中要打印某个具体内容时,为了规范打印格式,我们一般会将打印内容输出到一个PDF文件当中,打印时选择直接打印这个PDF文件即可。
在浏览器中借助WebSocket Server打印一个PDF文件实现的思路有两种:一种是将目标PDF文件的URL直接发送给WebSocket Server的桌面应用,WebSocket Server的桌面应用在收到这个URL后,内部去下载这个PDF文件,然后再去打印它;另一种思路就是在浏览器中先下载这个PDF文件,将文件以字符串的形式发送给目标WebSocket Server的桌面应用,WebSocket Server的桌面应用在收到这个PDF文件内容后再将其反序列化成一个具体的PDF文件后再进行打印。
将一个PDF文件转换成一个字符串,可以考虑采用Base64 编码实现
这两种思路实现起来各有优缺点,第一种思路实现起来比较简单,但容易受到环境影响,比如下载PDF文件时需要用户登录时,这种思路实现起来就相当的麻烦;第二种思路实现起来相对复杂,但不存在第一种思路中下载PDF文件可能需要登录的影响。
实例参考
在BaskReport报表中就是采用WebSocket实现的无预览静默打印功能,它的WebSocket Server的桌面应用是使用Java开发,并且已封装成一个可以在Windows上运行的exe文件,鉴于Java的特点,运行这个exe时需要安装并配置好JDK,这个WebSocket Server的桌面应用界面效果如下:
在它这个WebSocket Server的桌面应用中,允许用户配置打印服务端口,这样在Web浏览器中,通过WebSocket将打印内容发送给这个打印服务器时除了要指定打印服务器的地址,还需要指定端口。
在BaskReport中浏览器调用无预览静默打印服务时配置的窗口如下图所示:
关于BaskReport报表的详情可点击basksoft.com/了解,BaskReport的无预览静默打印使用参见basksoft.com/doc/report/…。
BaskReport报表的WebSocket Server是使用Java开发,个人觉得不是最好的解决办法,如果您熟悉C#的话,用C#做一下WebSocket Server的桌面应用,相信肯定会比Java的实现起来好。