首发于 极乐科技
JFinal小插件:Java驱动打印小票(80热敏打印机)

JFinal小插件:Java驱动打印小票(80热敏打印机)

来源: my.oschina.net/superzhu

作者:TheLostman(转载已获得作者许可)

摘要: 驱动打印,JFinal项目环境,可用于插件

驱动打印小票--80热敏打印机

项目环境基于JFinal2.2 偷了个懒直接在JFinal_demo上做的

在大神 SubLuLu/thermal_printer 开源的项目基础上写了这个demo,SubLuLu用的是指令打印,而且环境是基于Android的,所以我用Java做的项目无法很方便的打印图片和兼容更多的热敏打印机,因此借鉴大神的构思我采用驱动方式进行打印。

我(原作者)的项目地址: DriverPOSPrint

打印流程

如图中所示,在项目实际使用中采用异步的方式进行打印。调用者只需要创建新的PrintJob 添加到任务队列中,挂起的线程就会被自动唤起完成打印任务

打印模板

模板采用Json格式存储,分为header、goods、warn、msg四个部分,对模板的解析采用阿里出品的fastjson,模板共5中,模板名称分别对应PrintJob中missionType

模板示例-(simple.json)

模板中{$title}等表示指定的占位符,将来在打印参数中会被替换

打印规则

打印参数

参数示例

打印参数的代码结构如上所示,主要分为keys和goods两个部分:

封装的PrintJob

根据不同的missionType自动选用对应的模板,替换参数后打印

效果图(多模板)

(不好意思,把自拍发上来了)

使用示例

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.demo.common.driverpos.PrintJob;
import com.demo.common.driverpos.PrintQueue;
import com.demo.common.driverpos.PrintThread;
import com.jfinal.kit.JsonKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;

public class DriverPrintQueueTest extends BaseTest {

    static{

        System.out.println("printThread is start : " + System.currentTimeMillis());
        PrintThread.start();
    }

    @Override
    public void test() {
        mySleep(5);
        PrintQueue.add(new PrintJob(0, jsonParam(), "BTP-2002CP(E)"));
        mySleep(15);
    }

    public void mySleep(int i) {
        try {
            System.out.println("sleep" + i*1000 + "ms ...");
            Thread.sleep(i * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static Map<String, Object> jsonParam(){
        Map<String, Object> template = new HashMap<String, Object>();
        Map<String, Object> keys = new HashMap<String, Object>();
        String posResult = "点菜成功!1001 无此菜 本次点菜3/3份。其中2成功,1失败。合计XXXX元祝您用餐愉快!欢迎下次光临";
        keys.put("title", "网络订单");
        keys.put("brandName", "智慧餐厅");
        keys.put("shopName", "天山店");
        keys.put("tableNumb", "0002");
        keys.put("tableName", "外卖1");
        keys.put("orderId", "1609101220001");
        keys.put("dateTime", "2016-09-10 12:21:00");
        keys.put("allPrice", "66.88");
        keys.put("barCode","7255");

        if(!posResult.contains("成功")){
            if(posResult.contains("重单")){
                keys.put("warnTitle", "提    示");
                keys.put("warnMsg", "该订单已处理");
            }else{
                keys.put("warnTitle", "异常提示");
                keys.put("warnMsg", "自动下单失败请人工处理");
            }
        }else{
            if(posResult.contains("无此") || posResult.contains("沽清")
                    || posResult.contains("不存在")){
                keys.put("warnTitle", "异常提示");
                keys.put("warnMsg", "部分菜品未下成功请联系服务员人工处理");
            }
        }

        keys.put("posTitle", "收银软件下单结果");
        keys.put("posMsg", posResult);

        List<Map<String, Object>> goods = new ArrayList<Map<String,Object>>();
        List<Record> menu = Db.find("select * from menu");
//        int count = 0;
        for (Record record : menu) {
            Map<String, Object> good = new HashMap<String, Object>();
            good.put("code", record.get("code"));
            good.put("name", record.get("name"));
            good.put("quantity", "1.0");
            good.put("price", record.get("price"));
//            good.put("qrcode", "1.png");
//            if(count!=1){
//                good.put("remark", "免葱、免辣");
//            }
//            count++;
            goods.add(good);
        }

        template.put("goods", goods);
        template.put("keys", keys);
        System.out.println(JsonKit.toJson(template));
        return template;
    }

}
  • 在上面的代码中模拟多线程,一个线程取打印任务(Queue.take),当Queue队列为空时挂起。
  • 另一个线程add PrintJob,这时挂起的线程会被唤起,完成打印任务
  • 需要注意一点,示例中的baseTest类里有一个@BeforeClass 的方法加载SQLite数据库,用于读取菜品, 子类重写test方法即可用Unit进行单元测试

另外强调一点:驱动打印文本时自动换行没有采用指令方便,项目中已经实现自动换行功能,有兴趣的可以看看实现方式:)

—————————————————————————————————————————

在学习过程如果有任何疑问,请来极乐网( dreawer.com)提问,或者扫描下方二维码,关注极乐官方微信,在平台下方留言~

代办银行转账凭条舟山柜台转账汇款凭证报价曲靖柜台转账汇款凭证代做揭阳制作ATM转账凭条宜春做回执单赣州银行回执单价格湖州跨行转账凭条样本烟台汇款凭证查询长沙银行转账小票价格石家庄银行转账小票代办南昌汇款凭证哪家专业吉林跨行转账凭条样本天津银行定期存单用途开封代做转账凭条福州手机银行转账凭证定做郑州手机银行转账凭证用途重庆手机银行电子回单作用潍坊银行回执单作用包头开银行回执单北京定制银行柜台转账凭证江门代开ATM转账凭条揭阳银行转账回执单图片三亚打印转账凭条金华跨行转账凭条价格荆州打印转账回执单曲靖回执单哪家比较好九江银行转账凭条价格常德打印ATM转账回执单小票扬州转账凭条价格潮州柜台转账汇款凭证图片上饶定做汇款回执单香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

代办银行转账凭条 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化