Code128码打印---ZPL语言 By Sue

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

使用斑马打印机专门的打印命令ZPL语言进行VIN码打印
1. 斑马打印机驱动的设置
(1)使用的打印纸大概为------6.5cm*1.3cm
(2)设置Paper Size的大小为6.5cm*1.3cm-----使用的是用户自定义大小
(3)设置打印的浓度Printer Darkness 为10(默认为10)---可使用打印命令^MD16设置打印浓度
(4)设置Printer Actions 设置如下所示,具体作用不是很清楚
2.ZPL命令简单使用
(1)^XA 和^XZ 是开始和结束标记
(2)^MD30 设置色带颜色的深度取值范围从-30到30,30为最深颜色深度
(3)^LH 设置条码纸的边距
(4)^FO 设置条码左上角的位置
0,0 代表完全不留边距
(5)^ACN设置字体.
^ACN是设置字体的. 因为在条码下方会显示该条码的内容, 所以这里要设一下字体. 这个字体跟条码无关.
^Afo,h,w
(6)^BY是设置条码样式
^BY命令的格式:改变条码默认参数
^Byw,r,h
w 模块(窄条)宽开机初始化值:2点可接受的数值:1-10点
r 宽条与窄条的比例开机初始化值:3.0 可接受的数值:2.0到3.0,0.1的增量(对固定比例的条码无效)效)
h 条码高度开机初始化值:10点可接受的数值:1点到标签高度
(7)^BC是打印code128的指令
(8)^FD设置要打印的内容, ^FS表示换行.
(9)^XG命令用于调用一个或多个要进行打印的图形图像
(10)~DGd:o.x,t,w,data ~DG 命令用于下载以ASCII 十六进制表示的图形图像
(11)^FWr,z 用于为所有具有旋转方向的命令字段设置默认方向
(12)^TBa,b,c 用于打印具有定义的宽度和高度的文本块
(13)^FT 命令用于设置字段位置
(14)^FN 命令用于对数据字段进行编号
2.VIN(17位)条形码打印,中文打印---使用ZPL语言即命令来实现Zebra打印机打印条形码
(1)使用ZPL语言实现打印,下面是实现函数ZebraPrint
import java.io.File;
import java.io.FileInputStream;
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;
public class ZebraPrint {
byte[] dotfont;
String s_prt = "^XA,^MD16^FWN,2", s_prt_buffer="";
//^XA打印开始标志^MD打印浓度为30(-30~30) ^ABN,30,30设置字体大小
// 长,宽
//测试
public static void main(String[] args) {
try {
ZebraPrint a = new ZebraPrint();
a.setCommand("LNBMDLAA8CU000245");
printCN("发动机名称:QWFWEQFEFQFSFA", 100, 150,20,20,1);
printCN("发动机所属订单号:ASDFDSSAFADSF", 100, 180,20,20,1);
String str = a.getCommand();
System.out.println(str);
a.print(str );
} catch (Exception e) {
e.printStackTrace();
}
}
public ZebraPrint() throws Exception {
//加载24×24点阵字体库
//以流的形式下载文件,ts24.lib是指要下载文件的路径
File file = new File(System.getProperty("user.dir")+"\\src\\resources\\ts24.lib");
FileInputStream fis = new FileInputStream(file);
//创建一个刚刚好的缓冲区
//fis.available()获取关联的文件的字节数,文件体积不是很大可以这样操作
dotfont = new byte[fis.available()];
fis.read(dotfont);
fis.close();
}
public void setCommand(String barcode) {
printBarcode(barcode, 100, 40); //打印之后能够正确扫描
}
public void setCommand(String barcode,int x, int y,String fontType,int fontX,int fontY,int
thinBarcode,int times,int height) {
printBarcode(barcode,x,y,fontType,fontX,fontY,thinBarcode,times,height); //打印之后能够正确扫描
}
public String getCommand() {
return s_prt + s_prt_buffer+"^XZ";
//^XZ 打印结束
}
public void print(String str) throws PrintException {
PrintService psZebra = PrintServiceLookup.lookupDefaultPrintService();
if (psZebra == null) {
System.out.println("没有发现条码打印机.");
return;
}
DocPrintJob job = psZebra.createPrintJob();
byte[] by = str.getBytes();
DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
Doc doc = new SimpleDoc(by, flavor, null);
job.print(doc, null);
}
/**
* 打印条形码
* @param barcode 字符串
* @param xx x坐标
* @param yy y坐标
* @param fontX 字体高度单位:dots
* @param fontY 字体宽度
* @param thinBarcode 窄条宽度单位:dots 可接受的数值:1-10点
* @param times 宽条与窄条的比例可接受的数值:2到3.0,0.1的增量(对
固定比例的条码无效)
* @param height 高度可接受的数值:1点到标签高度
*
* 命令:
* ^FDa 参数a代表要打印的数据
^FO 设置条码位置
^FD设置要打印的内容, ^FS表示换行
^BY命令的格式:改变条码默认参数
^Byw,r,h
w 模块(窄条)宽开机初始化值:2点可接受的数值:1-10点
r 宽条与窄条的比例开机初始化值:3.0 可接受的数值:2.0到3.0,0.1的增量
(对固定比例的条码无效)
h 条码高度开机初始化值:10点可接受的数值:1点到标签高度
*/
protected void printBarcode(String barcode,int x, int y,String fontType,int fontX,int fontY,int thinBarcode,int times,int height) {
System.out.println(barcode);
s_prt_buffer += "^FO"+x+","+y+"^A"+fontType+"N,"+fontX+","+fontY
+"^BY"+thinBarcode+","+times+","+height+"^BCN,,Y,N^FD" + barcode + "^FS\n";
}
protected void printBarcode(String barcode,int x, int y) {
System.out.println(barcode);
// s_prt_buffer += "^BY3^FS^FO"+x+","+y+"^BEN,"+h+"^FD" + barcode + "\n";
s_prt_buffer += "^FO"+x+","+y+"^A5N,22,22^BY2,3,100^BCN,,Y,N,N^FD" + barcode + "^FS\n";//可以打印出条码和注释等宽
}
/**
* 打印英文字符,数字
* @param str
* @param x 距左顶角沿X轴的距离(原点)单位:dots
* @param y 距左顶角沿Y轴的距离(原点)单位:dots
* @param h 字体高度
* @param w 字体宽度
*/
protected void printChar(String str,int x, int y,int h,int w) {
System.out.println(str);
s_prt_buffer +="^FO"+x+","+y+"^A0,"+h+","+w+"^FD"+str+"^FS";
}
//字符旋转90度
protected void printCharR(String str,int x, int y,int h,int w) {
System.out.println(str);
s_prt_buffer +="^FO"+x+","+y+"^A0R,"+h+","+w+"^FD"+str+"^FS";
}
/**
* 打印中文字符串
* @param strCN
* @param x 距左顶角沿X轴的距离(原点)单位:dots
* @param y 距左顶角沿Y轴的距离(原点)单位:dots
* @param h 英文字符,数字字体高度
* @param w 英文字符,数字字体宽度
* @param b 图片放大系数接受的值:1 至10 默认值:1 (在这里即就是中文显示的大小)
*
^XG 调用图象
格式^XGd:o.x,mx,my
d---已存储图像的源设备
mx = x 轴的放大系数接受的值:1 至10 默认值:1
my = y 轴的放大系数接受的值:1 至10 默认值:1
~DG 命令用于下载以ASCII 十六进制表示的图形图像
格式~DGd:o.x,t,w,data
d = 存储图像的设备
t = 图形中的总字节数
w = 每行的字节
data = 定义图像的ASCII 十六进制字符串
一个汉字或符号在字库中的顺序号=94*(区码-1)+(位码-1)
机内码与区位码之间的变换关系:机内码高位字节=区码+160
机内码低位字节=位码+160
一个汉字字模在24点阵字库中的起始位置=
72×[(机内码高字节-176)×94 + (机内码低字节-161)] 汉字点阵数据存储位置偏移量offset =(94×(区码-1)+(位码-1))×72
*/
public void printCN(String strCN, int x, int y,int h,int w,int b) {
System.out.println(strCN);
byte[] ch = str2bytes(strCN);
for (int off = 0; off < ch.length;) {
if (((int) ch[off] & 0x00ff) >= 0xA0) {//ASCII码值"0xa0"表示汉字的开始
int qcode = ch[off] & 0xff;
int wcode = ch[off + 1] & 0xff;
s_prt_buffer = s_prt_buffer
+
String.format("^FO%d,%d^XG0000%01X%01X,%d,%d^FS\n", x,
y, qcode, wcode,b,b);
s_prt += String.format("~DG0000%02X%02X,00072,003,\n", qcode, wcode);
qcode = (qcode + 128 - 32) & 0x00ff;//区码:或qcode = (qcode - 128 - 32) & 0x00ff;(一般这样用)可达到减去0xA0的效果
wcode = (wcode + 128 - 32) & 0x00ff;//位码:或wcode = (wcode - 128 - 32) & 0x00ff;(一般这样用)可达到减去0xA0的效果
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;
s_prt += String.format("%02X%02X%02X\n", qcode, wcode,qcode1); //%02X --- 以十六进制显示,不足两位则补零
}
x = x + 25*b;
off = off + 2;//中文包含两个字节
} else if (((int) ch[off] & 0x00FF) < 0xA0) {
printChar(String.format("%c",ch[off]), x, y, h, w);
x = x + 15;
off++;//英文包含一个字节
}
}
}
byte[] str2bytes(String s) {
if (null == s || "".equals(s)) {
return null;
}
byte[] abytes = null;
try {
abytes = s.getBytes("gb2312");
} catch (UnsupportedEncodingException ex) {
}
return abytes;
}
}
(2)上面的s24.lib包(24*24点阵字体库)需要添加-----放在项目下(需要注意路径问题)
(3)下面的ZPL函数能够在6.5*1.3cm的纸张下打印出条形码长度与注释长度等宽
条形码和注释等宽:VIN码长度为17位
^XA,^MD16^FO100,40^A5N,30,33^BY4,3,150^BCN,,Y,N^FDLNBMDLAA1CR0238 37
^XZ
(4)不设置注释的字体和大小,可以居中打印出来,下面是具体的打印命令:
^XA,^MD16^FWN,2^FO100,40^BY2,3,100^BCN,,Y,N,N^FDLNBMDLAA8CU000245 ^FS
^XZ
Sue remarks:在调整条形码和注释等宽的时候,当字体类型和大小很难调整,达到要求时,可以考虑调整宽条与窄条的比例。

对于打印中文,需要注意:
(1)计算区位码
整个字库分94个区,每个区可存放94个汉字或字符,各汉字或符号所在的区即为区码,在区中的顺序号为位码,因此,通过区码和位码便可唯一的确定一个汉字或符号,计算公式为:一个汉字或符号在字库中的顺序号=94*(区码-1)+(位码-1)(1)
如果直接利用汉字的区位码作为编码存储,就会无法区分是汉字还是西文字符,为此,对区码作统一的变换后作为汉字的存储代码,即机内码。

机内码与区位码之间的变换关系如下:机内码高位字节=区码+160
机内码低位字节=位码+160(2)
对于16点阵字库,每个汉字字模使用32 B(16bit×16bit),再由式(1)和式(2)可知,一个汉字字模在16点阵字库中的起始位置可由式(3)求得:
32×[(机内码高字节-161)×94 + (机内码低字节-161)] (3)
由于汉字库前15个区主要用于存放各种非汉字符号,有些汉字系统为了不同的需要进行了裁减,对此就特别注意,应根据所选字库对式(3)进行适当修改。

同样,一个汉字字模在24点阵字库中的起始位置应为:
72×[(机内码高字节-176)×94 + (机内码低字节-161)] (4)
(2)计算汉字点阵数据存储位置偏移量
偏移量是指字模首字节距离文件头的相对位置。

其计算原理是:求出被检索汉字之前的汉字个数,再乘每个汉字所占的字节数。

1个n×n点阵字符所占字节数等于n×n÷8。

如16×16点阵占32 B,其便宜量offset计算式为:
offset =(94×(区码-1)+(位码-1))×32(5)
(3)移动文件指针读出点阵字模数据
打开点阵字库文件,将文件指针从文件头向后移动offset个字节,然后使用文件读取函数读出字模,如使用Windows API函数。

点阵字库存在分辨率低和不能放大两个致命的缺点。

其中,分辨率低导致不能反映字体形状细节,也就不能反映丰富多彩的字体,可以通过提高位图点数提高分辨率。

相较于其他字库,点阵字模原理简单使用非常容易,因此,载其在大型显示屏等户外电子装置显示汉字时得到广泛应用。

(4)关于如何计算汉字库中寻址某个汉字的点阵数据
接下来的问题就是如何在汉字库中寻址某个汉字的点阵数据了.要解决这个问题,首先需要了解汉字在计算机中是如何表示的.在计算机中英文可以使用 ASCII 码来表示,而汉字使用的是扩展 ASCII 码,并且使用两个扩展 ASCII 码来表示一个汉字.一个 ASCII 码使用一个字节表示,所谓扩展 ASCII 码,也就是 ASCII 码的最高位是1的 ASCII 码,简单的说就是码值大于等于 128 的 ASCII 码.一个汉字由两个扩展 ASCII 码组成,第一个扩展 ASCII 码用来存放区码,第二个扩展 ASCII 码用来存放位码.在 GB2312-80 标准中,将所有的汉字分为94个区,每个区有94个位可以存放94个汉字,形成了人们常说的区位码,这样总共就有94*94=8836 个汉字.在点阵字库中,汉字点阵数据就是按照这个区位的顺序来存放的,也就是最先存放的是第一个区的汉字点阵数据,在每一个区中有是按照位的顺序来存放的.在汉字的内码中,汉字区位码的存放实在扩展 ASCII 基础上存放的,并且将区码和位码都加上了32,然后存放在两个扩展 ASCII 码中.具体的说就是:
第一个扩展ASCII码 = 128+32 + 汉字区码
第二个扩展ASCII吗 = 128+32 + 汉字位码
如果用char hz[2]来表示一个汉字,那么我可以计算出这个汉字的区位码为:
区码 = hz[0] - 128 - 32 = hz[0] - 160
位码 = hz[1] - 128 - 32 = hz[1] - 160.
这样,我们可以根据区位码在文件中进行殉职了,寻址公式如下:
汉字点阵数据在字库文件中的偏移 = ((区码-1) * 94 + 位码) * 一个点阵字模占用的字节数
使用上面的程序打印中文“中华人民共和国”,形成的ZPL命令如下:
^XA~DG0000D6D0,00072,003,
001000
001C00
001800
001800
001800
101818
1FFFFC
181818
181818
181818
181818
181818
181818
1FFFF8
181818
101810
001800
001800
001800
001800
001800
001800
001800
001000
~DG0000BBAA,00072,003,
010400
01C700
018600
018620
030678
0386E0
070780
0F0604
1B0E04
333604
430604
0307FE
0303FC
021000
00180C
7FFFFE
001800
001800
001800
001800
001800
001800
001000
~DG0000C8CB,00072,003, 000000
001000
001C00
001800
001800
001800
003800
003800
003400
003400
006400
006200
00C200
00C300
018100
018180
0300C0
060060
040070
08003C
10001F
200008
400000
000000
~DG0000C3F1,00072,003, 000000
080060
0FFFF0
0C0060
0C0060
0C0060
0C0060
0FFFE0
0C1800
0C1810
0C1838
0FFFFC
0C1800
0C0C00
0C0C00
0C0604
0C0604
0C3304
0CC184
0F00E4
0E003C
1C001E
080004
~DG0000B9B2,00072,003, 010200
01C380
018300
018300
018300
018318
3FFFFC
018300
018300
018300
018300
018300
018308
01831C
3FFFFE
000000
008400
00E300
018180
0300E0
060070
180038
600010
000000
~DG0000BACD,00072,003, 000000
00E000
3F040C
0307FE
03060C
03060C
03360C
7FFE0C
03060C
07060C
07860C
07660C
0B360C
1B160C
13060C
33060C
2307FC
43060C
03060C
030408
030000
030000
020000
~DG0000B9FA,00072,003, 000000
200018
3FFFFC
300018
300018
300198
37FFD8
303018
303018
303018
303318
33FF98
303018
303618
303318
303218
3030D8
37FFD8
300018
300018
300018
300018
200010
^FO10,60^XG0000D6D0,10,10^FS
^FO260,60^XG0000BBAA,10,10^FS
^FO510,60^XG0000C8CB,10,10^FS
^FO760,60^XG0000C3F1,10,10^FS
^FO1010,60^XG0000B9B2,10,10^FS
^FO1260,60^XG0000BACD,10,10^FS
^FO1510,60^XG0000B9FA,10,10^FS
^XZ
修改时间:2013-3-15
由于新的需求,打印多行时,打印的长度(即y轴方向)只能打出二百多dots,尝试过分两条命令打印,但是条码和文字之间的间距过大,不可取。

查看ZPL的API,发现有一个设置标签长度的命令,命令格式:^LLy
直接使用该命令,没有作用,后来无意中发现,该命令只有在打印机模式为连续模式的情况下才有用。

相关文档
最新文档