IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 前端条码打印方案(表格+中文+一维码+二维码) -> 正文阅读

[JavaScript知识库]前端条码打印方案(表格+中文+一维码+二维码)

前言

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

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.length
  for (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, //单位,我这边用mm
    format: [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')

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

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-24 15:11:47  更:2022-02-24 15:13:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:44:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码