java使用zpl指令在Zebra打印机上打印条形码

参考文章:https://blog.csdn.net/scholar_man/article/details/78784163

打印机使用的是斑马打印机
条码样式

在这里插入图片描述

工具类ZplPrinter
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

import javax.print.*;
import javax.print.attribute.standard.PrinterName;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

/**
 * @description: 条形码工具类
 * @author: haoxueyang
 * @create: 2021-05-17 16:13
 */
@Configuration //使用@Configuration是为了setEnvironment环境变量的注入
public class ZplPrinter implements EnvironmentAware {

    private String printerModelNumber = null;//打印机型号
    private PrintService printService = null;//打印机服务
    private byte[] dotFont;
    private String begin = "^XA";    //标签格式以^XA开始
    private String end = "^XZ";        //标签格式以^XZ结束
    private String content = "";

    /**
     * tr接口发送给SAP数据所调用的SAP的接口地址
     */
    private static String ZPL_PRINTER_FONT_FILE;

    @Override
    public void setEnvironment(Environment environment) {
        this.ZPL_PRINTER_FONT_FILE = environment.getProperty("zpl.printer.file");
    }

    public ZplPrinter() {
    }

    /**
     * 构造方法
     *
     * @param printerModelNumber 打印机型号
     */
    public ZplPrinter(String printerModelNumber) {

        this.printerModelNumber = printerModelNumber;
        //加载字体
        File file = new File(this.ZPL_PRINTER_FONT_FILE);
        if (file.exists()) {
            FileInputStream fis;
            try {
                fis = new FileInputStream(file);
                dotFont = new byte[fis.available()];
                fis.read(dotFont);
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("ts24.lib文件不存在");
        }
        //初始化打印机
        PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
        PrintService defaultService = PrintServiceLookup.lookupDefaultPrintService();
        System.out.println("默认的打印机" + defaultService.getName());
        if (services != null && services.length > 0) {
            for (PrintService service : services) {
                if (printerModelNumber.equals(service.getName())) {
                    printService = service;
                    break;
                }
            }
        }
        if (printService == null) {
            System.out.println("没有找到打印机:[" + printerModelNumber + "]");
            //循环出所有的打印机
            if (services != null && services.length > 0) {
                System.out.println("可用的打印机列表:");
                for (PrintService service : services) {
                    System.out.println("[" + service.getName() + "]");
                }
            }
        } else {
            System.out.println("找到打印机:[" + printerModelNumber + "]");
            System.out.println("打印机名称:[" + printService.getAttribute(PrinterName.class).getValue() + "]");
        }
    }

    /**
     * 设置条形码
     *
     * @param barcode 条码字符
     * @param zpl     条码样式模板
     */
    public void setBarcode(String barcode, String zpl) {
        content += zpl.replace("${data}", barcode);
    }

    /**
     * 中文字符、英文字符(包含数字)混合
     *
     * @param str 中文、英文
     * @param x   x坐标
     * @param y   y坐标
     * @param eh  英文字体高度height
     * @param ew  英文字体宽度width
     * @param es  英文字体间距spacing
     * @param mx  中文x轴字体图形放大倍率。范围1-10,默认1
     * @param my  中文y轴字体图形放大倍率。范围1-10,默认1
     * @param ms  中文字体间距。24是个比较合适的值。
     */
    public void setText(String str, int x, int y, int eh, int ew, int es, int mx, int my, int ms) {
        byte[] ch = str2bytes(str);
        for (int off = 0; off < ch.length; ) {
            if (((int) ch[off] & 0x00ff) >= 0xA0) {
                int qcode = ch[off] & 0xff;
                int wcode = ch[off + 1] & 0xff;
                content += String.format("^FO%d,%d^XG0000%01X%01X,%d,%d^FS\n", x, y, qcode, wcode, mx, my);
                begin += String.format("~DG0000%02X%02X,00072,003,\n", qcode, wcode);
                qcode = (qcode + 128 - 32) & 0x00ff;
                wcode = (wcode + 128 - 32) & 0x00ff;
                int offset = ((int) qcode - 16) * 94 * 72 + ((int) wcode - 1) * 72;
                for (int j = 0; j < 72; j += 3) {
                    qcode = (int) dotFont[j + offset] & 0x00ff;
                    wcode = (int) dotFont[j + offset + 1] & 0x00ff;
                    int qcode1 = (int) dotFont[j + offset + 2] & 0x00ff;
                    begin += String.format("%02X%02X%02X\n", qcode, wcode, qcode1);
                }
                x = x + ms * mx;
                off = off + 2;
            } else if (((int) ch[off] & 0x00FF) < 0xA0) {
                setChar(String.format("%c", ch[off]), x, y, eh, ew);
                x = x + es;
                off++;
            }
        }
    }

    /**
     * 英文字符串(包含数字)
     *
     * @param str 英文字符串
     * @param x   x坐标
     * @param y   y坐标
     * @param h   高度
     * @param w   宽度
     */
    public void setChar(String str, int x, int y, int h, int w) {
        content += "^FO" + x + "," + y + "^A0," + h + "," + w + "^FD" + str + "^FS";
    }

    public void setLineChar(String str, int x, int y, int h, int w) {
        content += "^FO" + x + "," + y + "^AF0," + h + "," + w + "^FD" + str + "^FS";
    }

    public void setColumnChar(String str, int x, int y, int h, int w) {
        content += "^FO" + x + "," + y + "^AFR," + h + "," + w + "^FD" + str + "^FS";
    }

    /**
     * 英文字符(包含数字)顺时针旋转90度
     *
     * @param str 英文字符串
     * @param x   x坐标
     * @param y   y坐标
     * @param h   高度
     * @param w   宽度
     */
    public void setCharR(String str, int x, int y, int h, int w) {
        content += "^FO" + x + "," + y + "^A0R," + h + "," + w + "^FD" + str + "^FS";
    }

    /**
     * 获取完整的ZPL
     *
     * @return
     */
    public String getZpl() {
        return begin + content + end;
    }

    /**
     * 重置ZPL指令,当需要打印多张纸的时候需要调用。
     */
    public void resetZpl() {
        begin = "^XA";
        end = "^XZ";
        content = "";
    }

    /**
     * 打印
     *
     * @param zpl 完整的ZPL
     */
    public void print(String zpl) {
        if (printService == null) {
            System.out.println("打印出错:没有找到打印机:[" + printerModelNumber + "]");
            throw new BizException("打印出错:没有找到打印机:[" + printerModelNumber + "]");
        }

        DocPrintJob job = printService.createPrintJob();
        byte[] by = zpl.getBytes();
        DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
        Doc doc = new SimpleDoc(by, flavor, null);
        try {
            job.print(doc, null);
            System.out.println("已打印");
        } catch (PrintException e) {
            e.printStackTrace();
        }
    }

    /**
     * 字符串转byte[]
     *
     * @param s
     * @return
     */
    private byte[] str2bytes(String s) {
        if (null == s || "".equals(s)) {
            return null;
        }
        byte[] abytes = null;
        try {
            abytes = s.getBytes("gb2312");
        } catch (UnsupportedEncodingException ex) {
            ex.printStackTrace();
        }
        return abytes;
    }
}

ServiceImpl层
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.print.*;
import java.text.SimpleDateFormat;

@Service
public class IBaseDeviceServiceImpl extends ServiceImpl<BaseDeviceMapper, BaseDevice> implements IBaseDeviceService {

    @Autowired
    IBaseDeviceService service;
    @Autowired
    IHrUserService userService;
    @Autowired
    LogisticsOperatorServiceImpl logisticsOperatorService;
    @Autowired
    LogisticsPathPointServiceImpl logisticsPathPointService;
    @Autowired
    IBaseDeviceRelationService iBaseDeviceRelationService;
    @Autowired
    IWmInventoryService inventoryService;
    @Autowired
    IWmWarehouseService warehouseService;
    @Autowired
    IBaseLabelCodeConvertService labelCodeConvertService;

    /**
     * pda端打印机打印标签
     * 1、需要把C://ts24.lib文件放到指定位置
     *
     * @param wrapper
     */
    @Override
    public void printPdaLabelCodeByPrinter(WmInventoryWrapper wrapper) throws PrintException {
        //条码显示的数据
        WmInventory inventory = inventoryService.getOne(new QueryWrapper<WmInventory>().eq("label_code", wrapper.getLabelCode()).last("limit 1"));
        if (inventory != null) {
            if (inventory.getAssociateWarehouseId() != null) {
                WmWarehouse warehouse = warehouseService.getOneById(inventory.getAssociateWarehouseId());
                if (warehouse != null) {
                    wrapper.setWarehouseCode(warehouse.getCode());//仓库code
                    wrapper.setWarehouseName(warehouse.getName());//仓库name
                }
            }
            if (inventory.getMaterialId() != null) {
                MaterialMapCache materialCache = MaterialMapCache.getInstance();
                BaseMaterial material = materialCache.getIdKeyMap().get(inventory.getMaterialId());
                if (material != null) {
                    wrapper.setMaterialCode(material.getCode());//物料code
                    wrapper.setMaterialName(material.getName());//物料名称
                }
            }
        } else {
            throw new BizException(wrapper.getLabelCode() + "标签不存在");
        }
        wrapper.setMaterialQuantity(inventory.getMaterialQuantity());//数量
        if (inventory.getPackageType() != null) {
            if (inventory.getPackageType() == Constant.PackageType.PACKAGE_TYPE_1) {
                wrapper.setBoxType("整箱区满箱");
            } else if (inventory.getPackageType() == Constant.PackageType.PACKAGE_TYPE_2) {
                wrapper.setBoxType("整箱区不满箱");
            } else if (inventory.getPackageType() == Constant.PackageType.PACKAGE_TYPE_3) {
                wrapper.setBoxType("散装区");
            }
        }
        if (inventory.getCreateTime() != null) {
            wrapper.setCreateTime(inventory.getCreateTime());
        }
        BaseLabelCodeConvert labelCodeConvert = labelCodeConvertService.getOne(new QueryWrapper<BaseLabelCodeConvert>().eq("label_code", wrapper.getLabelCode()));
        if (labelCodeConvert == null) {
            throw new BizException("该标签["+wrapper.getLabelCode()+"]没有转换打印id");
        }
        wrapper.setLabelCode(labelCodeConvert.getId().toString());
        //打印
        this.printLabelCodeByPrinter(wrapper);
    }

    /**
     * 公用方法:PC端和pda端公用打印方法
     *
     * @param wrapper
     * @throws PrintException
     */
    private void printLabelCodeByPrinter(WmInventoryWrapper wrapper) throws PrintException {
        //条码设置
        ZplPrinter zplPrinter = new ZplPrinter(wrapper.getPrintDeviceModelNumber());
        //第一行
        zplPrinter.setText("物料名称", 30, 60, 19, 19, 14, 1, 1, 22);//1.1
        if (!StringUtils.isEmpty(wrapper.getMaterialName())) {
            zplPrinter.setText(wrapper.getMaterialName(), 130, 60, 19, 19, 14, 1, 1, 22);//1.2
        }
        //第二行
        zplPrinter.setText("物料编码", 30, 110, 18, 18, 13, 1, 1, 22);//2.1
        if (!StringUtils.isEmpty(wrapper.getMaterialCode())) {
            zplPrinter.setText(wrapper.getMaterialCode(), 130, 110, 18, 18, 13, 1, 1, 22);//2.2
        }
        //第三行
        zplPrinter.setText("箱内数量", 30, 160, 18, 18, 13, 1, 1, 22);//3.1
        zplPrinter.setText(wrapper.getMaterialQuantity().toString(), 130, 165, 18, 18, 13, 1, 1, 22);//3.2
        zplPrinter.setText("箱子类型", 300, 160, 18, 18, 13, 1, 1, 22);//3.3
        zplPrinter.setText(wrapper.getBoxType(), 400, 160, 18, 18, 13, 1, 1, 22);//3.4
        //第四行 库存产生时间
        zplPrinter.setText("库存产生时间", 120, 210, 18, 18, 15, 1, 1, 22);
        if (wrapper.getCreateTime() != null) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-MM-dd");
            zplPrinter.setText(simpleDateFormat.format(wrapper.getCreateTime()), 320, 215, 18, 18, 13, 1, 1, 22);
        }
        //表格线
        //行线
        zplPrinter.setLineChar("____", 30, 20, 2, 100); //第1条横线
        zplPrinter.setLineChar("____", 60, 20, 2, 110); //第1条横线
        zplPrinter.setLineChar("____", 30, 80, 2, 100); //第2条横线
        zplPrinter.setLineChar("____", 60, 80, 2, 110); //第2条横线
        zplPrinter.setLineChar("____", 30, 130, 2, 100); //第3条横线
        zplPrinter.setLineChar("____", 60, 130, 2, 110); //第3条横线
        zplPrinter.setLineChar("____", 30, 180, 2, 100); //第4条横线
        zplPrinter.setLineChar("____", 60, 180, 2, 110); //第4条横线
        zplPrinter.setLineChar("____", 30, 225, 2, 100); //第5条横线 即条形码上方横线
        zplPrinter.setLineChar("____", 60, 225, 2, 110); //第5条横线 即条形码上方横线
        zplPrinter.setLineChar("____", 30, 350, 2, 100); //第6条横线 即条形码下方横线
        zplPrinter.setLineChar("____", 60, 350, 2, 110); //第6条横线 即条形码下方横线
        //列线
        zplPrinter.setColumnChar("____", 20, 40, 2, 60);//第1列竖线
        zplPrinter.setColumnChar("____", 20, 60, 2, 60);//第1列竖线
        zplPrinter.setColumnChar("_____", 120, 41, 2, 30);//第2列竖线
        zplPrinter.setColumnChar("____", 120, 62, 2, 20);//第2列竖线
        zplPrinter.setColumnChar("___", 290, 151, 1, 1);//第3列竖线 平均分列线
        zplPrinter.setColumnChar("__", 290, 164, 1, 1);//第3列竖线 平均分列线
        zplPrinter.setColumnChar("___", 390, 151, 1, 1);//第4列竖线
        zplPrinter.setColumnChar("__", 390, 164, 1, 1);//第4列竖线
        zplPrinter.setColumnChar("____", 550, 40, 2, 60);//第5列竖线
        zplPrinter.setColumnChar("____", 550, 60, 2, 60);//第5列竖线
        String barZpl = "^FO35,260^BY2,3.0,80^BCN,,Y,N,N^FD${data}^FS";//条码样式模板
        zplPrinter.setBarcode(wrapper.getLabelCode(), barZpl);
        //打印机打印条码
        String printerZpl = zplPrinter.getZpl();
        zplPrinter.print(printerZpl);
    }

}

service层

public interface IBaseDeviceService extends IService<BaseDevice> {

    /**
     * pda端:打印机打印标签
     *
     * @param wrapper
     */
    void printPdaLabelCodeByPrinter(WmInventoryWrapper wrapper) throws PrintException;


}

controller层


@Controller
@RequestMapping("/sys/baseDevice")
public class BaseDeviceController {
    @Autowired
    IBaseDeviceService service;

    private static final Logger logger = LoggerFactory.getLogger(BaseDeviceController.class);

    /**
     * pda端:打印机打印标签
     *
     * @return
     */
    @RequestMapping("/printLabelCodeByPrinter")
    @ResponseBody
    public JsonResult printLabelCodeByPrinter(@RequestBody WmInventoryWrapper wrapper) {
        JsonResult jsonResult = new JsonResult();
        try {
            if (StringUtils.isEmpty(wrapper.getLabelCode())) {
                return jsonResult.setMsg(Constant.Info.PARAM_ERR);
            }
            service.printPdaLabelCodeByPrinter(wrapper);
            return jsonResult.setMsg("打印成功").setSuccess(true);
        } catch (BizException | PrintException e) {
            logger.error("接口报错【/getPage】", e);
            jsonResult.setMsg(e.getMessage());
            jsonResult.setSuccess(false);
        }
        return jsonResult;
    }

}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值