[转载]浏览器批量打印条码纸 - 郑某 - 博客园

[转载]浏览器批量打印条码纸 – 郑某 – 博客园.

前两天遇到了一个需要浏览器打印条码的需求,因为目前的管理系统是基于B/S的,在生产管理员用户那里需要将订单转为生产指令单,与此同时需要将订单中的产品批量打印出来条码纸来,以便生产完毕后贴到产品上面方便扫码入库和标注产品。

 先从打印机开始

    提供给我的是一台科诚打印机G500,实际使用效果还不错。目前很多的条码打印机厂商提供了可视化的条码打印软件,可以直接打印出来条码,还可以生成相应的EZPL指令,方便开发者使用指令来开发条码打印,当然还提供了基础的二次开发包和文档。

   下图是科诚官网下载的GO-LABLE打印设计软件。

使 用非常简单,摆弄一会儿就明白怎么玩了,这款打印软件提供了基础的条码图形,文字和图像图形工具,拖动到设计界面即可,这里需要注意的是,在使用字体的时 候有两种可以选择,一种是打印机内建字体,一种是windows字体,如果你条码上的文字不需要改变了,那就建议使用windows字体,这样打印出来的 文字清晰度很高,如果文字需要动态改变,比如我遇到的这个需求,那么就必须使用内建字体了,双击条码上的文字,会出现文字设定:

这里我选择了亚洲字体,使用前需要先下载亚洲字体到打印机,其实就是把本机的中文字体下载到打印机。其他的文字来源我试过了,但是只有这个选项可以打印出来中文而不出现乱码。

设计完成后,我们可以输出指令到右面的命令视窗,多观察一下,你会发现其实这就是按照一定的规则生产的一串配置信息,告诉打印机纸张的大小信息,要 出现一个什么样的图像,什么文本的文字,文字的字体类型,以及所有的这些元素的位置坐标信息,有了这些信息,打印机便可以按照要求输出打印图像了。我们可 以试着改变命令窗口的信息,然后输入回到设计界面,你就会发现设计效果已经按照你的修改发生了改变。

大家可能已经发现了,我在所有需要动态更改的地方,用@+相应的字段表示,目的就是为了以此为模板,通过替换模版的元素达到动态输出的效果。

这里着重讲一下二维码配置信息

W30,22,5,2,M,8,10,5,0
@单号

其中“@单号”是二维码的文本信息,上面配置信息倒数第二个,也就是那个“5”,是二维码信息的长度,,一个中文是两个字节,所以“@单号”的长度就是5了,如果文本信息换成其他的了,这里的“5”,也要做相应的改变。

制作ActiveX控件

如 果是做成winform,程序,那应该说是非常的简单了,直接调用提供的dll就行了,可现在要求在浏览器中完成这个任务,浏览器想调用dll,那就得用 的ActiveX控件了。关于ActiveX控件的开发和安装部署,网上有一些教程,其实和做winform差不多,只是添加一下guid,修改一下控件 属性就行了,真的是非常方便。下面把核心代码贴出来

//Trace.dll是官方提供的,放到bin文件夹下面<br>[DllImport("Trace.dll")]
        public static extern void sendcommand(
            [MarshalAs(UnmanagedType.LPArray)]
            byte[] command);
 public void printdata(string danhao,string kehu,string guige,string houdu,string yanse,string kuandu,string gaodu,string pingmi)
        {<br>            //获取程序集的文件夹目录,也就是安装后控件程序集所在的目录
            string sApplicationPath = Assembly.GetExecutingAssembly().Location;<br>//找到Data.cmd,这里是命令窗口中生成的那些指令信息,放到bin文件下,安装程序会把控件的dll和这个Data.cmd一起打包输出,这里就要求安装程//序务必吧Data.cmd包含进去。如果是调试状态,程序或到obj/debug文件下寻找Data.cmd,所以为了调试不出错,也放到那里一份Data.cmd
            sApplicationPath = sApplicationPath.Replace("CodexPrint.dll","Data.cmd");          
            using (StreamReader sr = new StreamReader(sApplicationPath, Encoding.GetEncoding("GB2312")))
            {
                StringBuilder sb = new StringBuilder();
                string sLine = "";
                while (sLine != null)
                {
                    sLine = sr.ReadLine();
                    if (sLine != null && !sLine.Equals(""))
                    {<br>                        //特别要注意必须每次读一行后添加上换行符,否则待会还原成字节数组的时候发给打印机,打印机不懂你在讲什么
                        sLine += Environment.NewLine;
                        sb.Append(sLine);
                    }
                }
                sr.Close();<br>                //去除空的部分
                string temp = sb.ToString().Trim();
 
                //获取单号的字节长度,替换"@单号"的长度5,一个汉字两个长度
                string erweimapeizhixinxi=temp.Substring(temp.IndexOf("W30"),(temp.LastIndexOf("@单号") -temp.IndexOf("W30") -1));
                string[] arraytemp=erweimapeizhixinxi.Split(new char[]{','});
                arraytemp[arraytemp.Length - 2] = Encoding.GetEncoding("GB2312").GetBytes(danhao ).Length.ToString();
                temp = temp.Replace(erweimapeizhixinxi,string.Join(",",arraytemp));
 
                //开始替换数据
                temp = temp.Replace("@单号", danhao);
                temp = temp.Replace("@客户", kehu);
                temp = temp.Replace("@规格", guige);
                temp = temp.Replace("@厚度", houdu);
                temp = temp.Replace("@颜色", yanse);
                temp = temp.Replace("@宽度", kuandu);
                temp = temp.Replace("@高度", gaodu);
                temp = temp.Replace("@平米", pingmi);
                
                byte[] buffer = Encoding.GetEncoding("GB2312").GetBytes(temp);
                openport("6"); //Ex:USB
                try
                {
                    sendcommand(buffer);
                    closeport();
                }
                catch (Exception error)
                {
                    MessageBox.Show(error.Message);
                    return;
                }
            }
        }

这样ActiveX控件的开发就基本完成了,然后就可以在PC安装了,类似工行网站在使用之前必须安装控件一样。

页面使用

ActiveX控件安装完毕后,页面的使用就简单了


在startprint方法里,我们可以通过js来调用控件中的printdata方法了。这里我循环了表格中的数据,然后逐行打印

<script type="text/javascript">
     function startprint() {
         var p = document.getElementById("BarCodePrint");
         var tableObj = document.getElementById("data");
         for (var i = 1; i < tableObj.rows.length; i++) {
             var rowcells = tableObj.rows[i].cells;
             var jsondata = { "danhao": rowcells[0].innerHTML, "kehu": rowcells[11].innerHTML, "guige": rowcells[1].innerHTML + rowcells[2].innerHTML,
                 "yanse": rowcells[3].innerHTML, "houdu": rowcells[4].innerHTML, "kuandu": rowcells[5].innerHTML, "gaodu": rowcells[6].innerHTML,
                 "pingmi": rowcells[10].innerHTML
             };
            //也可以省去定义json的过程,直接将数据传入下面的方法
            p.printdata(jsondata.danhao, jsondata.kehu, jsondata.guige, jsondata.houdu, jsondata.yanse, jsondata.kuandu, jsondata.gaodu, jsondata.pingmi);           
         }
                     
     }      
     
    </script>

这样整个工作就完成了,实测效果良好。ActiveX控件只能在IE下使用,谷歌浏览器还得使用其他插件配合,不过作为生产环节上的一环,要求工作人员使用IE就行了,呵呵。如果有一天突然想改变标签上的布局了,那么在GO-LABLE中重新设计好后生成新的指令,找到ActiveX控件的安装目录,找到Data.cmd,替换掉原来的的指令就可以了。但是这里面的模版替换元素必须形式一样,而且不能增加新的字段,如果增加的话,那就得重新开发升级ActiveX控件了。其实还有更灵活的方法,比如只传入方法一个字符串,里面包含了需要替换的标签和标签数据,通过分隔符区分,比如“@单号:0000001|@颜色:红色|………”,然后进行字符串处理就行了。当然页面的调用形式也相应做出改变就行。

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏