前端生成二维码/条形码并以pdf导出

如上图是在最开始写完之后出现的情况:我的应用场景是可以一次生成单个或者多个二维码,比如当我第一次选中两条数据要生成时是正常的,但是当我第二次在第一次的基础上减少或者增加一条数据要生成时就会出现问题(第一个问题就是如上图,第二个问题是导出个数不对了)

以下为修改后代码:

savePDF() {
			if (this.printType == 1) {//生成条形码
				const newArr = this.listMultipleData.map(item => {
					return {
						barCodeName: item.name,
						barCodeDate: item.updateTime,
						barCodeOrderNumber: item.enCode
					};
				});
				this.$refs['myBarCode'].initDom(newArr).then(res1 => {
					// 生成条形码图片
					const promiseMap = this.listMultipleData.map((item, index) => {
						return this.$refs['myBarCode'].createdBarCodeImg(`#barcodeImg${index}`, item.enCode);
					});
					Promise.all(promiseMap).then(res2 => {
						this.$refs['myBarCode'].createCanvasLoop(newArr);
					});
				});
			} else {// 生成二维码图片
				const newArr = this.listMultipleData.map(item => {
					return {
						barCodeName: item.name,
						barCodeDate: item.updateTime,
						barCodeOrderNumber: item.code
					};
				});
				this.$refs['myQrCode'].initDom(newArr).then(res1 => {
					// 生成二维码图片
					const promiseMap = this.listMultipleData.map((item, index) => {
						return this.$refs['myQrCode'].createdQrCodeImg(index,item.enCode);
					})

					Promise.all(promiseMap).then(res2 => {
						this.$refs['myQrCode'].createCanvasLoop(newArr);
					});
				});
			}
		},

 封装组件(二维码)需注意createdQrCodeImg事件中需加清空对应二维码容器部分,不然会出现上图二维码遮挡情况

<template>
	<div class="barCode">
		<div class="qrCode" :id="`qrCodeImgBox${index}`" v-for="(item, index) in dataList" :key="index">
			<div class="qrCodeImgw" :ref="`qrCodeImg${index}`" :id="`qrCodeImg${index}`"></div>
			<div v-if="lineNumber == 2" class="orderNumber">{{ item.barCodeOrderNumber }}</div>
		</div>
	</div>
</template>
<script>
import html2Canvas from 'html2canvas';
import jsPDF from 'jspdf';
import QRCode from 'qrcodejs2';
export default {
	name: 'qrCode',
	data() {
		return {
			dataList: [],
			barCodeName: '',
			barCodeDate: '',
			qrcode: {}
		};
	},
	props: {
		lineNumber: {
			type: [Number, String]
		}
	},
	methods: {
		stopLoading() {
			this.$emit('stopLoading');
		},
		initDom(data) {
			return new Promise(resolve => {
				this.dataList = data;
				this.$nextTick(() => {
					resolve();
				});
			});
		},
		// 生成条形码
		createdQrCodeImg(index, text) {
			return new Promise(resolve => {
				const id = `#qrCodeImg${index}`;
				const targetDom = document.querySelector(id);
				console.log(this.qrcode);

				// 先清空对应的二维码容器
				if (targetDom && targetDom.firstChild) {
					while (targetDom.firstChild) {
						targetDom.removeChild(targetDom.firstChild);
					}
				}
				var qrcode = new QRCode(targetDom, {
					text: text, //可以是链接,也可以是文本
					width: 100, //
					height: 100, //二维码的高度
					colorLight: '#ffffff', //二维码背景色
					colorDark: '#000000', //二维码前景色,以实现红码为例
					correctLevel: QRCode.CorrectLevel.H //纠错等级
				});

				this.qrcode = qrcode;
				console.log(this.qrcode);

				resolve();
			});
		},
		// 遍历生成Canvas
		createCanvasLoop(data) {

			let pdf = new jsPDF({
				orientation: 'l',
				unit: 'pt',
				format: [140, 140],
				hotfixes: [] // an array of hotfix strings to enable
			});
			const options = { width: 150, height: 150, style: {} };
			let startY = 10;
			const indexArr = data.map((x, xi) => {
				return {
					...x,
					index: xi
				};
			});
			new Promise((resolve, reject) => {
				for (const item of indexArr) {
					const element = document.querySelector(`#qrCodeImgBox${item.index}`);
					// 使用html2canvas将 HTML 元素转换为 Canvas
					html2Canvas(element, options).then(canvas => {
						// 获取Canvas的图像数据
						const imgData = canvas.toDataURL('image/png');
						// 创建一个新的 jsPDF 实例
						// 将Canvas转换为PDF
						pdf.addImage(imgData, 'PNG', 20, 20, 150, 150);
						// startY += item.index * 5;
						if (item.index !== data.length - 1) {
							pdf.addPage();
						}
						if (item.index == data.length - 1) {
							resolve();
						}
					});
				}
			}).then(() => {

				pdf.save('标签打印.pdf');

				this.stopLoading();

			});
		}
	}
};
</script>
<style scoped lang="scss">
.qrCode {
	width: 120px;
	height: 120px;
}

.qrCodeImgw {
	margin-top: 50px;
}

.barCodeBox {
	width: 200px;
	height: auto;
	margin: 10px 15px 0 15px;
}

.code-table-excel {
	margin-top: 50px;
}

.code-table-excel td {
	border: 1px solid #000;
	border-collapse: collapse;
}

.text-center {
	text-align: center;
}

.orderNumber {
	margin-top: 5px;
	font-size: 13px;
	width: 87%;
	word-wrap: break-word;
}
</style>

效果图:

 

 封装组件(条形码)

<template>
    <div class="barCode">
        <table :id="`barCode${index}`" v-for="(item, index) in dataList" cellspacing="0" :key="index"
            class="code-table-excel" width="100%">
            <!-- <table cellspacing="0" class="code-table-excel" width="100%"> -->
            <tbody>
                <tr>
                    <td width="30%">名称</td>
                    <td width="70%">{{ item.barCodeName }}</td>
                </tr>
                <tr>
                    <td width="30%">日期</td>
                    <td width="70%">{{ item.barCodeDate }}</td>
                </tr>
                <tr v-if="lineNumber == 2">
                    <td width="30%">编码</td>
                    <td width="70%">{{ item.barCodeOrderNumber }}</td>
                </tr>
                <tr>
                    <td colspan="2" class="text-center">
                        <img class="barCodeBox" :id="`barcodeImg${index}`" />
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</template>
<script>
import html2Canvas from 'html2canvas';
import jsPDF from 'jspdf';
import JsBarcode from 'jsbarcode';
export default {
    name: "barCode",
    data() {
        return {
            dataList: [],
            barCodeName: '',
            barCodeDate: ''
        }
    },
    props: {
        lineNumber: {
            type: [Number, String]
        },
        styleObj: {
            type: Object
        }
    },
    methods: {
        stopLoading() {
            this.$emit('stopLoading');
        },
        initDom(data) {
            return new Promise((resolve) => {
                this.dataList = data;
                this.$nextTick(() => {
                    resolve();
                })
            })
        },
        // 生成条形码
        createdBarCodeImg(targetDom, number) {
            return new Promise((resolve) => {
                JsBarcode(targetDom, number, {
                    // format: "pharmacode",  //条形码的格式
                    lineColor: "#000",  //线条颜色
                    width: 4, //线宽
                    height: 80,  //条码高度
                    displayValue: false //是否显示文字信息
                });
                resolve();
            });
        },
        // 遍历生成Canvas
        createCanvasLoop(data) {

            let pdf = new jsPDF({
                orientation: 'l',
                unit: 'pt',
                // format: [135, 240],
                format: [this.styleObj.width, this.styleObj.height],
                hotfixes: [] // an array of hotfix strings to enable
            });
            // const options ={ width: 240, height: 160, style: {}};
            const options = { width: this.styleObj.width, height: this.styleObj.height, style: {} };
            let startY = 0;
            const indexArr = data.map((x, xi) => {
                return {
                    ...x,
                    index: xi
                }
            })
            new Promise((resolve, reject) => {
                for (const item of indexArr) {
                    const element = document.querySelector(`#barCode${item.index}`);
                    // 使用html2canvas将 HTML 元素转换为 Canvas
                    html2Canvas(element, options).then(canvas => {
                        // 获取Canvas的图像数据
                        const imgData = canvas.toDataURL('image/png');
                        // 创建一个新的 jsPDF 实例
                        // 将Canvas转换为PDF
                        pdf.addImage(imgData, 'PNG', 40, 20, 0, 0);
                        // startY += item.index * 5;
                        if (item.index !== data.length - 1) {
                            pdf.addPage();
                        }
                        if (item.index == data.length - 1) {
                            resolve();
                        }
                    });
                };
            }).then(() => {
                pdf.save("标签打印.pdf");
                this.stopLoading();
            });
        },
    }
}
</script>
<style scoped lang="scss">
.barCodeBox {
    width: 200px;
    height: 40px;
    margin: 10px 15px 0 15px;
}

.code-table-excel {
    margin-top: 50px;
}

.code-table-excel td {
    border: 1px solid #000;
    border-collapse: collapse;
}

.text-center {
    text-align: center;
}
</style>

效果图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值