java调用zebra斑马打印条码+英文+数字+中文

news/2024/11/23 20:09:53/

打印机型号:GT800,只要支持zpl,下面的方式都可以通用。
打印的具体样式如下所示:有引用其他文章的打印方式,但是不通用,而且中文这块,打印出来是反的,并且我需要一次性打印两张一样的,参考的链接百度都是那篇文章,如下:这是原博主的,百度很多都是抄这个一模一样,我在zpl语言那边有改进,具体看下面代码,有详细解析
在这里插入图片描述

先贴上整个类的代码,其中有一个ts24.lib文件我放在网盘,那玩意老费劲不好找,
网盘地址:链接:https://pan.baidu.com/s/1hsPz0F1uBBgg0hlRQDbIfw
提取码:o00d

package com.lims.common.core.utils.print;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.standard.PrinterName;//import sun.awt.AppContext;
/*** 采用点阵字库ts24.lib* @author Labrador**/
public class ZplPrinter {private String printerURI = null;			//打印机完整路径private PrintService printService = null;	//打印机服务private byte[] dotFont;private String darkness = "~SD10";	//Set Darkness设置色带颜色的深度 0-30private String width = "^PW1000";	//Print Width打印宽度0-1500private String length = "^LL800";	//Label Length标签长度0-x(暂无作用)private String begin = "^XA" + darkness + width;	//标签格式以^XA开始private String end = "^XZ";			//标签格式以^XZ结束private String content = "";		//打印内容private String message = "";		//打印的结果信息/*** 构造方法* @param printerURI 打印机路径*/public ZplPrinter(String printerURI){this.printerURI = printerURI;//加载字体File file = new File("C:\\Users\\gonghf\\Desktop\\ts24.lib");if(file.exists()){FileInputStream fis;try {fis = new FileInputStream(file);dotFont = new byte[fis.available()];fis.read(dotFont);fis.close();} catch (IOException e) {e.printStackTrace();}}else{System.out.println("C://ts24.lib文件不存在");}//初始化打印机//AppContext.getAppContext().put(PrintServiceLookup.class.getDeclaredClasses()[0], null);//刷新打印机列表PrintService[] services = PrintServiceLookup.lookupPrintServices(null,null);if (services != null && services.length > 0) {for (PrintService service : services) {if (printerURI.equals(service.getName())) {printService = service;break;}}}if (printService == null) {System.out.println("没有找到打印机:["+printerURI+"]");//循环出所有的打印机if (services != null && services.length > 0) {System.out.println("可用的打印机列表:");for (PrintService service : services) {System.out.println("["+service.getName()+"]");}}}else{System.out.println("找到打印机:["+printerURI+"]");System.out.println("打印机名称:["+printService.getAttribute(PrinterName.class).getValue()+"]");}}/*** 设置条形码* @param barcode 条码字符* @param zpl 条码样式模板*/public void setBarcode(String barcode,String zpl) {content += zpl.replace("${data}", barcode);}/*** 中文字符、英文字符(包含数字)混合* @param str 中文、英文* @param x x坐标* @param y y坐标* @param eh 英文字体高度height* @param ew 英文字体宽度width* @param es 英文字体间距spacing* @param mx 中文x轴字体图形放大倍率。范围1-10,默认1* @param my 中文y轴字体图形放大倍率。范围1-10,默认1* @param ms 中文字体间距。24是个比较合适的值。*/public void setText(String str, int x, int y, int eh, int ew, int es, int mx, float my, int ms) {byte[] ch = str2bytes(str);for (int off = 0; off < ch.length;) {if (((int) ch[off] & 0x00ff) >= 0xA0) {//中文字符try {int qcode = ch[off] & 0xff;int wcode = ch[off + 1] & 0xff;
//                    content += String.format("^FO%d,%d^XG0000%01X%01X,%d,%d^FS\n", x, y, qcode, wcode, mx, my);content += String.format("^FO%d,%d^XG0000%01X%01X,%d,%f^FS\n", x, y, qcode, wcode, mx, my);
//                    System.out.println("content===="+content);begin += String.format("~DG0000%02X%02X,00072,003,\n", qcode, wcode);qcode = (qcode + 128 - 32) & 0x00ff;wcode = (wcode + 128 - 32) & 0x00ff;int offset = ((int) qcode - 16) * 94 * 72 + ((int) wcode - 1) * 72;for (int j = 0; j < 72; j += 3) {qcode = (int) dotFont[j + offset] & 0x00ff;wcode = (int) dotFont[j + offset + 1] & 0x00ff;int qcode1 = (int) dotFont[j + offset + 2] & 0x00ff;begin += String.format("%02X%02X%02X\n", qcode, wcode, qcode1);}x =  x + ms * mx;off = off + 2;} catch (Exception e) {e.printStackTrace();//替换成X号setChar("X", x, y, eh, ew);x = x + es;//注意间距更改为英文字符间距off = off + 2;}} else if (((int) ch[off] & 0x00FF) < 0xA0) {//英文字符setChar(String.format("%c", ch[off]), x, y, eh, ew);x = x + es;off++;}}}/*** 英文字符串(包含数字)* @param str 英文字符串* @param x	x坐标* @param y y坐标* @param h 高度  H* @param w 宽度*/public void setChar(String str, double x, double y, int h, int w) {content += "^FO" + x + "," + y + "^AQN," + h + "," + w + "^FD" + str + "^FS";}/*** 英文字符(包含数字)顺时针旋转180度* @param str 英文字符串* @param x	x坐标* @param y y坐标* @param h 高度* @param w 宽度*/public void setCharR(String str, int x, int y, int h, int w) {content += "^FO" + x + "," + y + "^A0I," + h + "," + w + "^FD" + str + "^FS";}/*** 获取完整的ZPL* @return*/public String getZpl() {return begin + content + end;}/*** 重置ZPL指令,当需要打印多张纸的时候需要调用。*/public void resetZpl() {begin = "^XA" + darkness + width;end = "^XZ";content = "";}/*** 打印* @param zpl 完整的ZPL*/public boolean print(String zpl){if(printService==null){message = "打印出错:没有找到打印机["+printerURI+"]";System.out.println("打印出错:没有找到打印机["+printerURI+"]");return false;}DocPrintJob job = printService.createPrintJob();byte[] by = zpl.getBytes();DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;Doc doc = new SimpleDoc(by, flavor, null);try {job.print(doc, null);message = "已打印";System.out.println("已打印");return true;} catch (PrintException e) {message = "打印出错:"+e.getMessage();System.out.println("打印出错:"+e.getMessage());e.printStackTrace();return false;}}public String getMessage(){return message;}/*** 字符串转byte[]* @param s* @return*/private byte[] str2bytes(String s) {if (null == s || "".equals(s)) {return null;}byte[] abytes = null;try {abytes = s.getBytes("gb2312");} catch (UnsupportedEncodingException ex) {ex.printStackTrace();}return abytes;}//^B3N,Y,Y  code39条形码public  boolean printBarcode(ZplPrinter p){//1.打印单个条码String bar0 = "D21066000101";//条码内容String str = "厦门湖里永康门诊部";String bar0Zpl = "^FO190,90^BY1.4,3,80^BCN,60,N,N,N^FD${data}^FS";//条码样式模板p.setBarcode(bar0, bar0Zpl);p.setCharR(bar0,200,60,25,25);content += "^CI26^SEE:GB18030.DAT^CWJ,E:MSUNG24^CI28^FO160,20^A1I,10,10^FD"+str+"^FS";
//        p.setText("厦门湖里永康门诊部", 160, 120, 10, 10, 30, 1, 0, 24);content += "^FO500,90^BY1.4,3,80^BCN,60,N,N,N^FD"+bar0+"^FS^FO510,60^A0I,25,25^FD"+bar0+"^FS^FT680,20^A1I,10,10^FD"+str+"^FS";String zpl = p.getZpl();System.out.println(zpl);boolean result = p.print(zpl);//打印return result;}public static void main(String[] args) {ZplPrinter p = new ZplPrinter("ZDesigner GT800 (EPL)");p.printBarcode(p);}
}

代码解析:
首先要找到打印机:原博主是通过远程分享的方式\pch啥玩意的,我是直接根据打印机的名字来,具体的可以看下面这个方法的service.getName,自己debug找一下自己的打印机名字就知道了

        PrintService[] services = PrintServiceLookup.lookupPrintServices(null,null);if (services != null && services.length > 0) {for (PrintService service : services) {if (printerURI.equals(service.getName())) {printService = service;break;}}}

第二步就是那个lib文件,自己下了自己放
第三步就看如下这个方法里面的东西了,精髓都在这了:

    //^B3N,Y,Y  code39条形码public  boolean printBarcode(ZplPrinter p){//1.打印单个条码String bar0 = "D21066000101";//条码内容String str = "厦门湖里永康门诊部";String bar0Zpl = "^FO190,90^BY1.4,3,80^BCN,60,N,N,N^FD${data}^FS";//条码样式模板p.setBarcode(bar0, bar0Zpl);p.setCharR(bar0,200,60,25,25);content += "^CI26^SEE:GB18030.DAT^CWJ,E:MSUNG24^CI28^FO160,20^A1I,10,10^FD"+str+"^FS";
//        p.setText("厦门湖里永康门诊部", 160, 120, 10, 10, 30, 1, 0, 24);content += "^FO500,90^BY1.4,3,80^BCN,60,N,N,N^FD"+bar0+"^FS^FO510,60^A0I,25,25^FD"+bar0+"^FS^FT680,20^A1I,10,10^FD"+str+"^FS";String zpl = p.getZpl();System.out.println(zpl);boolean result = p.print(zpl);//打印return result;}

bar0Zpl 这个就是打印的模板,这个获取的方法,
第一,如果你的打印机比较高级,可以去下载ZebraDesigner 3 这个官网软件试试,会生成prn文件,我试过了我是用不了,不然就直接文本打开就可以看里面的zpl语言,这边这个链接可以看看你的打印机支持啥玩意:在文章的下面自己翻一下
第二:ZebraDesigner 3 for Developers 这个也是官方软件,这边可以去绑定变量然后去用,参考链接:工具的使用说明
第三:CODESOFT 2015这个软件要是有下过想研究的小伙伴感觉可以放弃了,这边中文什么的会乱码,有网上说找Unicode编码可以的,但是我没成功,有兴趣自己研究
第四:解答这个zpl:FO这个就是开始的意思,复制就好,后面两个190,90,是对应的xy坐标,自己去调整,BY这个是调整条形码的高度,宽度,然后中间那个空白的大小,那三个数字参数是这样的,第一个增幅是0.1,后面是1;BCN这个是D210000那个的字体调整,跟大小没啥关系,大小是下面方法调的

下面这个方法就是条形码替换,也可以直接写死,只是显得low一点

   public void setBarcode(String barcode,String zpl) {content += zpl.replace("${data}", barcode);}

再然后就是p.setCharR这个方法了,这个是我中间那一串数字的打印,里面有一个^AOI这个I是字体的方向,还有R,O好像,反正I是旋转180度,最下面我会附上这个zpl语言的文档,可以自己细看这个东西。
重点来了,中文字:我参考的是这篇博主的东西:但是这个里面的中文会乱码
所以我在中文这边里面加上了^CI28,这个就是转UTF-8的意思,这个博主里面有说到:具体可打开细看
^A1I,10,10 这个东西是调整中文的大小,我试过了,最小就是我图片那种的大小,负数也一样,只能往更大了调整,虽然我需要更小的字体,但是一直没法解决,如果有小伙伴研究出来了,可以滴滴我一下,不胜感激。中间那个数字字体可以xy坐标随便调整大小。
然后固定的^FS就是结尾的意思了
另一个重点同行打印两一个条码:^FD这个符号加上然后自己调整x坐标就可以了

这边附上几个觉得还不错zpl的语言文档:这个对字体的方向描述比较清晰
这个是整个zpl的文档,道客巴巴的比较规范
这个是其他博主写的,大同小异,得自己去看

基本上就是这些东西了,花了我三天时间,人都傻了,希望写了这么多,能对研究打印机的人有些帮助吧,要是有描述不太明白的地方或者有什么其他好的建议,可以给我留言或者直接邮箱我1095254145@qq.com
共勉!!


http://www.ppmy.cn/news/200331.html

相关文章

斑马打印机常见问题解决方案 条码打印机常见问题解决方案

一维条码本身是不能包含中文字符的&#xff0c;但是如果标签中有需要打印中文的地方出现乱码&#xff0c;那主要的原因出在您的打印软件上。如果您用的是斑马公司的BARONE 5.0或以下版本&#xff0c;必须在其软件的安装目录中的BIN目录中找到SETUP.INI文件&#xff0c;打开其文…

条形码的发展历史

条形码的发展历史 1949年美国人诺曼伍德兰&#xff08;Norman Joseph Woodland&#xff09;和伯纳德西尔弗&#xff08;Bernard Silver&#xff09;申请了用于食品自动识别领域的环形条形码&#xff08;公牛眼&#xff09;。1963年在1963年10月号《控制工程》杂志上刊登了描述…

什么是条形码?条形码的历史

条码概述      条形码是由美国的N&#xff0e;T&#xff0e;Woodland在1949年首先提出的&#xff0e;近年来&#xff0c;随着计算机应用的不断普及&#xff0c;条形码的应用得到了很大的发展&#xff0e;条形码可以标出商品的生产国、制造厂家、商品名称、生产日期、图书分…

关于手机条码识别的几个非常有用的网站

夏浪科技http://www.sumlung.com/cn/ 它做的东西就是我想要的&#xff0c;很好很强大。 它还提供手机微摄镜头&#xff0c;使得不具备微摄功能的手机能够进行微拍。 二维条码生成网站&#xff1a;http://www.mayacode.com/ 魔印http://www.moin.com.cn/index.jsp 里面的产品…

网络编程知识点总结(4)

sock服务端代码实现读写 前几章有具体介绍这几个函数&#xff0c;这里就简单罗列出来了 &#xff08;1&#xff09;socket()函数 int socket(int domain, int type, int protocol); &#xff08;2&#xff09;bind()函数: IP号端口号与相应描述字赋值函数 int bind(int soc…

android平板能玩吃鸡吗,刺激战场用什么平板好 平板吃鸡配置推荐

刺激战场用什么平板好&#xff1f;平板用户是比较多的&#xff0c;很多人都用其他的模拟器玩手游&#xff0c;这里的平板玩家更多&#xff0c;那么用什么平板好&#xff1f;下面是小编给大家带来刺激战场平板吃鸡配置推荐&#xff0c;快一起来看看吧。 刺激战场平板吃鸡配置推荐…

平板电脑安装软件_平板电脑用哪款便签软件比较好?

平板电脑是一个非常便携的智能移动设备&#xff0c;它的诞生让很多职场人士非常喜欢&#xff0c;平板电脑的体积较小&#xff0c;性能也不弱&#xff0c;让人们在性能和便携之间找到了平衡点。使用平板电脑的时候&#xff0c;有很多办公辅助类软件可供选择&#xff0c;平板电脑…

android10系统是平板电脑吗,买平板电脑应该选win10还是安卓系统?

哈喽小伙伴们大家好&#xff0c;我是节奏君~ 科技不断进步&#xff0c;大家对科技产品的要求也越来越高&#xff0c; 今天&#xff0c;我们就一起来讨论一下买平板电脑选系统的事~ 很多小伙伴都在纠结&#xff1a;到底应该买哪个好&#xff1f;win10还是安卓&#xff1f; 节奏君…