美文网首页
AndroidPrinter

AndroidPrinter

作者: CarlosLynn | 来源:发表于2019-06-18 17:36 被阅读0次

    AndroidPrinter

    ESC-POS命令打印辅助库

    感谢源码地址:ProjectX

    介绍

    标准ESC-POS命令打印,固定IP或蓝牙打印,支持黑白图片打印。
    其中PrintCommands类列出了基本所有的ESC-POS打印命令。
    打印指令参考自Commande ESCPOS.pdf文档。

    截图

    <img src="screenshot.png" alt="Screenshots"/><img src="printer_example.jpg" alt="xample"/>

    先决条件

    • minSdkVersion 5
    • <uses-permission android:name="android.permission.INTERNET" />
    • <uses-permission android:name="android.permission.BLUETOOTH" />

    入门

    引用:

    dependencies {
        ...
       compile 'com.zxn.printer:android-printer:1.0.0'
        ...
    }
    

    添加权限:

    添加蓝牙权限
    <uses-permission android:name="android.permission.BLUETOOTH" />
    网络请求权限
    <uses-permission android:name="android.permission.INTERNET" />

    实现接口:

    实现PrintDataMaker接口,完成具体打印任务:

    public class TestPrintDataMaker implements PrintDataMaker {
    
        private Context context;
        private String qr;
        private int width;
        private int height;
    
        public TestPrintDataMaker(Context context, String qr, int width, int height) {
            this.context = context;
            this.qr = qr;
            this.width = width;
            this.height = height;
        }
    
        @Override
        public List<byte[]> getPrintData(int type) {
            ArrayList<byte[]> data = new ArrayList<>();
            try {
                PrinterWriter printer;
                printer = type == PrinterWriter58mm.TYPE_58 ? new PrinterWriter58mm(height, width) : new PrinterWriter80mm(height, width);
                printer.setAlignCenter();
                data.add(printer.getDataAndReset());
    
                ArrayList<byte[]> image1 = printer.getImageByte(context.getResources(), R.drawable.ic_printer_logo);
                data.addAll(image1);
    
                printer.setAlignLeft();
                printer.printLine();
                printer.printLineFeed();
    
                printer.printLineFeed();
                printer.setAlignCenter();
                printer.setEmphasizedOn();
                printer.setFontSize(1);
                printer.print("我的餐厅");
                printer.printLineFeed();
                printer.setFontSize(0);
                printer.setEmphasizedOff();
                printer.printLineFeed();
    
                printer.print("最时尚的明星餐厅");
                printer.printLineFeed();
                printer.print("客服电话:400-8008800");
                printer.printLineFeed();
    
                printer.setAlignLeft();
                printer.printLineFeed();
    
                printer.print("订单号:88888888888888888");
                printer.printLineFeed();
    
                printer.print("预计送达:" +
                        new SimpleDateFormat("yyyy/MM/dd HH:mm", Locale.getDefault())
                                .format(new Date(System.currentTimeMillis())));
                printer.printLineFeed();
    
                printer.setEmphasizedOn();
                printer.print("#8(已付款)");
                printer.printLineFeed();
                printer.print("××区××路×××大厦××楼×××室");
                printer.printLineFeed();
                printer.setEmphasizedOff();
                printer.print("13843211234");
                printer.print("(张某某)");
                printer.printLineFeed();
                printer.print("备注:多加点辣椒,多加点香菜,多加点酸萝卜,多送点一次性手套");
                printer.printLineFeed();
    
                printer.printLine();
                printer.printLineFeed();
    
                printer.printInOneLine("星级美食(豪华套餐)×1", "¥88.88", 0);
                printer.printLineFeed();
                printer.printInOneLine("星级美食(限量套餐)×1", "¥888.88", 0);
                printer.printLineFeed();
                printer.printInOneLine("餐具×1", "¥0.00", 0);
                printer.printLineFeed();
                printer.printInOneLine("配送费", "免费", 0);
                printer.printLineFeed();
    
                printer.printLine();
                printer.printLineFeed();
    
                printer.setAlignRight();
                printer.print("合计:977.76");
                printer.printLineFeed();
                printer.printLineFeed();
    
                printer.setAlignCenter();
    
                data.add(printer.getDataAndReset());
    
                String bitmapPath = FileUtils.getExternalFilesDir(context, "Temp") + "tmp_qr.jpg";
                if (QRCodeUtil.createQRImage(qr, 380, 380, null, bitmapPath)) {
                    ArrayList<byte[]> image2 = printer.getImageByte(bitmapPath);
                    data.addAll(image2);
                } else {
                    ArrayList<byte[]> image2 = printer
                            .getImageByte(context.getResources(), R.drawable.ic_printer_qr);
                    data.addAll(image2);
                }
    
                printer.printLineFeed();
                printer.print("扫一扫,查看详情");
                printer.printLineFeed();
                printer.printLineFeed();
                printer.printLineFeed();
                printer.printLineFeed();
                printer.printLineFeed();
    
                printer.feedPaperCutPartial();
    
                data.add(printer.getDataAndClose());
                return data;
            } catch (Exception e) {
                return new ArrayList<>();
            }
        }
    }
    

    准备打印:

    创建打印执行者:

    PrintExecutor executor = new PrintExecutor(String ip, int port, int type);
    PrintExecutor executor = new PrintExecutor(BluetoothDevice device, int type);
    

    设置执行者状态监听(非必须):

    executor.setOnStateChangedListener(new PrintSocketHolder.OnStateChangedListener() {
        @Override
        public void onStateChanged(int state) {
            switch (state) {
                case PrintSocketHolder.STATE_0:
                    //生成打印页面数据...
                    break;
                case PrintSocketHolder.STATE_1:
                    //生成数据成功,开始创建Socket连接...
                    break;
                case PrintSocketHolder.STATE_2:
                    //创建Socket成功,开始获取输出流...
                    break;
                case PrintSocketHolder.STATE_3:
                    //获取输出流成功,开始写入打印页面数据...
                    break;
                case PrintSocketHolder.STATE_4:
                    //写入打印页面数据成功,正在完成打印...
                    break;
            }
        }
    });
    

    设置执行者回调监听(非必须):

    executor.setOnPrintResultListener(new PrintExecutor.OnPrintResultListener() {
        @Override
        public void onResult(int errorCode) {
            switch (errorCode) {
                case PrintSocketHolder.ERROR_0:
                    //打印成功完成!
                    break;
                case PrintSocketHolder.ERROR_1:
                    //生成打印页面数据失败!
                    break;
                case PrintSocketHolder.ERROR_2:
                    //创建Socket失败!
                    break;
                case PrintSocketHolder.ERROR_3:
                    //获取输出流失败!
                    break;
                case PrintSocketHolder.ERROR_4:
                    //写入打印页面数据失败!
                    break;
                case PrintSocketHolder.ERROR_5:
                    //必要的参数不能为空!
                    break;
                case PrintSocketHolder.ERROR_6:
                    //关闭Socket出错
                    break;
                case PrintSocketHolder.ERROR_100:
                    //打印失败
                    break;
            }
        }
    });
    

    执行打印:

    int result = executor.doPrinterRequest(PrintDataMaker maker);//同步
    executor.doPrinterRequestAsync(PrintDataMaker maker);//异步
    

    自定义

    如果你要实现自己的打印机PrinterWriter,那么你需要继承PrinterWriter,并实现其
    必须的方法。示例:

    public class PrinterWriter80mm extends PrinterWriter {
    
        public static final int TYPE_80 = 80;// 纸宽80mm
        public int width = 500;
    
        public PrinterWriter80mm() throws IOException {
        }
    
        public PrinterWriter80mm(int parting) throws IOException {
            super(parting);
        }
    
        public PrinterWriter80mm(int parting, int width) throws IOException {
            super(parting);
            this.width = width;
        }
    
        @Override
        protected int getLineWidth() {
            //一行能够放下多少个“-”
            return 24;
        }
    
        @Override
        protected int getLineStringWidth(int textSize) {
            //根据字体的大小,一行可以放下多少个英文字符
            switch (textSize) {
                default:
                case 0:
                    return 47;
                case 1:
                    return 23;
            }
        }
    
        @Override
        protected int getDrawableMaxWidth() {
            //图片能够全部打印在纸上的最大宽度
            return width;
        }
    }
    

    注意

    • 打印图片出现乱码或者打印不出,大部分原因是打印机缓存较小导致,可调小PrinterWriter80mm的parting参数,设置其图片高度分割值(0~255),调小了还不行的话,缩小图片尺寸或者调整输出流的写入方式。
    • 仅提供建立蓝牙连接打印,不包括蓝牙搜索及配对功能
    • 不包含二维码生成功能
    • PrintCommands包含了大量打印指令,但是并非全部经过测试,而且并非所有打印机都支持。

    支持

    如果发现错误,请在此处提出:
    https://github.com/AlexMofer/ProjectX/issues

    许可

    Copyright (C) 2015 AlexMofer

    Licensed to the Apache Software Foundation (ASF) under one or more contributor
    license agreements. See the NOTICE file distributed with this work for
    additional information regarding copyright ownership. The ASF licenses this
    file to you under the Apache License, Version 2.0 (the "License"); you may not
    use this file except in compliance with the License. You may obtain a copy of
    the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    License for the specific language governing permissions and limitations under
    the License.

    相关文章

      网友评论

          本文标题:AndroidPrinter

          本文链接:https://www.haomeiwen.com/subject/zrkqqctx.html