前言

条码打印不同于普通打印机,条码大小各不相同,需要针对不同标签贴纸开发不同的样式

1. 条码打印的两种方案:

  • 后端ZPL指令打印
  • 前端调用浏览器打印

2. 优缺点分析:

优点 缺点
后端ZPL指令打印 样式固定,不会出现兼容性问题 不能调用客户端打印机,打印机需要支持ZPL指令
前端调用浏览器打印 对打印机品牌没有要求,可以调用客户端打印机打印 样式比较难调整,中文需要单独下载字体

一.后端打印

前端打印主要是使用javax.print.*包下的类通过给打印机发送ZPL指令的字符串实现打印服务,
核心的业务逻辑主要是寻找打印机,发送指令,如下:

 public class ZebraService {private static final Logger logger = LoggerFactory.getLogger(ZebraService.class);public ZebraService(ZebraProperties zebraProperties) {this.zebraProperties = zebraProperties;PrintService[] services = PrintServiceLookup.lookupPrintServices(null,null);if (services != null && services.length > 0) {for (PrintService service : services) {if (zebraProperties.getName().equals(service.getName())) {printService = service;break;}}}if (printService == null) {logger.error("没有找到打印机:{}",zebraProperties.getName());//循环出所有的打印机if (services != null && services.length > 0) {for (PrintService service : services) {logger.warn("可用的打印机:{}",service.getName());}}}else{logger.info("找到打印机:{},打印机名称:{}",zebraProperties.getName(),printService.getAttribute(PrinterName.class).getValue());}}public boolean print(String zpl){logger.info("当前ZPL:{}",zpl);if(printService==null){logger.error("打印出错:没有找到打印机{}",zebraProperties.getName());return false;}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);logger.info("已打印");return true;} catch (PrintException e) {logger.error("打印出错:{}",e.getMessage());return false;}}
}

具体的组装ZPL指令可以查询ZPL手册

二.前端打印

前端打印我主要测试了两种方案:1.直接画html然后打印,2.生成pdf后打印
第一种方案css样式调整起来折磨人,直接选择第二种简单粗暴

1.这里主要使用了3个插件:

npm i jspdf  # 用于生成pdf
npm i jsbarcode  # 用于生成一维码
npm i qrcode  # 用于生成二维码

2. 先贴出完整代码

import {jsPDF} from "jspdf";
import './jianbaosong-normal'const table = {unit:'mm',width:100,height:80,offset:2,colH:10,
}
let doc;
function tableInit(){doc = new jsPDF({orientation: "landscape",unit: table.unit,format: [table.width, table.height]});
}
//获取行Y值
function getRowY(indexRow,colH){return table.offset+indexRow*colH;
}export function pdfPrint(contents){tableInit();const length=contents.lengthfor (let i = 0; i < length; i++) {if(i>0&& i<length){doc.addPage([table.width,table.height],'landscape')}doc.setFont('jianbaosong');//上边doc.line(table.offset,table.offset,table.width-table.offset,table.offset)//左边doc.line(table.offset,table.offset,table.offset,table.height-table.offset)//右边doc.line(table.width-table.offset,table.offset,table.width-table.offset,table.height-table.offset)//下边doc.line(table.offset,table.height-table.offset,table.width-table.offset,table.height-table.offset)//画行doc.setFontSize(15)doc.text("xxxxx股份有限公司",11,9);doc.line(table.offset,getRowY(1,table.colH),table.width-table.offset,getRowY(1,table.colH))//第二行文字doc.setFontSize(12)doc.text("物料代码", 3, getRowY(2,table.colH)-3);doc.text(contents[i].materialNo, 30+3, getRowY(2,table.colH)-3);//第二行列doc.line(30,getRowY(1,table.colH),30,getRowY(2,table.colH))doc.line(table.offset,getRowY(2,table.colH),table.width-table.offset,getRowY(2,table.colH))doc.text("物料名称", 3, getRowY(3,table.colH)-3);doc.setFontSize(10)doc.text(contents[i].materialName, 30+3, getRowY(3,table.colH)-3);doc.line(30,getRowY(2,table.colH),30,getRowY(3,table.colH))doc.line(table.offset,getRowY(3,table.colH),table.width-table.offset,getRowY(3,table.colH))doc.setFontSize(12)doc.text("供应商名称", 3, getRowY(4,table.colH)-3);doc.setFontSize(10)doc.text(contents[i].supplierName, 30+3, getRowY(4,table.colH)-3);doc.line(30,getRowY(3,table.colH),30,getRowY(4,table.colH))doc.line(table.offset,getRowY(4,table.colH),table.width-table.offset,getRowY(4,table.colH))doc.setFontSize(12)doc.text("物料数量", 3, getRowY(5,table.colH)-3);doc.text(contents[i].volume+contents[i].mainUnit, 30+3, getRowY(5,table.colH)-3);doc.line(30,getRowY(4,table.colH),30,getRowY(5,table.colH))doc.line(table.offset,getRowY(5,table.colH),table.width-table.offset,getRowY(5,table.colH))doc.text("发货日期", 3, getRowY(6,table.colH)-3);doc.text(new Date().toISOString().split("T")[0],30+3, getRowY(6,table.colH)-3);doc.line(30,getRowY(3,table.colH),30,getRowY(6,table.colH))doc.line(table.offset,getRowY(6,table.colH),table.width-table.offset,getRowY(6,table.colH))//绘制条码及二维码// doc.addImage()doc.addImage(contents[i].img, 'JPEG', 70, getRowY(6,table.colH)+1, 14, 14, '', 'FAST')doc.addImage(contents[i].barcode, 'JPEG', 10, getRowY(6,table.colH)+1,48, 14, '', 'FAST')}window.open(doc.output('bloburl'), '_blank');
}

3. 再放生成效果

4.效果及代码解析

  1. 生成pdf对象
 doc = new jsPDF({orientation: "landscape", //方向,这里是横向unit: table.unit, //单位,我这边用mmformat: [table.width, table.height] //声明pdf大小});
  1. 画线,横线竖线同理
 doc.line(2,2,30,2) //从(2,2)坐标往右画一条长度为30mm的横线
  1. 内容,设置内容前设置字体样式,需要中文的话需要单独下载中文ttf字体,然后转成js文件,放入项目中,ttf文件转js可使用这个链接,然后直接使用字体名导入即可
doc.setFont('jianbaosong');
doc.setFontSize(12)
doc.text("供应商名称", 3, getRowY(4,table.colH)-3);
  1. 画一维码,二维码;这里是把一二维码图片的base64添加进pdf
doc.addImage(contents[i].img, 'JPEG', 70, getRowY(6,table.colH)+1, 14, 14, '', 'FAST')

具体一维码二维码生成方式见下篇文档

前端条码打印方案(表格+中文+一维码+二维码)相关推荐

  1. 智沃邦条码扫码出入库管理系统 仓库出入库管理系统 一维码 二维码系统

    智沃邦条码出入库管理系统,将普通的商品进行重新编码,并自动生成的一维码或者二维码,通过扫描器进行扫描操作,实现商品的出入库业务.本系统由西安智沃邦信息科技有限公司开发. 一.系统简介: 1.本系统可以 ...

  2. 使用扫描软件扫描含有中文字符的二维码显示乱码?

    在使用中琅领跑条码标签打印软件制作并打印二维码时,有些朋友也会遇到这种问题:使用扫描软件扫描含有中文字符的二维码时,扫描界面显示为一串问号(即乱码).是什么原因造成扫描中文乱码的呢?又该如何解决呢?今 ...

  3. halcon视觉 一维、二维码的区别-@龙熙视觉培训李杰

    一维码(条形码) 一维条码即指条码条和空的排列规则,常用的一维码的码制包括:EAN码.39码.交叉25码.UPC码.128码.93码,ISBN码,及Codabar(库德巴码)等. 条码是由一组规则排列 ...

  4. Andro Studio 基于Zing一维码二维码扫描代码

    现在一维码二维码在我们的日常生活中使用如此的广泛,所以拥有扫码功能的APP变得非常普遍,一个安卓APP需要扫码功能就要用到zxing了,zxing是谷歌开源的让开发者更方便使用摄像头的库,而我们常用的 ...

  5. STM32F407获取OV7670摄像头图像及上位机解码(一维码二维码)

    STM32F407获取OV7670摄像头图像及上位机解码(一维码&二维码) 1. 目的 针对静止拍摄图像场景,实现STM32F407对30万像素OV7670摄像头进行图像捕获,并通过串口将数据 ...

  6. STM32H750获取OV5640摄像头图像及上位机解码(一维码二维码)

    STM32H750获取OV5640摄像头图像及上位机解码(一维码&二维码) 1. 目的 针对静止拍摄图像场景,实现STM32H750对500万像素OV5640摄像头进行图像捕获,并通过串口将数 ...

  7. STM32F407获取OV2640摄像头图像及上位机解码(一维码二维码)

    STM32F407获取OV2640摄像头图像及上位机解码(一维码&二维码) 1. 目的 针对静止拍摄图像场景,实现STM32F407对200万像素OV2640摄像头进行图像捕获,并通过串口将数 ...

  8. STM32H750获取OV2640摄像头图像及上位机解码(一维码二维码)

    STM32H750获取OV2640摄像头图像及上位机解码(一维码&二维码) 1. 目的 针对静止拍摄图像场景,实现STM32H750对200万像素OV2640摄像头进行图像捕获,并通过串口将数 ...

  9. STM32H750获取OV7670摄像头图像及上位机解码(一维码二维码)

    STM32H750获取OV7670摄像头图像及上位机解码(一维码&二维码) 1. 目的 针对静止拍摄图像场景,实现STM32H750对30万像素OV7670摄像头进行图像捕获,并通过串口将数据 ...

最新文章

  1. 数字货币支付能成为主流吗?
  2. vue项目通过命令行传参实现多环境配置(基于@vue/cli)
  3. python threading 多线程
  4. 【计算机网络】网络层 : IPv4 地址 ( IP 地址分类 | 特殊 IP 地址 | 私有 IP 地址 | A 类、B 类、C 类 IP 地址网络号主机号数量 )★
  5. c++桥接模式bridge
  6. java数组的api_java程序员常用的11个API,赶紧收藏
  7. 数据结构与算法:已知二叉树两种遍历序列,求第三种遍历序列
  8. 广度优先搜索——字串变换(洛谷 P1032)
  9. php海思hi3531d,海思hi3531DV200 h.265编解码AI处理器
  10. ajax 循环php数组,jQuery通过ajax请求php遍历json数组到table中的代码(推荐)
  11. 3D打印软件——Repetier-Host 简单的使用总结
  12. 安全基础教育第二季第1集:屡战屡败的找回密码
  13. macbook linux 双系统,Mac双系统切换及设置技巧
  14. 校园财务管理系统——数据库设计
  15. 六级词汇总结( 整理自己的大学时候的资料发现的好东东!!~~)
  16. python检测刀具_科研一角|Python语言在人工智能加工中心机器人方面的应用
  17. html放大镜,可清晰放大整个网页
  18. 《java程序员面试笔试宝典》学习笔记
  19. Student的增删改查
  20. 联想y7000笔记如何安装matlab,联想Y7000P笔记本怎样安装win7系统 安装win7系统操作分享...

热门文章

  1. python数据分析论文报告_Calaméo - 【原创】在PYTHON中进行主题模型LDA分析数据分析报告论文(代码+数据) ....
  2. PHP图片处理库Grafika详细教程(4):图形绘制
  3. 概率统计中的样本矩和顺序统计量
  4. 极品飞车ol 与服务器连接不稳定,极品飞车ONLINE燃擎封测常见问题FAQ
  5. 商家私域流量运营价值考核方式,私域流量池的数据评价指标!
  6. P2P之关资金存管(三)我们的模式:懒猫
  7. 婚礼请帖_20个精美的婚礼请柬网站设计
  8. Java命令行程序构建工具airlift使用
  9. android 主题xml,自定义Android主题风格theme.xml方法 Android开发技术
  10. Golang的执行流程,即注意事项