qrcode+jspdf前端打印条码一排多个,带中文版

下载依赖和引入

// 下载包, 本文使用jspdf@2.3.1
npm install jspdf qrcode

// 引入
import jsPDF from 'jspdf'
var QRcode = require('qrcode')

新建封装的generatePrint.js文件,新增利用canvas生成文字

import jsPDF from 'jspdf'
// import html2canvas from 'html2canvas';
// import './sourcebold-bold';
var QRCode = require('qrcode')
// import QRCode from 'qrcodejs2'
let width, height
let pdf
// let timer
// import addfont from '@/font/font'
// function addfont(pdf) {
//   var font = '' // 中的就是ttf转化成的编码
//   pdf.addFileToVFS('bolds', font)
//   return true
// }
// var isPrintZW

class PrintTag {
  constructor(data, style, isPrintZW) {
    this.imageList = []
    this.list = data
    this.isPrintZW = isPrintZW
    // this.printConfig = {
    //   // pageWidth: 870, // 一页宽度
    //   // pageHeight: 330, // 一页的高度
    //   pageWidth: 82,
    //   pageHeight: 30,
    //   left: 10, // 标签左边距
    //   offsetLeft: 22, // 每个标签的偏移量
    //   top: 4, // 标签上间距
    //   picWidth: 20, // 二维码宽度
    //   picHeight: 20, // 二维码高度
    //   linePicNum: 3, // 一排显示个数
    //   rotateDeg: 270, // 角度
    //   fontSize: 58 // 字号
    // }
    this.printConfig = style
    this.setPdfConfig()
  }
  start() {
    this.buildQRcode()
  }
  // 设置pdf
  setPdfConfig() {
    // console.log('ppp', this.printConfig)
    width = this.printConfig.pageWidth
    height = this.printConfig.pageHeight
    pdf = new jsPDF('l', 'mm', [width, height])
    // console.log('待',pdf)
    // console.log('有哪些',pdf.getFontList());
    // 添加并设置字体
    // addfont(pdf)
    // pdf.addFont('bolds', 'customFont', 'normal')
    pdf.setFont('customFont', 'bold')
    pdf.setFontSize(this.printConfig.fontSize)
    // // 在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})
    // pdf.text('我是中文', 20, 20, { angle: this.printConfig.rotateDeg })
  }
  // 生成二维码
  buildQRcode() {
    this.list.map((item, index) => {
      // console.log('iii',item)
      QRCode.toDataURL(item.sampleIdLims)
        .then(url => {
          this.imageList.push({ url: url, materielName: item.materielName, possessor: item.possessor, matCode: item.sampleIdLims })
        })
        .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
    const top = this.printConfig.top
    const textOpt = { angle: this.printConfig.rotateDeg }
    // console.log('ppp',this.printConfig)
    arr.map((base64, index) => {
      if (this.isPrintZW) {
        var canvas = document.createElement('canvas')
        // canvas.innerHTML = `<div>288282</div><div>test</div>`
        var context = canvas.getContext('2d')
        // 如果在这里直接设置宽度和高度会造成内容丢失 , 暂时未找到原因 , 可以用以下方案临时解决
        // canvas.width = context.measureText(text).width;

        // 方案一:可以先复制内容  然后设置宽度 最后再黏贴
        // 方案二:创建新的canvas,把旧的canvas内容黏贴过去
        // 方案三: 上边设置完宽度后,再设置一遍文字

        // 方案一: 这个经过测试有问题,字体变大后,显示不全,原因是canvas默认的宽度不够,
        // 如果一开始就给canvas一个很大的宽度的话,这个是可以的。
        // var imgData = context.getImageData(0,0,canvas.width,canvas.height);  //这里先复制原来的canvas里的内容
        // canvas.width = context.measureText(text).width;  //然后设置宽和高
        // context.putImageData(imgData,0,0); //最后黏贴复制的内容

        // 方案三:改变大小后,重新设置一次文字
        // canvas.width = context.measureText('你好').width;
        canvas.width = 600
        canvas.height = 300
        // 擦除(0,0)位置大小为200x200的矩形,擦除的意思是把该区域变为透明
        context.clearRect(0, 0, canvas.width, canvas.height)
        context.fillStyle = '#000'
        context.font = 'normal bold 32px Arial'
        // context.scale(0.8, 0.8)
        // 最多放18位
        context.textBaseline = 'middle'
        const str1 = `物料编号:${base64.matCode}`
        // console.log('长度',str1.substring(0,str1.length))
        if (str1.length <= 18) {
          context.fillText(str1, 0, 60)
        } else {
          context.fillText(str1.substring(0,18), 0, 60)
          context.fillText(str1.substring(19,str1.length), 0, 100)
        }
        const str2 = `物料名称:${base64.materielName}`
        if (str2.length <= 14) {
          context.fillText(str2, 0, 150)
        } else {
          context.fillText(str2.substring(0,14), 0, 150)
          context.fillText(str2.substring(15,str2.length), 0, 190)
        }
        const str3 = `供应商:${base64.possessor}`
        if (str3.length <= 14) {
          context.fillText(str3, 0, 240)
        } else {
          context.fillText(str3.substring(0,14), 0, 240)
          context.fillText(str3.substring(14,str3.length), 0, 280)
        }
        // context.fillText(`物料编号:${base64.matCode}`, 0, 60)
        // context.fillText(`物料编号:${base64.matCode}`, 0, 100)
        // context.fillText(`物料名称:${base64.materielName}`, 0, 150)
        // context.fillText(`物料名称:${base64.materielName}`, 0, 190)
        // context.fillText(`供应商:${base64.possessor}`, 0, 240)
        // context.fillText(`供应商:${base64.possessor}`, 0, 280)
        var dataUrl = canvas.toDataURL('image/png')// 注意这里背景透明的话,需要使用png
      }

      left = this.printConfig.left + this.printConfig.offsetLeft * (index % this.printConfig.linePicNum)
      // console.log('sssss',btoa(encodeURI('你好')),base64)
      if (this.isPrintZW) {
        // pdf.addImage(dataUrl, 'JPEG', left + 10, top+16, 30, 30, '', 'FAST')
        if (index === 0 || index % 2 === 0) { // 判断是第0个还是第偶数个
          pdf.addImage(base64.url, 'JPEG', left - 10, top, picWidth, picHeight, '', 'FAST')
          pdf.addImage(dataUrl, 'JPEG', left - 8, top + 16, 60, 30, '', 'FAST')
        } else {
          pdf.addImage(base64.url, 'JPEG', left, top, picWidth, picHeight, '', 'FAST')
          pdf.addImage(dataUrl, 'JPEG', left + 2, top + 16, 60, 30, '', 'FAST')
        }
      } else {
        pdf.addImage(base64.url, 'JPEG', left, top, picWidth, picHeight, '', 'FAST')
      }
      // pdf.text('hello 12345', left + item.offsetLeft, top + item.offsetTop, textOpt)
      // console.log('ooo',this.list[index].sampleIdLims.slice(0, 16),this.list[index].sampleIdLims.slice(16))
      if (!this.isPrintZW) {
        if (this.list[index].sampleIdLims.length > 15) {
          pdf.text(this.list[index].sampleIdLims.slice(0, 15) + '\n' + this.list[index].sampleIdLims.slice(15), left + 1, 19 + top, 0)
          // pdf.text(this.list[index].sampleIdLims.slice(0, 10)+'\n'+this.list[index].sampleIdLims.slice(10,21)+'\n'+this.list[index].sampleIdLims.slice(21),left-4,24,0)
        } else {
          // pdf.text(this.list[index].sampleIdLims,left,24,0)
          // pdf.text(this.list[index].sampleIdLims,left+4,23,0)20+top+0.5
          pdf.text(this.list[index].sampleIdLims, left + 4, 19.5 + top, 0)
        }
      }
      // 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')
      }
    })
    // _blank
    window.open(pdf.output('bloburl'), '_blank')
    // console.timeEnd('print')
  }
}
// isPrintZW:是否打印带中文的标签
export function generatePrint(data, step, lableType, style, isPrintZW = false) {
  // console.log(data, step)
  return new PrintTag(data, style, isPrintZW).start()
}

在需要打印的页面引用

import { generatePrint } from '@/utils/generatePrint'

data(){
    return{
        labelStyle: {
        // pageWidth: 870, // 一页宽度
        // pageHeight: 330, // 一页的高度
        // pageWidth: 104,
        // pageHeight: 50.8,
        // left: 14, // 标签左边距
        // offsetLeft: 28, // 每个标签的偏移量
        // top: 3, // 标签上间距
        // picWidth: 20, // 二维码宽度
        // picHeight: 20, // 二维码高度
        // linePicNum: 3, // 一排显示个数
        // rotateDeg: 270, // 角度
        // fontSize: 58 // 字号
      },
    }
},
methods:{
    // 打印二维码
    async printLabel() {
     let flag = false
      for (const key in this.labelStyle) {
        // console.log('dd',this.labelStyle[key])
        if (this.labelStyle[key] === null) {
          flag = true
        }
      }
      if (flag) {
        this.$message({
          type: 'warning',
          message: '打印格式参数未设置完整!'
        })
        return
      }
      // console.log('eee',this.showQRTable,this.isPrintAllType)
      let arr = []
      if (this.isPrintAllType) {
        arr = this.showQRTable.filter(val => {
          if (val.materielTypeName != null) {
            return val
          }
        })
        // console.log('aaa',arr)
      } else {
        arr = this.showQRTable
      }
      arr = arr.map(val => {
        const obj = {}
        obj.sampleIdLims = `${val.materielCode}#${val.materielNum}#${val.planCode}`
        obj.sampleIdLims = val.materielCode
        obj.materielName = val.materielName// 物料名称
        obj.possessor = val.possessor ? val.possessor : ''
        return obj
      })
      // console.log('aaa', arr)
      this.labelStyle = {
        pageWidth: 104,
        pageHeight: 50.8,
        // left: 14, // 标签左边距
        left: 12, // 标签左边距
        // offsetLeft: 28, // 每个标签的偏移量
        offsetLeft: 40, // 每个标签的偏移量
        top: -1, // 标签上间距
        picWidth: 20, // 二维码宽度
        picHeight: 20, // 二维码高度
        linePicNum: 2, // 一排显示个数
        rotateDeg: 270, // 角度
        fontSize: 6 // 字号
      }
      // // console.log('ddd',arr)
      generatePrint(arr, 2, '', this.labelStyle, true)
    },
}

最终效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值