最近在公司里面做了个业务,主要是对接工业打印机打印条形码,然后在CSDN和稀土掘金看了一下其他的方案很久嘛,然后自己又总结了一些,加入了进来,方法可能有点low,大家有更好的方案推荐,可以评论区call下。

在这里主要是对接的一台比较老的机型,Zebra S4M机型 203Pi。

用到的亚银标签纸格式是60mm*38mm , 碳带也是60mm的,不过其他型号应该也是倒差不差的,差不了太多。

本文参考了本文Java调用Zebra800条码打印机_ts24.lib_fmwind的博客-CSDN博客

话不多说,直接上代码!

package com.south.framework.web.testPrint;import javax.print.*;
import javax.print.attribute.standard.PrinterName;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;//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 = "~SD22"; //Set Darkness设置色带颜色的深度 0-30private String width = "^PW1200";    //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("D:\\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("D://ts24.lib文件不存在");}//初始化打印机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, int 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);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 高度* @param w 宽度*/public void setChar(String str, int x, int y, int h, int w) {content += "^FO" + x + "," + y + "^A0," + h + "," + w + "^FD" + str + "^FS";}/*** 英文字符(包含数字)顺时针旋转90度* @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 + "^A0R," + h + "," + w + "^FD" + str + "^FS";}/*** ZPL条形码边框指令设置* @param x         边框的最右侧X轴坐标* @param y         边框的最右侧y轴坐标* @param width     边框的宽度* @param height    边框的高度* @param thickness 边框的粗细程度* */public void setBox(int x, int y, int width, int height, int thickness) {content += "^FO" + x + "," + y + "^GB" + width + "," + height + "," + thickness + "B^FS";}/*** ZPL条形码边框指令设置* @param x     边框的最右侧X轴坐标* @param y     边框的最右侧y轴坐标* @param h     条形码的高度设置* @param w     条形码的宽度设置* @param hw    条形码的宽高比 指宽度是高的倍数,不过好像有点瓦* @param size  设置条形码条码格式,可以不填,不填就是打印机将自动根据条码数据的内容选择最适合的条码格式。* Y,N,N 分别表示 第一个参数 Y 表示显示校验码,第二个参数 N 表示不显示文字标签,第二个参数 N 表示不显示文字标签。* 他还有一种写法 FO30,230^BY2,2,50^BCN,32,Y,N,N^FD>;EDEzj200303170006^FS 这里的>;起始符是为了告诉打印机这是Code 128条形码的起始位置* */public String setZPLGrammer(int x,int y,double h,int w,int hw,int size){return "^FO"+x+","+y+"^BY"+h+","+w+","+hw+"^BCN,"+size+",Y,N,N^FD${data}^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;}/**** @param unit 单位名称* @param orderId 工单号* @param type 类别*/public static boolean printPicking(String unit,String orderId,String type){ZplPrinter p = new ZplPrinter("ZDesigner S4M-203dpi ZPL");p.setText(unit, 253, 26, 40, 40, 20, 1, 1, 24);p.setChar(orderId, 253, 76, 20, 20);p.setText(type, 253, 120, 53, 53, 20, 1, 1, 24);String zpl = p.getZpl();//System.out.println(zpl);boolean flag=p.print(zpl);return flag;}}

这个是调用打印机的工具类代码,之看到CSDN别人的,然后可能加了些其他功能上去。

再来看测试类,封装了一个对象传进去在main方法里面进行测试。

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;public class ZplPrinterTest {public static void main(String[] args) throws ParseException {// 选择自己的打印机ZplPrinter zplPrinter = new ZplPrinter("ZDesigner S4M-203dpi ZPL");PrintGoods printGoods = new PrintGoods("测试打印电脑标签纸","戴尔主机","1234567890","222222A22M2222B222JH",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()),"DEzj200303170006");// 打印抬头zplPrinter.setText(printGoods.getTitileName(), 125, 10,40, 40, 20, 1, 1, 24);// 打印边框// 设置左边框zplPrinter.setBox(15,40,550,40,3);zplPrinter.setBox(15,80,550,40,3);zplPrinter.setBox(15,120,550,40,3);zplPrinter.setBox(15,160,550,40,3);zplPrinter.setBox(15,200,550,80,3);// 设置右边框zplPrinter.setBox(460,40,550,40,3);zplPrinter.setBox(460,80,550,40,3);zplPrinter.setBox(460,120,550,40,3);zplPrinter.setBox(460,160,550,40,3);zplPrinter.setBox(460,160,550,40,3);zplPrinter.setBox(460,200,550,80,3);// 打印字段zplPrinter.setText("设备编码", 50, 50, 40, 40, 20, 1, 1, 24);zplPrinter.setChar(printGoods.getCoding(), 170, 55, 20, 20);zplPrinter.setText("资产名称", 50, 90, 40, 40, 20, 1, 1, 24);zplPrinter.setText(printGoods.getGoodsName(), 170, 90, 40, 40, 20, 1, 1, 24);zplPrinter.setText("设备", 50, 130, 40, 40, 20, 1, 1, 24);zplPrinter.setChar("S/N", 100, 135, 20, 20);zplPrinter.setText("码", 130, 130, 40, 40, 20, 1, 1, 24);zplPrinter.setChar(printGoods.getSn(), 170, 135, 20, 20);zplPrinter.setText("购买时间", 50, 170, 53, 53, 20, 1, 1, 24);zplPrinter.setChar(printGoods.getShopTime(), 170, 175, 20, 20);// ZPL解析语句String bar2Pap = "^FO30,215^BY1.5,30,100^BCN,32,Y,N,N^FD${data}^FS";//条码样式模板zplPrinter.setZPLGrammer(30,215,1.5,30,100,32);// 将${data}替换成扫描二维码后展示的数据zplPrinter.setBarcode(printGoods.getBarCode(),bar2Pap);// 执行打印方法zplPrinter.print(zplPrinter.getZpl());}static class PrintGoods {private String titileName;private String goodsName;private String coding;private String sn;private String shopTime;private String barCode;public PrintGoods() {}public PrintGoods(String titileName, String goodsName, String shopTime, String coding, String sn,String barCode) {this.titileName = titileName;this.goodsName = goodsName;this.coding = coding;this.sn = sn;this.shopTime = shopTime;this.barCode = barCode;}public String getTitileName() {return titileName;}public void setTitileName(String titileName) {this.titileName = titileName;}public String getGoodsName() {return goodsName;}public void setGoodsName(String goodsName) {this.goodsName = goodsName;}public String getShopTime() {return shopTime;}public void setShopTime(String shopTime) {this.shopTime = shopTime;}public String getCoding() {return coding;}public void setCoding(String coding) {this.coding = coding;}public String getSn() {return sn;}public void setSn(String sn) {this.sn = sn;}public String getBarCode() {return barCode;}public void setBarCode(String barCode) {this.barCode = barCode;}@Overridepublic String toString() {return "PrintGoods{" +"titileName='" + titileName + '\'' +", goodsName='" + goodsName + '\'' +", shopTime='" + shopTime + '\'' +", coding='" + coding + '\'' +", sn='" + sn + '\'' +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (!(o instanceof PrintGoods)) return false;PrintGoods that = (PrintGoods) o;return Objects.equals(titileName, that.titileName) &&Objects.equals(goodsName, that.goodsName) &&Objects.equals(shopTime, that.shopTime) &&Objects.equals(coding, that.coding) &&Objects.equals(sn, that.sn);}@Overridepublic int hashCode() {return Objects.hash(titileName, goodsName, shopTime, coding, sn);}
}}

详细的讲解也写在里面的注释了,反正就是对于中文和英文数字是有格式要求的,中文要用setText指令来执行,英文和数字要用setChar指令执行

在这里可能需要用到一个点阵图ts24.lib,这个文件的链接我就放在下方了,不出意外就是长期有效了

链接:https://pan.baidu.com/s/1mUpF6xEzbiZRtADzQNTP3w?pwd=yyds
提取码:yyds

Java对接Zebra斑马打印机打印条形码相关相关推荐

  1. java使用佳博打印机打印条形码

    在实际开发中我们使用条形码打印机打印条形码,这里介绍下使用动态链接库TSClib.dll编辑方式打印条形码,还有js实现方式,这里不进行介绍,会给相关的demo 准备工作: 1.佳博打印机,如佳博GP ...

  2. Android Zebra斑马打印机 打印面单不清楚 解决方法

    刚开始的效果. 字体模糊. 分析原因: 1.打印机的打印浓度太低 2.文本字体不对 3.bitmap的问题 因为这个面单是通过view 获取到bitmap再喂给打印机打印的 下载打印机的驱动,设置打印 ...

  3. 浅谈Zebra斑马打印机三种打印方式的利弊

    经过几个项目的洗礼,对Zebra打印机有了一个初步的了解,也用了好几种方式进行通讯打印,下面我们来谈谈这几种方式的优缺点吧. 主要有以下三种方法: 1.利用ZPLII指令集编写带有位置信息,字体大小, ...

  4. Zebra斑马打印机编程C#--入门级别打印

    该篇介绍了Zebra打印机打印中文+英文+图片的方法,如果是单单打印英文的话,可使用Zebra自带指令打印Zebra利用指令绘制出图像打印.还有一篇博客是介绍Zebra三种打印方式的利弊Zebra斑马 ...

  5. 斑马打印机打印中文乱码的问题

    斑马打印机打印中文乱码的问题 前些天公司有需求需要使用web打印,咱也没弄过也没接触过呀,这种情况只能上官网看看了,因为我是用的是java环境,所以以下只介绍在java环境下解决的办法.这需要下载开发 ...

  6. 斑马打印机打印不出来字怎么解决

    在条码打印软件中制作标签的时候,有的时候标签内容比较多,可能不注意就在标签上或者数据源中添加了一个空对象,也没预览,就直接连接斑马打印机进行打印了.最后发现,点击打印之后,斑马打印机没反应,咨询是怎么 ...

  7. 【项目管理】Java使用pdfbox调用打印机打印PDF文件

    [项目管理]Java使用pdfbox调用打印机打印PDF文件 1.项目前言 2.项目实现 3.关键代码 4.效果演示 5.问题处理 5.1 安装对应字体 5.2 修改对应代码 系统:Win10 Jav ...

  8. Zebra斑马打印机指令编程进阶(语言通用)--利用指令绘制出图像打印

    之前介绍过Zebra的入门打印,由于Zebra指令繁多,并且自带字体不能打印中文,如果打印内容中有中文的话,还是推荐大家先用Graphic类先画好自己想要的image,然后将整张图片进行打印.而且调试 ...

  9. TSC打印机打印条形码和二维码,JS实现方式

    自上一篇TSC打印条形码和二维码的文章发布以来,有不 少网友咨询相关技术, 今天全部整理一下,实现的源码和文件也全部公开. -- 2019.03.28  整理最新的js打印的实现方式 说明: 1.以下 ...

最新文章

  1. 对于数据库连接池的一些思考和MyBatis的集成与使用
  2. mysql sqlserver对比_很用心的写了 9 道 MySQL 面试题
  3. 史上最大AI芯片诞生:462平方厘米、40万核心、1.2万亿晶体管,创下4项世界纪录...
  4. java htmldecoder_HTMLDecoder——开头的HTML编码的解码工具类(java)
  5. 六边形溯源追踪算法编程思想与代码
  6. springboot 访问html_Spring Boot中使用Spring Security进行安全控制
  7. Markdown 编辑器才是yyds|CSDN编辑器测评
  8. Facebook刷新开放域问答SOTA:模型训模型!Reader当Teacher!
  9. java 声明抽象方法_java – 类必须声明为abstract或实现抽象方法错误
  10. GRT上线Bancor提案已通过
  11. 解决springmvc在multipart/form-data方式提交请求在过滤器Filter中获取不到参数的问题
  12. Linux中如何查找占用硬盘体积最大的文件方法
  13. 如何设置tomcat定时自动重启
  14. ftp扫描工具下载,ftp扫描下载工具到底该怎么选择?
  15. 北大中文核心期刊目录(2004年版)工业技术类
  16. python输入个人所得税计算_分享一下python的个税计算代码
  17. 判断分数是否为无限循环小数
  18. python3表白代码弹窗_抖音整蛊表白电脑弹窗代码大全
  19. 135编辑器怎么复制html,微信公众号怎么复制别人的图文排版(图文模板复制方法)...
  20. 脱离.Net Framework运行doNet程序的简单方法

热门文章

  1. 进程同步与互斥c语言实验,操作系统进程同步与互斥实验报告.doc
  2. strerror函数使用
  3. 移动wifi显示限制服务器,wifi控制 云服务器异常
  4. Java项目:JSP航班机票销售管理系统
  5. FPGA开发法宝 IP核
  6. 血气分析试题计算机答案,血气分析与临床应用试题答案(最新).doc
  7. 登陆qq时显示服务器错误,刚才想上QQ的时候,显示无法登陆QQ,显示连接服务器超时,错误代码0x00000001是怎么回事啊!!急...
  8. 聚观早报 | 抖音超市上线;首架国产大飞机 C919 完成首次飞行
  9. java中parseint_Java parseInt()和parseFloat()的用法
  10. 【新知实验室-TRTC开发】实时音视频之欢度世界杯