vue项目中点击按钮实现打印面单需求

853 阅读6分钟

体会及需求

这个需求,最初是在终端由后端实现的,具体怎么实现的,问了几次没告诉我,所以我觉得是公司机密,不方便透露给我或者后端同事怕我学会了抢他饭碗,没关系,我负责实现需求就好了。后来用户想要在web端也有这个效果,所以就有了这个需求。一开始听老大说到这个需求,感觉挺简单的,无非就是点击按钮直接调用window.print这个打印方法即可。然后老大就继续补充了,说需要用户输入件数,联数,托盘数。然后有两个按钮,一个是按件数打印,打印出来的纸张数量=件数×联数,一个是按托盘数打印,然后打印出来的纸张数量=托盘数×联数。并且打印的面单内容会根据输入的联数实现一个动态的打印,比如用户输入联数2,件数2,就会打印出来4张纸,每三张纸会有三个数字,也就是联数,用户输入的是2,那么4张纸显示的联数分别就是1,2,1,2。页面效果如下图一(弹出窗用的是elementUI的组件),最终打印纸的效果如图二。老大说研究一下看能否实现,不能就算了,开什么玩笑,我的人生格言可是——没什么需求是我搞不定的,如果有,那就算了......

图一:image.png 图二:image.png

用过的方案

在研究需求过程中,用到了几个方案,如:window.print()方法,print-js库,JQ的print,Lodop库,vue-print-nb,hiprint。经过无数次的尝试后,最终选择了vue-print-nb,其实感觉print-js库也能实现,建议自己百度一下。Lodop的话实现静默打印是要钱的,默默放弃了

问题一:局部打印

vue-print-nb的教程链接:juejin.cn/post/708887…

安装和引入使用方法都在链接有,直接在想要打印的区域标签加个id,如printFn,然后打印的按钮加个v-print="printFn",就可以实现局部打印了。

问题二:页面显示的效果跟打印预览的效果不同

直接写行内样式即可调整打印预览的效果,或者在样式中使用@media print这个来写样式,具体的可以自行百度这个用法

问题三:打印图片或PDF会有锯齿

我感觉这是整个需求中最难搞定的一部分,查了许久,也问了同事,都没法解决,原因是打印机的分辨率太低,后端返回图片的话,直接放上去打印出来会有锯齿或者模糊。

解决方法:直接前端手写样式,如同问题二解决的方法一样,替代图片,至于小图标原本是UI给的是图片形式,现在为了打印只能使用阿里巴巴的字体图标iconfont了,如果在阿里巴巴矢量图标库找不到替换的图标,就将就着用图片吧

问题四:后端返回条形码是图片

又是该死的图片,打印出来又是该死的锯齿且模糊。没办法,只能让后端返回条形码的数字给我,然后我这里直接用JsBarcode这个东西生成条形码

image.png JsBarcode的教程链接:juejin.cn/post/684490…

问题五:根据用户输入的内容动态打印纸张数量和内容

打印张数的话,因为前面体会和需求那里提到的计算公式,所以我使用的是直接两层v-for生成用户输入的内容,然后给它加个margin-bottom,相当于把他当成一页,然后用外边距把另一页挤下去,这样就能实现打印张数的设置了。问题就是要一次一次的去打印调试样式。而内容也就是联数的动态打印,就直接索引+1即可

image.png

问题六:页面中隐藏要打印的内容,打印预览时在预览中显示

这个问题用的是bootstrap+JQ解决的,直接安装引入,然后给想要隐藏的标签加个行内样式名class="visible-print-block"。老大觉得引入bootstrap+JQ太麻烦,最终选择用定位把要打印的内容给顶出页面。这个也比较容易解决,百度出来的方法有很多,自行选择即可。

问题七:件数不同,条码也应该不同才对。由于前面的设置,导致条码一直是同一个

由于需求就是输入件数2,应该会有2个不同的条形码才对。由于前面的设置,导致条码一直是同一个。

解决方法:遍历生成条形码的时候,加上一个id,然后在id名后面加上遍历的索引。接着在js中生成条形码的时候也遍历一下,然后也是用id+索引的形式。这样就能实现生成不同的条形码了

image.png

可以参考该网站:blog.csdn.net/weixin_4391…

问题八:v-print和点击事件都绑定在同一个标签上会出现的Bug

由于v-print和点击事件都绑在一个按钮上面,在点击事件里面我们需要拿后端数据和用户输入的数量进行一个渲染遍历,也就是一个异步的操作。如果都绑在同一个按钮上面就会导致DOM还没遍历生成,打印预览页面就出来了,所以会看到预览页面一片空白。针对这个问题,研究了一天,最终选择摆烂方案,也就是再加多一个按钮。前面用户输入完数量,点击按件数或者按托盘数打印的按钮时,先获取数据遍历生成DOM,然后再弹出一个弹窗,是否确认打印,然后在确认的那个按钮绑定v-print属性。

image.png

建议

建议一步一步来,发现一个问题就先解决这个问题

1.先看看电脑连接打印机,随便拿一个文件或者打印测试页打印一下看看能不能打印出来,一般需要下载打印机对应的驱动

2.页面弄一个打印按钮,然后点击看看能不能打印

3.看后端返回的数据是什么,比如图片或者PDF或者文字,自己先写个静态模拟一下,看打印出来的效果

4.进一步实现需求,比如对接后端,实现动态打印,用户输入内容和纸张数量,静默打印,局部打印,页面隐藏打印内容