下载依赖和引入
// 下载包, 本文使用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)
},
}
最终效果