Android sockot连接打印机EPSON ESCPOS指令打印

    xiaoxiao2022-07-12  170

    sockot连接打印机EPSON ESC/POS指令打印

    接了一个需求,需要用Android pad连接打印机进行打印,以前倒是没接触过,这次在网上找了下资料,简单实现了下需求。 在这记录下相关代码以及踩的坑 首先第一步就是通过socket连接打印机再通过socket发送打印指令就行

    代码步骤都比较简单,先看下代码

    public class EscPos { public static final byte FS = 0x1C; public static final byte HT = 0x9; public static final byte LF = 0x0A; public static final byte CR = 0x0D; public static final byte ESC = 0x1B; public static final byte DLE = 0x10; public static final byte GS = 0x1D; public static final byte STX = 0x02; public static final byte US = 0x1F; public static final byte CAN = 0x18; public static final byte CLR = 0x0C; public static final byte EOT = 0x04; /* 初始化打印机 */ public static final byte[] ESC_INIT = new byte[]{ESC, '@'}; /* 设置标准模式 */ public static final byte[] ESC_STANDARD = new byte[]{ESC, 'S'}; /* 设置汉字打印模式 */ public static final byte[] ESC_CN_FONT = new byte[]{FS, '&'}; /* 选择字符集 */ public static final byte[] ESC_SELECT_CHARACTER = new byte[]{ESC, 'R', 9}; /* 设置用户自定义汉字字体 焗7118 */ public static final byte[] ESC_FS_2 = new byte[]{FS, 0x32, 0x71, 0x18}; /* 取消用户自定义字体 */ public static final byte[] ESC_CANCEL_DEFINE_FONT = new byte[]{ESC, '%', 0}; /* 打开钱箱指令 */ public static final byte[] ESC_OPEN_DRAWER = new byte[]{ESC, 'p', 0x00, 0x10, (byte) 0xff}; /* 切纸指令GS V m * m 0,48 Executes a full cut(cuts the paper completely) * 1,49 Excutes a partilal cut(one point left uncut) */ public static final byte[] POS_CUT_MODE_FULL = new byte[]{GS, 'V', 0x00}; public static final byte[] POS_CUT_MODE_PARTIAL = new byte[]{GS, 'V', 0x01}; /* 西文字符 (半宽)字体A (6 ×12),汉字字符 (全宽)字体A (12×12) */ public static final byte[] ESC_FONT_A = new byte[]{ESC, '!', 0}; /* 西文字符 (半宽)字体B (8×16),汉字字符 (全宽)字体B (16×16) */ public static final byte[] ESC_FONT_B = new byte[]{ESC, '!', 1}; /* 12*24 0/48*/ public static final byte[] ESC_FONTA = new byte[]{ESC, 'M', 48}; /* 9*17 1/49*/ public static final byte[] ESC_FONTB = new byte[]{ESC, 'M', 1}; /* 默认颜色字体指令 */ public static final byte[] ESC_FONT_COLOR_DEFAULT = new byte[]{ESC, 'r', 0x00}; /* 红色字体指令 */ public static final byte[] ESC_FONT_COLOR_RED = new byte[]{ESC, 'r', 0x01}; /* 标准大小 */ public static final byte[] FS_FONT_ALIGN = new byte[]{FS, 0x21, 1, ESC, 0x21, 1}; /* 横向放大一倍 */ public static final byte[] FS_FONT_ALIGN_DOUBLE = new byte[]{FS, 0x21, 4, ESC, 0x21, 4}; /* 纵向放大一倍 */ public static final byte[] FS_FONT_VERTICAL_DOUBLE = new byte[]{FS, 0x21, 8, ESC, 0x21, 8, GS, '!', 0x01}; /* 横向纵向都放大一倍 */ public static final byte[] FS_FONT_DOUBLE = new byte[]{FS, 0x21, 12, ESC, 0x21, 48}; /* 靠左打印命令 */ public static final byte[] ESC_ALIGN_LEFT = new byte[]{0x1b, 'a', 0x00}; /* 居中打印命令 */ public static final byte[] ESC_ALIGN_CENTER = new byte[]{0x1b, 'a', 0x01}; /* 靠右打印命令 */ public static final byte[] ESC_ALIGN_RIGHT = new byte[]{0x1b, 'a', 0x02}; /* 字体加粗 */ public static final byte[] ESC_SETTING_BOLD = new byte[]{ESC, 0x45, 1}; /* 取消字体加粗 */ public static final byte[] ESC_CANCEL_BOLD = new byte[]{ESC, 0x45, 0}; public static final int STATE_1 = 1;// 创建Socket连接 public static final int STATE_2 = 2;// 获取输出流 public static final int STATE_3 = 3;// 关闭Socket public static final int STATE_0 = 0;// 成功 public static final int ERROR_2 = -2;// 创建Socket失败 public static final int ERROR_3 = -3;// 获取输出流失败 public static final int ERROR_4 = -4;// 关闭Socket出错 public static final int ERROR_100 = -100;// 失败 // 通过socket流进行读写 private OutputStream socketOut = null; // 以ip作为key,EscPos实例作为value的Map private static Map<String, EscPos> posMap = new HashMap<String, EscPos>(); private static EscPos escPos = null; // 默认端口 public static int DEFAULT_PORT = 9100; private Socket socket; private OnPrinterListener listener; private String ip; private int port; /** * 根据ip、端口、字符编码构造工具类实例 * * @param ip 打印机ip * @param port 打印机端口,默认9100 * @throws IOException */ public EscPos(String ip, int port) { this.ip = ip; this.port = port; } public synchronized static EscPos getInstance(String ip, Integer port) { escPos = posMap.get(ip); if (escPos == null) { escPos = new EscPos(ip, port); } return escPos; } public static synchronized EscPos getInstance(String ip) { return getInstance(ip, DEFAULT_PORT); } public static synchronized EscPos getInstance() { //这儿写死或者传入打印机地址和端口 return getInstance("", ""; } public static void myPrinter(final List<String> list, final OnPrinterListener printerListener) { Runnable runnable = new Runnable() { @Override public void run() { EscPos escPos = EscPos.getInstance(); escPos.setListener(printerListener); escPos.connectSocket(); try { escPos.init(); for (int i = 0; i < list.size(); i++) { escPos.line(1); escPos.boldOff(true); escPos.printStr(list.get(i)); //escPos.printStr("测试字体6"); } escPos.line(10); escPos.feedAndCut(); escPos.closeIOAndSocket(); printerListener.onListener(STATE_0); } catch (IOException e) { printerListener.onError(ERROR_100); LOGGER.error("Socket printer write ===> ", e); e.printStackTrace(); } } }; new Thread(runnable).start(); } public void connectSocket() { try { socket = new Socket(); SocketAddress socAddress = new InetSocketAddress(ip, port); socket.connect(socAddress, 5000); if (listener != null) { listener.onListener(STATE_1); } try { socketOut = socket.getOutputStream(); if (listener != null) { listener.onListener(STATE_2); } } catch (IOException e) { if (listener != null) { listener.onError(ERROR_3); } LOGGER.error("Socket printer getOutputStream ===> ", e); e.printStackTrace(); } } catch (IOException e) { if (listener != null) { listener.onError(ERROR_2); } LOGGER.error("Socket printer connect ===> ", e); e.printStackTrace(); } } /** * 换行 * * @param lineNum 换行数,0为不换行 * @return * @throws IOException */ public EscPos line(int lineNum) throws IOException { for (int i = 0; i < lineNum; i++) { socketOut.write("\n".getBytes()); socketOut.flush(); } return this; } /** * 加粗 * * @param flag false为不加粗 * @return * @throws IOException */ public EscPos bold(boolean flag) throws IOException { if (flag) { socketOut.write(ESC_SETTING_BOLD); } return this; } /** * 取消粗体 * * @param flag true为取消粗体模式 * @return * @throws IOException */ public EscPos boldOff(boolean flag) throws IOException { if (flag) { socketOut.write(ESC_CANCEL_BOLD); //socketOut.write(FS_FONT_DOUBLE); } return this; } /** * 初始化打印机 * * @return * @throws IOException */ EscPos init() throws IOException { socketOut.write(ESC_INIT); return this; } /** * 打印空白 * * @param length 需要打印空白的长度 * @throws IOException */ private void printSpace(int length) throws IOException { for (int i = 0; i < length; i++) { socketOut.write(" ".getBytes()); } socketOut.flush(); } /** * 进纸并全部切割 * * @return * @throws IOException */ public EscPos feedAndCut() throws IOException { socketOut.write(POS_CUT_MODE_FULL); socketOut.flush(); return this; } public void closeIOAndSocket() { try { socketOut.close(); socket.close(); if (listener != null) { listener.onListener(STATE_3); } } catch (IOException e) { if (listener != null) { listener.onError(ERROR_4); } LOGGER.error("Socket printer close ===> ", e); e.printStackTrace(); } } /** * 打印字符串 * * @param str 所需打印字符串 * @return * @throws IOException */ public EscPos printStr(String str) throws IOException { socketOut.write(ESC_CN_FONT); socketOut.write(str.getBytes(Charset.forName("GBK"))); socketOut.write(LF); socketOut.flush(); return this; } public void setListener(OnPrinterListener listener) { this.listener = listener; } public interface OnPrinterListener { void onListener(int status); void onError(int errorCode); } }

    打印调用示例代码

    //printerData 是list<string>类型的数据 循环打印文案 EscPos.myPrinter(printerData, new EscPos.OnPrinterListener() { @Override public void onListener(int status) { } @Override public void onError(final int errorCode) { ((Activity) context).runOnUiThread(new Runnable() { @Override public void run() { //此时已在主线程中,可以更新UI了 if (errorCode == EscPos.ERROR_2) { Toast.makeText(context, "连接打印机失败", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, "打印异常", Toast.LENGTH_SHORT).show(); } } }); } });

    过程遇到的坑

    socket连不上打印机 1.确保打印机的网和手机在同一个网段内 2.打印机端口和地址正确(可百度查询如何确定打印机IP和端口)

    socket发送打印指令不起作用 这个当时坑死我了,我用一个串测试“hello word” ,结果就因为中间多加了空格,就是打印不出来,后来才知道,这种空格没法打印,一定要写个简单的串先测试。

    最新回复(0)