阅读 271

qrcode+jspdf前端打印标签

业务背景

需求是前端打印出一排2个、一排5个、圆标签等,各种样式的标签,并包含二维码、中英文、数字, 如下图:

094a12ae8b69c45d9099c2540c5ca587.jpg 对于打印机来讲,一排就是一页,想要打印出这样的标签,步骤如下:

  1. 确认前端打印功能

  2. 计算每个标签在一页中的位置

  3. 每个标签中打印二维码

  4. 打印英文和数字

  5. 打印中文


方案确认

首先确定jspdf作为前端打印插件,jspdf的文档很细,功能强大,是一个优秀的框架,但是默认不支持中文,需要额外引入字体,最开始想通过html2canvas的方法把页面的中文通过dom生成图片再使用jspdf打印出来的方案,后来发现打印出来的文字很不清晰,清晰度的问题难以解决,所以就只能换成直接使用jspdf直接生成文字的方式处理,就是必须要引入字体文件。

实现方法

一、引入jspdf和qrcode

// 下载包, 本文使用jspdf@2.3.1 npm install jspdf qrcode // 引入 import jsPDF from 'jspdf' var QRcode = require('qrcode') 复制代码

二、确定标签尺寸和纸张尺寸, 配置jspdf

以一排5个为例,使用的纸张尺寸是87 * 33, 标签尺寸是 15 * 30

const pdf = new jsPDF('l', 'mm', [870, 330]) // 声明一套配置 const printConfig = {      pageWidth: 870, // 一页宽度     pageHeight: 330, // 一页的高度     left: 35, // 标签左边距     offsetLeft: 174, // 每个标签的偏移量     top: 25, // 标签上间距     picWidth: 100, // 二维码宽度     picHeight: 100, // 二维码高度     linePicNum: 5, // 一排显示个数     rotateDeg: 270, // 角度     fontSize: 58 // 字号 } 复制代码

三、生成二维码并在指定位置打印

const imageList = [] // 声明一个imageList用了存放二维码base64 list.map((item, index) => {   QRCode.toDataURL(item.code)   .then(url => {     imageList.push(url)   })   .catch(err => {     console.error(err)   }) }) // 打印二维码图片 let left = printConfig.left let top = printConfig.top imageList.map(base64 => {   left = printConfig.left + printConfig.offsetLeft * (index % printConfig.linePicNum)    // 添加图片   pdf.addImage(base64, 'JPEG', left, top, picWidth, picHeight, '', 'FAST')      // 超过限制个数就翻页   if (index !== 0 && (index + 1) % printConfig.linePicNum === 0 && index < imageList.length - 1 ) {     pdf.addPage([width,  height], 'l')   } }) 复制代码

这样可以在指定位置打印出二维码了

三、打印英文和数字

jspdf直接可以打印英文和数字,所以直接打印即可, left和top是需要增加偏移量的

 pdf.text('this is my word', left + item.offsetLeft, top + item.offsetTop, {angle: printConfig.rotateDeg}) 复制代码

四、打印中文

中文的引入会麻烦一些,需要引入语言包,具体生成方法可以参考官网,或参考 www.cnblogs.com/ww01/p/1149…

先找到ttf文件后convert成一个js,将生成的js放到文件中

function addfont(pdf) {     var font = 'AA****' // 中的就是ttf转化成的编码     pdf.addFileToVFS('bolds', font)     return true; } // 在pdf生成后,添加并设置字体 addfont(pdf) pdf.addFont('bolds', 'customFont', 'normal') pdf.setFont('customFont') pdf.setFontSize(58) //打印 pdf.text('我是中文', left + item.offsetLeft, top + item.offsetTop, {angle: printConfig.rotateDeg}) 复制代码

完整代码

以下是我封装的打印方法, 外部直接调用generatePrint即可

import jsPDF from 'jspdf' var QRCode = require('qrcode') let width, height; let pdf; let timer class PrintTag {   constructor(data) {     this.imageList = []     this.list = data     this.printConfig = {          pageWidth: 870, // 一页宽度         pageHeight: 330, // 一页的高度         left: 35, // 标签左边距         offsetLeft: 174, // 每个标签的偏移量         top: 25, // 标签上间距         picWidth: 100, // 二维码宽度         picHeight: 100, // 二维码高度         linePicNum: 5, // 一排显示个数         rotateDeg: 270, // 角度         fontSize: 58 // 字号     }     this.setPdfConfig()   }   start() {     this.buildQRcode()   }   // 设置pdf   setPdfConfig() {     width = this.printConfig.pageWidth     height = this.printConfig.pageHeight     pdf = new jsPDF('l', 'mm', [width,  height])     //添加并设置字体     addfont(pdf)     pdf.addFont('bolds', 'customFont', 'normal')     pdf.setFont('customFont')     pdf.setFontSize(58)   }   // 生成二维码   buildQRcode() {     this.list.map((item, index) => {       QRCode.toDataURL(item.sampleIdLims)       .then(url => {         this.imageList.push(url)       })       .catch(err => {         console.error(err)       })     })     this.checkImageLoaded()   }   // qrcode是异步,所以延迟生成pdf   checkImageLoaded() {     setTimeout(() => {       if (this.imageList.length === this.list.length) {         this.generate(this.imageList)       }     }, 500)   }   // 生成pdf   generate(arr) {     console.time('print')     const picWidth = this.printConfig.picWidth     const picHeight = this.printConfig.picWidth     let left = 0     let top = this.printConfig.top     const textOpt = {angle: this.printConfig.rotateDeg}     arr.map((base64, index) => {       left = this.printConfig.left + this.printConfig.offsetLeft * (index % this.printConfig.linePicNum)       pdf.addImage(base64, 'JPEG', left, top, picWidth, picHeight, '', 'FAST')       pdf.text('hello 12345', left + item.offsetLeft, top + item.offsetTop, textOpt)       pdf.text('我说中文', left + item.offsetLeft, top + item.offsetTop + 25, textOpt)               if (index !== 0 && (index + 1) % this.printConfig.linePicNum === 0 && index < arr.length - 1 ) {         pdf.addPage([width,  height], 'l')       }     })          window.open(pdf.output('bloburl'), '_blank');     console.timeEnd('print')   } } export function generatePrint(data, step, lableType) {   console.log(data, step)   return new PrintTag(data, step, lableType).start() }


作者:上头小官
链接:https://juejin.cn/post/7023680840441790501

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐