热敏打印机ESC指令封装-SAAS本地化及未来之窗行业应用跨平台架构

news2024/9/22 13:34:57

一热敏打印机ESC指令

它包含了一系列的控制指令,通过这些指令可以实现对打印内容的格式设置,如字体大小、加粗、下划线、对齐方式等。还能够控制打印的位置、纸张进纸、切纸等操作。

例如,在商业零售场景中,收银小票打印机就是基于 ESC/POS 指令来打印出清晰、格式规范的交易小票。又比如,一些标签打印机也采用这一指令集,以便精确地打印出各种产品标签。

ESC/POS 的广泛应用,使得不同厂家生产的打印设备在一定程度上实现了指令的通用性,方便了开发者进行软件编程和控制

二、封装代码

package CyberWinPHP.Cyber_Plus;

import java.io.ByteArrayOutputStream;

import android.graphics.Bitmap;
import android.util.Log;

 

public class ESCUtil {

    public static final byte ESC = 0x1B;// Escape
    public static final byte FS =  0x1C;// Text delimiter
    public static final byte GS =  0x1D;// Group separator
    public static final byte DLE = 0x10;// data link escape
    public static final byte EOT = 0x04;// End of transmission
    public static final byte ENQ = 0x05;// Enquiry character
    public static final byte SP =  0x20;// Spaces
    public static final byte HT =  0x09;// Horizontal list
    public static final byte LF =  0x0A;//Print and wrap (horizontal orientation)
    public static final byte CR =  0x0D;// Home key
    public static final byte FF =  0x0C;// Carriage control (print and return to the standard mode (in page mode))
    public static final byte CAN = 0x18;// Canceled (cancel print data in page mode)

    //初始化打印机
    public static byte[] init_printer() {
        byte[] result = new byte[2];
        result[0] = ESC;
        result[1] = 0x40;
        return result;
    }

    //打印浓度指令
    public static byte[] setPrinterDarkness(int value){
        byte[] result = new byte[9];
        result[0] = GS;
        result[1] = 40;
        result[2] = 69;
        result[3] = 4;
        result[4] = 0;
        result[5] = 5;
        result[6] = 5;
        result[7] = (byte) (value >> 8);
        result[8] = (byte) value;
        return result;
    }

    /**
     * 打印单个二维码 sunmi自定义指令
     * @param code:         二维码数据
     * @param modulesize:   二维码块大小(单位:点, 取值 1 至 16 )
     * @param errorlevel:   二维码纠错等级(0 至 3)
     *                0 -- 纠错级别L ( 7%)
     *                1 -- 纠错级别M (15%)
     *                2 -- 纠错级别Q (25%)
     *                3 -- 纠错级别H (30%)
     */
    public static byte[] getPrintQRCode(String code, int modulesize, int errorlevel){
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        try{
            buffer.write(setQRCodeSize(modulesize));
            buffer.write(setQRCodeErrorLevel(errorlevel));
            buffer.write(getQCodeBytes(code));
            buffer.write(getBytesForPrintQRCode(true));
        }catch(Exception e){
            e.printStackTrace();
        }
        return buffer.toByteArray();
    }
    
    //
    /* 打开钱箱指令 */ 
    public static final byte[] cyber_ESC_OPEN_DRAWER = new byte[]{ESC, 'p', 0x00, 0x10, (byte) 0xff}; 

    /**
     * 横向两个二维码 sunmi自定义指令
     * @param code1:            二维码数据
     * @param code2:            二维码数据
     * @param modulesize:   二维码块大小(单位:点, 取值 1 至 16 )
     * @param errorlevel:   二维码纠错等级(0 至 3)
     *                0 -- 纠错级别L ( 7%)
     *                1 -- 纠错级别M (15%)
     *                2 -- 纠错级别Q (25%)
     *                3 -- 纠错级别H (30%)
     */
    public static byte[] getPrintDoubleQRCode(String code1, String code2, int modulesize, int errorlevel){
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        try{
            buffer.write(setQRCodeSize(modulesize));
            buffer.write(setQRCodeErrorLevel(errorlevel));
            buffer.write(getQCodeBytes(code1));
            buffer.write(getBytesForPrintQRCode(false));
            buffer.write(getQCodeBytes(code2));

            //加入横向间隔
            buffer.write(new byte[]{0x1B, 0x5C, 0x18, 0x00});

            buffer.write(getBytesForPrintQRCode(true));
        }catch(Exception e){
            e.printStackTrace();
        }
        return buffer.toByteArray();
    }

    /**
     * 光栅打印二维码
     */
    public static byte[] getPrintQRCode2(String data, int size){
        byte[] bytes1  = new byte[4];
        bytes1[0] = GS;
        bytes1[1] = 0x76;
        bytes1[2] = 0x30;
        bytes1[3] = 0x00;

        byte[] bytes2 = BytesUtil.getZXingQRCode(data, size);
        return BytesUtil.byteMerger(bytes1, bytes2);
    }

    /**
     * 打印一维条形码
     */
    public static byte[] getPrintBarCode(String data, int symbology, int height, int width, int textposition){
        if(symbology < 0 || symbology > 10){
            return new byte[]{LF};
        }

        if(width < 2 || width > 6){
            width = 2;
        }

        if(textposition <0 || textposition > 3){
            textposition = 0;
        }

        if(height < 1 || height>255){
            height = 162;
        }

        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        try{
            buffer.write(new byte[]{0x1D,0x66,0x01,0x1D,0x48,(byte)textposition,
                    0x1D,0x77,(byte)width,0x1D,0x68,(byte)height,0x0A});

            byte[] barcode;
            if(symbology == 10){
                barcode = BytesUtil.getBytesFromDecString(data);
            }else{
                barcode = data.getBytes("GB18030");
            }

            if(symbology > 7){
                buffer.write(new byte[]{0x1D,0x6B,0x49,(byte)(barcode.length+2),0x7B, (byte) (0x41+symbology-8)});
            }else{
                buffer.write(new byte[]{0x1D,0x6B,(byte)(symbology + 0x41),(byte)barcode.length});
            }
            buffer.write(barcode);
        }catch(Exception e){
            e.printStackTrace();
        }
        return buffer.toByteArray();
    }


    //光栅位图打印
    public static byte[] printBitmap(Bitmap bitmap){
        byte[] bytes1  = new byte[4];
        bytes1[0] = GS;
        bytes1[1] = 0x76;
        bytes1[2] = 0x30;
        bytes1[3] = 0x00;

        byte[] bytes2 = BytesUtil.getBytesFromBitMap(bitmap);
        return BytesUtil.byteMerger(bytes1, bytes2);
    }

    //光栅位图打印 设置mode
    public static byte[] printBitmap(Bitmap bitmap, int mode){
        byte[] bytes1  = new byte[4];
        bytes1[0] = GS;
        bytes1[1] = 0x76;
        bytes1[2] = 0x30;
        bytes1[3] = (byte) mode;

        byte[] bytes2 = BytesUtil.getBytesFromBitMap(bitmap);
        return BytesUtil.byteMerger(bytes1, bytes2);
    }

    //光栅位图打印
    public static byte[] printBitmap(byte[] bytes){
        byte[] bytes1  = new byte[4];
        bytes1[0] = GS;
        bytes1[1] = 0x76;
        bytes1[2] = 0x30;
        bytes1[3] = 0x00;

        return BytesUtil.byteMerger(bytes1, bytes);
    }


    /*
    *   选择位图指令 设置mode
    *   需要设置1B 33 00将行间距设为0
     */
    public static byte[] selectBitmap(Bitmap bitmap, int mode){
        return BytesUtil.byteMerger(BytesUtil.byteMerger(new byte[]{0x1B, 0x33, 0x00}, BytesUtil.getBytesFromBitMap(bitmap, mode)), new byte[]{0x0A, 0x1B, 0x32});
    }

    /**
     * 跳指定行数
     */
    public static byte[] nextLine(int lineNum) {
        byte[] result = new byte[lineNum];
        for (int i = 0; i < lineNum; i++) {
            result[i] = LF;
        }

        return result;
    }

    // ------------------------underline-----------------------------
    //设置下划线1点
    public static byte[] underlineWithOneDotWidthOn() {
        byte[] result = new byte[3];
        result[0] = ESC;
        result[1] = 45;
        result[2] = 1;
        return result;
    }

    //设置下划线2点
    public static byte[] underlineWithTwoDotWidthOn() {
        byte[] result = new byte[3];
        result[0] = ESC;
        result[1] = 45;
        result[2] = 2;
        return result;
    }

    //取消下划线
    public static byte[] underlineOff() {
        byte[] result = new byte[3];
        result[0] = ESC;
        result[1] = 45;
        result[2] = 0;
        return result;
    }

    // ------------------------bold-----------------------------
    /**
     * 字体加粗
     */
    public static byte[] boldOn() {
        byte[] result = new byte[3];
        result[0] = ESC;
        result[1] = 69;
        result[2] = 0xF;
        return result;
    }

    /**
     * 取消字体加粗
     */
    public static byte[] boldOff() {
        byte[] result = new byte[3];
        result[0] = ESC;
        result[1] = 69;
        result[2] = 0;
        return result;
    }

    // ------------------------character-----------------------------
    /*
    *单字节模式开启
     */
    public static byte[] singleByte(){
        byte[] result = new byte[2];
        result[0] = FS;
        result[1] = 0x2E;
        return result;
    }

    /*
    *单字节模式关闭
    */
    public static byte[] singleByteOff(){
        byte[] result = new byte[2];
        result[0] = FS;
        result[1] = 0x26;
        return result;
    }

    /**
     * 设置单字节字符集
     */
    public static byte[] setCodeSystemSingle(byte charset){
        byte[] result = new byte[3];
        result[0] = ESC;
        result[1] = 0x74;
        result[2] = charset;
        return result;
    }

    /**
     * 设置多字节字符集
     */
    public static byte[] setCodeSystem(byte charset){
        byte[] result = new byte[3];
        result[0] = FS;
        result[1] = 0x43;
        result[2] = charset;
        return result;
    }

    // ------------------------Align-----------------------------

    /**
     * 居左
     */
    public static byte[] alignLeft() {
        byte[] result = new byte[3];
        result[0] = ESC;
        result[1] = 97;
        result[2] = 0;
        return result;
    }

    /**
     * 居中对齐
     */
    public static byte[] alignCenter() {
        byte[] result = new byte[3];
        result[0] = ESC;
        result[1] = 97;
        result[2] = 1;
        return result;
    }

    /**
     * 居右
     */
    public static byte[] alignRight() {
        byte[] result = new byte[3];
        result[0] = ESC;
        result[1] = 97;
        result[2] = 2;
        return result;
    }

    //切刀
    public static byte[] cutter() {
        byte[] data = new byte[]{0x1d, 0x56, 0x01};
        return data;
    }

    //走纸到黑标
    public static byte[] gogogo(){
        byte[] data = new byte[]{0x1C, 0x28, 0x4C, 0x02, 0x00, 0x42, 0x31};
        return data;
    }


    
    //          private                /
    
    private static byte[] setQRCodeSize(int modulesize){
        //二维码块大小设置指令
        byte[] dtmp = new byte[8];
        dtmp[0] = GS;
        dtmp[1] = 0x28;
        dtmp[2] = 0x6B;
        dtmp[3] = 0x03;
        dtmp[4] = 0x00;
        dtmp[5] = 0x31;
        dtmp[6] = 0x43;
        dtmp[7] = (byte)modulesize;
        return dtmp;
    }

    private static byte[] setQRCodeErrorLevel(int errorlevel){
        //二维码纠错等级设置指令
        byte[] dtmp = new byte[8];
        dtmp[0] = GS;
        dtmp[1] = 0x28;
        dtmp[2] = 0x6B;
        dtmp[3] = 0x03;
        dtmp[4] = 0x00;
        dtmp[5] = 0x31;
        dtmp[6] = 0x45;
        dtmp[7] = (byte)(48+errorlevel);
        return dtmp;
    }


    private static byte[] getBytesForPrintQRCode(boolean single){
        //打印已存入数据的二维码
        byte[] dtmp;
        if(single){     //同一行只打印一个QRCode, 后面加换行
            dtmp = new byte[9];
            dtmp[8] = 0x0A;
        }else{
            dtmp = new byte[8];
        }
        dtmp[0] = 0x1D;
        dtmp[1] = 0x28;
        dtmp[2] = 0x6B;
        dtmp[3] = 0x03;
        dtmp[4] = 0x00;
        dtmp[5] = 0x31;
        dtmp[6] = 0x51;
        dtmp[7] = 0x30;
        return dtmp;
    }

    private static byte[] getQCodeBytes(String code) {
        //二维码存入指令
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        try {
            byte[] d = code.getBytes("GB18030");
            int len = d.length + 3;
            if (len > 7092) len = 7092;
            buffer.write((byte) 0x1D);
            buffer.write((byte) 0x28);
            buffer.write((byte) 0x6B);
            buffer.write((byte) len);
            buffer.write((byte) (len >> 8));
            buffer.write((byte) 0x31);
            buffer.write((byte) 0x50);
            buffer.write((byte) 0x30);
            for (int i = 0; i < d.length && i < len; i++) {
                buffer.write(d[i]);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return buffer.toByteArray();
    }


    /**
     * 设置字体大小
     */

    public static byte[] setTextSize(int size) {
        byte[] bytes = CMD_FontSize(size).getBytes();
        return bytes;
    }

    // 字体的大小
    // 0:正常大小 1:两倍高 2:两倍宽 3:两倍大小 4:三倍高 5:三倍宽 6:三倍大小
    // 7:四倍高 8:四倍宽 9:四倍大小 10:五倍高 11:五倍宽 12:五倍大小
    public static String CMD_FontSize(int nfontsize) {
        String _cmdstr = "";
        // 设置字体大小
        switch (nfontsize) {
            case -1:
                _cmdstr = new StringBuffer().append((char) 29).append((char) 33)
                        .append((char) 0).toString();// 29 33
                break;

            case 0:
                _cmdstr = new StringBuffer().append((char) 29).append((char) 33)
                        .append((char) 0).toString();// 29 33
                break;

            case 1:
                _cmdstr = new StringBuffer().append((char) 29).append((char) 33)
                        .append((char) 1).toString();
                break;

            case 2:
                _cmdstr = new StringBuffer().append((char) 29).append((char) 33)
                        .append((char) 16).toString();
                break;

            case 3:
                _cmdstr = new StringBuffer().append((char) 29).append((char) 33)
                        .append((char) 17).toString();
                break;

            case 4:
                _cmdstr = new StringBuffer().append((char) 29).append((char) 33)
                        .append((char) 2).toString();
                break;

            case 5:
                _cmdstr = new StringBuffer().append((char) 29).append((char) 33)
                        .append((char) 32).toString();
                break;

            case 6:
                _cmdstr = new StringBuffer().append((char) 29).append((char) 33)
                        .append((char) 34).toString();
                break;

            case 7:
                _cmdstr = new StringBuffer().append((char) 29).append((char) 33)
                        .append((char) 3).toString();
                break;

            case 8:
                _cmdstr = new StringBuffer().append((char) 29).append((char) 33)
                        .append((char) 48).toString();
                break;

            case 9:
                _cmdstr = new StringBuffer().append((char) 29).append((char) 33)
                        .append((char) 51).toString();
                break;

            case 10:
                _cmdstr = new StringBuffer().append((char) 29).append((char) 33)
                        .append((char) 4).toString();
                break;

            case 11:
                _cmdstr = new StringBuffer().append((char) 29).append((char) 33)
                        .append((char) 64).toString();
                break;

            case 12:
                _cmdstr = new StringBuffer().append((char) 29).append((char) 33)
                        .append((char) 68).toString();
                break;

        }
        Log.d("textSize",_cmdstr);
        return _cmdstr;
    }
}

三、阿雪技术观

拥抱开源与共享,见证科技进步奇迹,畅享人类幸福时光!

让我们积极投身于技术共享的浪潮中,不仅仅是作为受益者,更要成为贡献者。无论是分享自己的代码、撰写技术博客,还是参与开源项目的维护和改进,每一个小小的举动都可能成为推动技术进步的巨大力量

扫码,可学习更多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2043295.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

刷到好听的音频怎么办

在短视频平台上&#xff0c;我们常常会刷到那些好听得让人陶醉的视频&#xff0c;可却无法直接下载保存其中的音频&#xff0c;是不是感觉很遗憾&#xff1f; 比如刷到林俊杰这首前奏超好听的《江南》&#xff0c;却禁止下载无法直接下载保存。 别担心&#xff0c;下面就为您揭…

html页面缩放自适应

html页面缩放自适应 一、为什么页面要进行缩放自适应 在我们一般web端进行页面拼接完成后&#xff0c;在web端的显示正常&#xff08;毕竟我们是按照web端进行页面拼接完成的&#xff09;&#xff0c;那么要是用其他设备打开呢&#xff0c;比如手机或者平板&#xff0c;这时候…

聚鼎科技:新手做装饰画生意卖什么比较好

在艺术的广阔天地里&#xff0c;装饰画以其独特的魅力逐渐成为室内装饰不可或缺的元素。对于刚入行的新手而言&#xff0c;选择合适的装饰画产品至关重要&#xff0c;它关系到业务的成功与否。以下是一些关于新手做装饰画生意卖什么比较好的建议。 考虑到市场需求的多样性&…

宝兰德荣获openEuler项目群青铜捐赠人称号,共筑开源生态繁荣新篇章

近日&#xff0c;开放原子开源基金会正式公布了新增捐赠人名单&#xff0c;宝兰德凭借在开源领域的卓越贡献与深厚实力&#xff0c;被授予openEuler项目群青铜捐赠人称号。 开放原子开源基金会是致力于推动全球开源事业发展的非营利机构&#xff0c;于2020年6月在北京成立。开放…

Vue3+Vite项目从零搭建+安装依赖+配置按需导入

环境准备 Vscode/HBuilder等任何一种前端开发工具node.js&npm本地开发环境 源代码管理&#xff1a;Git 技术栈 项目构建 创建项目 npm create vite依次运行最后三行出现&#xff0c;成功启动项目在浏览器输入 http://localhost:5173/ 可以显示页面 src别名的配置 在…

xcode14.2学习笔记 swift5开发macos网络程序笔记

1. .frame(width: 200.0, height: 200.0) 控制默认窗体大小 2.去除Metal API Validation提示 Product->Scheme > Edit Scheme... > Run > Diagnostics > Metal API Validation. 3.本地安装git依赖资源&#xff08;可能有的时候并不好用&#xff0c;显示不出自…

星露谷模组开发教程#6 烹饪和制造配方

首发于Enaium的个人博客 在上篇文章中我们添加了一个新的食物&#xff0c;但是这个食物并没有配方&#xff0c;所以我们今天来添加一个配方。 烹饪配方 我们在Data/CookingRecipes.json中可以看到所有的食物配方&#xff0c;所以我们需要修改这个配置文件来添加我们的食物配方…

基于Vue2使用x2js将JSON转换成XML、将XML转换成JSON

x2js源码地址GitHub - abdolence/x2js: x2js - XML to JSON and back for JavaScriptx2js - XML to JSON and back for JavaScript. Contribute to abdolence/x2js development by creating an account on GitHub.https://github.com/abdolence/x2js import x2js from x2js;//…

go语言后端开发学习(四) —— 在go项目中使用Zap日志库

一.前言 在之前的文章中我们已经介绍过如何使用logrus包来作为我们在gin框架中使用的日志中间件&#xff0c;而今天我们要介绍的就是我们如何在go项目中如何集成Zap来作为日志中间件 二.Zap的安装与快速使用 和安装其他第三方包没什么区别&#xff0c;我们下载Zap包只需要执…

Github Actions自动发布release

目录 说明正文1.设置仓库密钥2.打开仓库权限3.配置自动化文件4.写在最后 说明 GitHub Actions 是 GitHub 的持续集成服务&#xff0c;于2018年10月推出。通过Github Actions可以实现诸多自动化功能&#xff0c;比如自动打包&#xff0c;自动发布Release等等。除此之外&#xf…

实验10-3 递归计算Ackermenn函数

本题要求实现Ackermenn函数的计算&#xff0c;其函数定义如下&#xff1a; 函数接口定义&#xff1a; int Ack( int m, int n ); 其中m和n是用户传入的非负整数。函数Ack返回Ackermenn函数的相应值。题目保证输入输出都在长整型范围内。 输入样例&#xff1a; 2 3输出样例&am…

8 个最佳 Java IDE 和文本编辑器

从 2024 年使用的最佳 Java IDE 和代码编辑器中进行选择&#xff0c;并提高您的 Java 生产力。 Java 是世界上最流行的编程语言之一&#xff0c;于 1995 年首次推出&#xff0c;它确实践行了“编写一个&#xff0c;随处运行”的座右铭。该语言用途广泛&#xff0c;可用于构建从…

浅谈物理集中式数据中台架构在数据开发中的不足

在传统数据开发和生产领域&#xff0c;企业面临的问题主要源于数据规模的急剧增长&#xff0c;多源异构数据的不断扩张&#xff0c;以及数据消费端看数、用数的人员越来越多。初期&#xff0c;数据仓库的主要功能聚焦于支持经营仪表盘的视图构建&#xff0c;旨在为企业提供直观…

ubuntu:最新安装使用docker

前言 系统&#xff1a;ubuntu 22.04 desktop 目的&#xff1a;安装使用docker 安装小猫猫 没有安装包的&#xff0c;可以自己去瞅瞅&#xff0c;这里不提供下载方式 sudo dpkg -i ./cat-verge_1.7.5_amd64.deb 在应用里&#xff0c;打开这个软件&#xff0c;并开启系统猫猫 配…

单元训练08:外部中断的基本操作

蓝桥杯 小蜜蜂 单元训练08&#xff1a;外部中断的基本操作 #include "stc15f2k60s2.h"#define LED(x) \{ \P0 x; \P2 P2 & 0x1f | 0x80; \P2 & 0x1f; \}#define L1 0xFE; // 定义L1亮…

SpringBoot集成MyBatis和FlyWay

一、什么是FlyWay 一个开源的数据库迁移工具&#xff0c;用于管理和执行数据库结构的版本变更。通俗来说&#xff0c;它帮助开发者跟踪和应用数据库中的更改&#xff0c;比如表的创建、列的修改等。主要的功能为&#xff1a; 数据库版本控制&#xff1a; Flyway 使用一组迁移…

硬件I2C和软件I2C(模拟I2C)的区别

硬件I2C和软件I2C是两种不同的实现I2C&#xff08;Inter-Integrated Circuit&#xff0c;集成电路间&#xff09;通信协议的方式&#xff0c;它们在实现方式、性能特点以及应用场景上存在显著差异。 一、实现方式 硬件I2C&#xff1a;通过专门的硬件电路实现&#xff0c;这些…

泛交通领域的可视化大屏作品欣赏,各个都相当惊艳。

各位新老朋友大家好&#xff0c;本次给大家带来泛交通领域的可视化大屏&#xff0c;供大家鉴赏。 泛交通领域是指综合利用各种交通方式和资源&#xff0c;提供全方位、多元化的出行选择和服务的交通体系。 它包括以下几个方面&#xff1a; 1. 公共交通&#xff1a;包括地铁、…

花钱买不到系列之—linux系统调用

关于系统调用是什么&#xff0c;为什么用系统调用? 也是通过生活的例子来说明白。 我们生活中有一种东西叫银行&#xff0c;银行是不是有存钱的仓库对不对&#xff1f;好银行有存钱的仓库&#xff0c;银行有桌椅板凳啊&#xff0c;银行还有电脑&#xff0c;设备啊&#xff0c;…

文华财经期货DK多空提示指标源码

N1:40; A:(COHL)/4; AA0:MA(A,N1),LINETHICK3;//中 MA1:MA(CLOSE,5), NODRAW; MA2:MA(CLOSE,10), NODRAW; MA3:MA(C,60), NODRAW,LINETHICK1; 转折线:MA3, NODRAW,COLORCYAN; 顺势线:MA(CLOSE,10), NODRAW; MA20:MA(C,20), NODRAW; MA30:MA(C,30), NODRAW; ZD:MA3>…