在之前的项目中,关联到一些硬件,其中就有一款斑马的条码打印机,我当时使用的是ZT230-300dpi的型号。用该打印机来打印工业标签条码。在网上寻找资料都没有找到合适的,所以记录此篇来总结遇到的各种问题。
一、打印方式使用文件传送方式
目前采用的方式为发送打印指令文件来触发打印机打印效果,附上代码:
public static void main(String[] args) {
try {
Connection conn = new TcpConnection("192.168.1.20", 6101);
conn.open();
File file = new File("D:/glassModel");
FileOutputStream fos = new FileOutputStream(file);
OutputStreamWriter osw=new OutputStreamWriter(fos, Charsets.UTF_8);
String module ="^XA" +
"^PW390" +
"^BY3,3,97^FT14,111^BCN,,N,N" +
"^FD>:bm>500000001^FS" +
"^FT118,135^A0N,25,24^FB127,1,0,C^FH\\^FDbm00000001^FS" +
"^PQ1,0,1,Y^XZ";
fos.write(module.getBytes());
osw.flush();
osw.close();
String path = file.getAbsolutePath();
ZebraPrinter zebraPrinter = ZebraPrinterFactory.getInstance(conn);
zebraPrinter.sendFileContents(path);
} catch (Exception e) {
e.printStackTrace();
}
}
注:上面代码中的打印指令不包含中文字符,使用的zebra0 的默认字体。
常用指令的含义:(包含字体的引入)
^XA #指令开始
^CI28
^SEE:GB18030.DAT
^CW1,E:ARI000.FNT^FS #导入字体类型和代号
^MMP #打印模式使用剥纸
^PW283 #标签宽度
^LL0150 #标签高度
^LS0 #标签整体左右位置(12为1mm)正数往左,负数往右
^LT0 #标签整体上下位置(12为1mm)正数往下,负数往上
^BY2,3,99 #字段宽高w宽度,r宽度比,h高度
^FT51,121 #字段位置x,y
^BCN,,N,N #code128条码,方向(正常),高度,打印注释(否),采用校验(否)
^FD>;#{msg}^FS #条码数据
^FT51,144 #字段排版x,y(12为1mm)
^A1N,21,21 #使用字体1,方向N(正常),字体宽高w,h
^FH\^FD#{name} #{msg}^FS #字段数据
^PQ1,0,1,Y #打印数量,暂停切纸数,副本数,覆盖暂停计数
^XZ #指令结束
值得注意的是,生成的文件编码如果不指定,那么在打印中文字符时,可能出现字符无法被正确识别的问题。如果在指令中未设置剥纸方式打印速度浓度之类,则会使用打印机当前设置的参数。
二、打印方式使用图片打印方式
使用模板打印中文字符时需要打印机拥有中文字体库,而有些中文字库体积较大,而打印机的内通常较小,可能不能加装含中文的字体。这时可以采用生成图片打印的方式。将需要生成的条码和文字使用java的awt包变成bufferImage对象,然后使用zebra的SDK包中的API输出打印。
/**
* description: 将字符串转化为条码
* @param String
* @return BufferedImage
*/
public BufferedImage getBarCode(String msg){
OutputStream ous=null;
try {
File file=new File("code.jpg");
ous=new FileOutputStream(file);
if(StringUtils.isEmpty(msg) || ous==null)
return null;
//选择条形码类型(好多类型可供选择)
Code128Bean bean=new Code128Bean();
//设置长宽
final double moduleWidth=0.8;
final int resolution=150;
bean.setModuleWidth(moduleWidth);
bean.doQuietZone(false);
String format = "image/png";
// 输出流
BitmapCanvasProvider canvas = new BitmapCanvasProvider(ous, format,
resolution, BufferedImage.TYPE_BYTE_BINARY, false, 0);
//生成条码
bean.generateBarcode(canvas,msg);
canvas.finish();
//将生成的条码读取进来
BufferedImage bi=ImageIO.read(file);
//裁剪生成的条码
BufferedImage be=bi.getSubimage(0, 0,bi.getWidth(),bi.getHeight()*4/5);
return be;
}catch (IOException e) {
throw new RuntimeException(e);
} finally {
if(ous!=null) {
try {
ous.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* description: 将汉字转换成图片
* @param String
* @return BufferedImage
*/
public BufferedImage createImage(String str) throws Exception {
try {
//字符串加空格以达成居中的目的
int space=0;
//条码长度约为52个空格,汉子长度约为3个空格,根据汉字数计算空格数
str=" "+str;
// int width=500;
// int height=20;
// 创建图片
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_BGR);
Graphics g = image.getGraphics();
g.setClip(0, 0, width, height);
g.setColor(Color.white);
g.fillRect(0, 0, width, height);// 先用黑色填充整张图片,也就是背景
g.setColor(Color.black);// 在换成黑色
g.setFont(new Font("微软雅黑", Font.PLAIN, 16));// 设置画笔字体
/** 用于获得垂直居中y */
Rectangle clip = g.getClipBounds();
FontMetrics fm = g.getFontMetrics(new Font("微软雅黑", Font.PLAIN, 16));
int ascent = fm.getAscent();
int descent = fm.getDescent();
int y = (clip.height - (ascent + descent)) / 2 + ascent;
for (int i = 0; i < str.length(); i++) {// 256 340 0 680
g.drawString(str, i * 680, y);// 画出字符串
}
g.dispose();
return image;
}catch(Exception e) {
e.printStackTrace();
}
}
/**
* description: 拼接条码及汉字
*/
public BufferedImage mergeImage(BufferedImage image1,BufferedImage image2){
try {
BufferedImage finalImg=new BufferedImage(image1.getWidth(),image1.getHeight()+image2.getHeight(),image1.getType());
finalImg.createGraphics().drawImage(image1,0,0,null);
finalImg.createGraphics().drawImage(image2,0,image1.getHeight(),null);
return finalImg;
}catch(ServiceException e) {
e.printStackTrace();
}
}
/**
* description: 将图片发送至打印机打印
* @param BufferedImage
* @param String
* @param int
* @throws Exception
*/
public void sendImageToPrint(String msg) throws Exception {
BufferedImage imageIn= mergeImage(getBarCode(msg),createImageTwo(msg));
if (imageIn!=null) {
Connection printerConnection = null;
try {
printerConnection = (Connection) new TcpConnection("192.168.1.20", 6101);
printerConnection.open();
ZebraImageI image = ZebraImageFactory.getImage(imageIn);
//调整打印机标签位置,参数分别为打印图片信息,初始x坐标点,初始y坐标点,x轴长度,y轴长度
ZebraPrinterFactory.getInstance(printerConnection).printImage(image,0 ,0, 350, 110, false);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (printerConnection != null) {
printerConnection.close();
}
} catch (ConnectionException e) {
e.printStackTrace();
}
}
}
}
斑马打印机的SDK的文档:Overview (Zebra API for Android (build v2.11.2800))
生成指令文档的工具:ZebraDesigner 2 软件 : 支持与下载 | Zebra