思普瑞特,小票打印机和标签打印机java网络驱动设计与实现

3,085 阅读3分钟

网络打印走的socket连接,主流的java, php, c, c#等语言都支持socket,所以实现打印机的网络打印几乎是和语言无关的

打印机默认端口是9100 使用socket连接上打印机后,将打印内容按照打印机的指令进行编码后调用send就可以打印了

协议文档

小票打印机和标签打印机走的协议不同,所以各自都有一个协议,小票打印机使用的是esc协议,标签打印机使用的是tsc/tspl协议

小票打印机esc协议文档:

  1. sprinter.com.cn/img/up/data…
  2. blog.csdn.net/feng88724/a…
  3. www.sprt.cc/img/up/data…

标签打印机tsc/tspl协议文档:

  1. sprinter.com.cn/img/up/data…

可以看到打印机支持的指令非常多,下面找到常用的指令实现我们的打印目的

小票打印机

小票打印机已经有java驱动了,参考:github.com/SubLuLu/the… 小票打印机指令使用10进制表示了,所以难以阅读,指令对应的意思请对照文档 核心代码如下

连接打印机

public NetEscPos(String ip, int port, String encoding) throws IOException {
    Socket socket = new Socket(ip, port);
    socketOut = socket.getOutputStream();
    socket.isClosed();
    NetEscPos.encoding = encoding;
    writer = new OutputStreamWriter(socketOut, encoding);
}

发送命令,比如发送切纸命令

private NetEscPos feedAndCut() throws IOException {
    writer.write(0x1D);
    writer.write(86);
    writer.write(65);
    writer.write(0);
    writer.flush();
    return this;
}

对应的文档为

查看打印效果

IMG_54061

标签打印机

参考实现:github.com/fintrace/ts… 核心指令如下

SIZE 40 mm, 30 mm
SPEED 5
DENSITY 7
DIRECTION 1
REFERENCE 0,0
OFFSET 0 mm
SHIFT 0
CLS
TEXT 20,60,"TSS24.BF2",0,2,2,"堂食   0001"
TEXT 20,120,"TSS24.BF2",0,1,1,"2019-03-22 10:05:51"
TEXT 20,150,"TSS24.BF2",0,1,1,"大鸡腿(1/3)"
TEXT 20,180,"TSS24.BF2",0,1,1,"加冰 标签备注"
PRINT 1

查看打印效果:

IMG_00401

对应的指令可以参考文档,比如第一行设置标签纸宽度和长度的SIZE指令

一些注意的点

可以使用redis的阻塞队列实现获取是否打印成功的状态,参考:基于List的 LPUSH+BRPOP 的实现

字符集需要设置成 gb2312

使用点阵图可以打印更清晰的图片 java参考:EscPos.java#L501 c#参考:blog.csdn.net/xiaoxian802… 核心代码如下

// 每行进行打印
for (int i = 0; i < bufImage.getHeight() / 24 + 1; i++) {
    write(escBmp);

    for (int j = 0; j < bufImage.getWidth(); j++) {
        for (int k = 0; k < 24; k++) {
            if (((i * 24) + k) < bufImage.getHeight()) {
                pixelColor = bufImage.getRGB(j, (i * 24) + k);
                if (pixelColor != -1) {
                    data[k / 8] += (byte) (128 >> (k % 8));
                }
            }
        }

        write(data);
        // 重置参数
        data[0] = (byte) 0x00;
        data[1] = (byte) 0x00;
        data[2] = (byte) 0x00;
    }
    //换行
    byte[] byteSend1 = new byte[2];
    byteSend1[0] = 0x0d;
    byteSend1[1] = 0x0a;
    write(byteSend1);
}

c#版如下

// data
for (int i = 0; i < (bmp.Height / 24) + 1; i++)
{
    socket.Send(escBmp, escBmp.Length, 0);
 
    for (int j = 0; j < bmp.Width; j++)
    {
        for (int k = 0; k < 24; k++)
        {
            if (((i * 24) + k) < bmp.Height)   // if within the BMP size
            {
                pixelColor = bmp.GetPixel(j, (i * 24) + k);
                if (pixelColor.R == 0)
                {
                    data[k / 8] += (byte)(128 >> (k % 8));
                }
            }
        }
 
        socket.Send(data, 3, 0);
        data[0] = (byte)'\x00';
        data[1] = (byte)'\x00';
        data[2] = (byte)'\x00';    // Clear to Zero.
    }
    
    byte_send = Encoding.GetEncoding("gb18030").GetBytes("\n");
 
    //发送测试信息
    socket.Send(byte_send, byte_send.Length, 0);
} // data

如果在编写驱动过程中遇到问题,可加作者微信探讨

wx