生产制造追溯系统-再说条码打印
前言
在之前的博客中我介绍了如何实现生产现场的条码打印,我们的生活中到处都是条码,一维码、二维码随处可见,更别说一家从事生产制造加工的工厂了,而条码种类繁多、离线打印等情况就直接导致了条码管控上的难度,甚至会出现较为严重的品质事件,上一个版本中我是通过web应用程序调用 winform 中的函数进行打印,winform中嵌套了 webbrowser 来浏览网页,通过这几年的实际运用,这个方法基本能够满足大部分需求,但还是美中不足,由于 webbrowser 所示用的浏览器内核比较低,导致很多样式无法兼容,尽管网络上有一些方法去改变这个问题(比如webkit,cef,修改注册表等等),但总是或多或少有一些问题。
新的方案,告别 winform & webbrowser
我们本次以生产线 卡通包装 工位为例,进行描述:
通常情况下,操作员会扫描多个彩盒条码,这个扫描的数量一个到多个不等,每一个彩盒上面都有一个唯一的条形码或二维码,当彩盒扫描完成以后需要结束装箱,此时系统应该直接将对应的卡通标贴打印出来,操作员从打印机上撕下卡通标贴并贴于卡通箱,在此之前我们需要提前将卡通标贴的打印模板制作出来并上传至系统中,操作界面如下,支持同一个产品打印多张标贴:
此时,我们需要编写一个 api 来获取服务器上面的模板文件以及需要打印出来的数据列表,关键代码如下:
string serverurl = xmlhelper.getxmlreader(path, "config", "server"); string api = xmlhelper.getxmlreader(path, "config", "api"); //通过 api 获取模板文件******************************************************************* string _btw_url = api + "?action=get_carton_label&carton_sn=" + _carton_sn; httphelper http_btw = new httphelper(); //创建httphelper参数对象 httpitem item_btw = new httpitem() { url = _btw_url,//url必需项 contenttype = "application/json", }; httpresult req_result_btw = http_btw.gethtml(item_btw); string btw_str = req_result_btw.html; jobject obj_btw = (jobject)jsonconvert.deserializeobject(btw_str); datatable dt = library.jsonlib.todatatable(obj_btw["msg"].tostring()); //通过 api 获取模板文件*******************************************************************
webclient web = new webclient(); string _api_url = api + "?action=get_carton_print_list&carton_sn=" + _carton_sn; httphelper http_data_list = new httphelper(); //创建httphelper参数对象 httpitem item_data_list = new httpitem() { url = _api_url,//url必需项 contenttype = "application/json", }; httpresult req_result_data_list = http_data_list.gethtml(item_data_list); string print_str = req_result_data_list.html; jobject obj = (jobject)jsonconvert.deserializeobject(print_str); string _key = obj["msg"]["key"].tostring(); string _value = obj["msg"]["value"].tostring(); string splitkey = "*"; string[] keys = _key.split(splitkey.tochararray(), stringsplitoptions.none); string[] values = _value.split(splitkey.tochararray(), stringsplitoptions.none); for (int i = 0; i < dt.rows.count; i++) { _file_url = serverurl + "app/cartonlabel/" + dt.rows[i]["label_file"].tostring(); _file_name = system.guid.newguid().tostring() + "_" + dt.rows[i]["label_file"].tostring(); web.downloadfile(_file_url, _directory + _file_name); _print(); }
api 编写完成之后我们进行发布,发布到本地指定一个文件夹留作备用,现在我们还差一步,那就是如何通过网页在客户端本地打印?大家都知道我们的网站是部署在服务器而非客户端本地的,但是打印的条码必须出现在客户端本地的打印机,此时你可以考虑通过网络共享打印机的办法来实现,但是这种方法非常不稳定,一些安全方面的设置就足以让你内流满面,因此我们可以考虑使用 cassinidev 来实现,大致思路如下:
- 新建一个批处理或者其它类型的程序。
- 在项目中引用 cassinidev 文件至。
- 在本地new一个服务实例并启动。
通过如下代码即可启动该服务:
new server(9001, "/", system.io.path.combine(appdomain.currentdomain.basedirectory, "service"), system.net.ipaddress.parse("127.0.0.1"), "", 0, false, false);
在包装之前我们将该服务启动起来,我做了一个简单的界面,如下图所示:
此时,我们需要用到上一步发布的 api,将发布的 api 文件拷贝至service目录,这个service目录在这个批处理程序的根目录下面,至此所有的前期工作已经做完了,现在只需要调用本地这个api 即可。 我们选择 mo-00002 这个工单进行演示:
下面开始扫描条码进行包装,该产品的包装容量为每一个卡通箱需要包装 4 个彩盒。
系统提示打印命令发送成功的时候,我们的打印机已经自动将标贴打印出来了,如下图所示:
结论
相对之前的 webbrowser,目前这种方式可以更好的兼容样式表,比如h5,再就是同一套系统不用分为网页端与客户端,尽管打开的是同一个网站;维护起来也要更加方便。
推荐阅读