Vue3+TypeScript+printjs 实现标签批量打印功能

news2024/11/16 7:23:40

前言:临时性需求没怎么接触过前端,代码实现有问题及优化点希望大佬可以留言告知一下

开发工具:VS CODE

界面开发:Vue3+TypeScript+ElementPlus

打印组件:Print-JS

前端打印入口图:

标签页面:

打印界面:

实现功能:前端点击"打印标签"弹出打印界面进行打印作业

实现过程:主界面点击"打印标签"调用el-dialog弹窗(预览和直接打印都居于弹窗实现)

  标签模板代码:

<template>
    <div class="LabelPrint-List">
        <el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="50%" >
            <template #header>
				<div style="color: #fff">
					<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit/> </el-icon>
					<span>标签打印界面</span>
				</div>
			</template>
            <el-row :gutter="10">
                <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb10">
                     <div v-for="item in state.Datas">
                        <el-card class="box-card" style="width:100mm; height: 90mm;display: block;" >
                            <div :id='item.id?.toString()'>
                                <!-- print-js -->
                                <div class="labelHeadBody">
                                    <div class="labelHeadBodyLeftHead">
                                        <img class="labelHeadBodyLeftHeadimage"  src="/image/点金log.png" fit="fill" />
                                    </div>
                                    <div class="labelHeadBodyRightHead">
                                        <table class="tableHead">
                                            <tr>
                                                <td class="labelHeadBodyRightHeadTd">某某有限公司</td>
                                            </tr>
                                            <tr>
                                                <td class="labelHeadBodyRightHeadTd">物料标识卡</td>
                                            </tr>
                                        </table>
                                    </div>
                                </div>
                                <div class="labelBody">
                                     <table>
                                        <tbody>
                                            <tr><td class="lableBodytdleft">P/N:</td><td class="lableBodytdright">{{ item.produceNo }}</td></tr>
                                            <tr><td class="lableBodytdleft">数量:</td><td class="lableBodytdright">{{ item.quantity }}</td></tr>
                                            <tr><td class="lableBodytdleft">规格:</td><td class="lableBodytdright lableBodytdrightfont">{{ item.platingSpecs }}</td></tr>
                                            <tr><td class="lableBodytdleft">供应商:</td><td class="lableBodytdright">东莞点金</td></tr>
                                            <tr><td class="lableBodytdleft">生产日期:</td><td class="lableBodytdright">{{moment(String(item.createTime)).format('YYYY/MM/DD')}}</td></tr>
                                            <tr><td class="lableBodytdleft">批次单号:</td><td class="lableBodytdright">{{ item.lot }}</td></tr>
                                            <tr><td class="lableBodytdleft">单重:</td><td class="lableBodytdright">{{ item.singleWeight }}</td></tr>
                                            <tr><td class="lableBodytdleft">总重:</td><td class="lableBodytdright">{{ item.sumWeight }}</td></tr>
                                            <tr><td class="lableBodytdleft">标识人:</td><td class="lableBodytdright"></td></tr>
                                        </tbody>
                                     </table>
                                </div>
                                
                            </div>
                        </el-card>
                     </div>
                </el-col>
            </el-row>
            <template #footer>
				<span class="dialog-footer">
					<el-button @click="cancel">取 消</el-button>
                    <el-button style="background-color:red;color:white" @click="print">打 印</el-button>
				</span>
			</template> 
        </el-dialog>
    </div>
</template>

Typescript代码:

printrow 方法中使用nextTick是当el-dialog弹窗DOM加载完成后在调用PrintJS获取需要打印的区域,这个直接打印过程其实会先弹窗然后DOM加载完成后直接调用浏览器打印界面,后面把弹出关闭,如果不加载el-dialog可以通过动态加载html内容来实现直接打印,我这里图方便就用该方法实现了。

printJS({printable:区域id,type:打印类型(pdf\image\html等),style:打印内容的CSS样式})

注意:style参数值按打印区域的HTMLCSS样式构建,调用printJS设置scanStyles:false不会自动加载HTML的CSS样式需要重新给Style参数赋值所以增加了一个printStyle函数,scanStyles默认值是true(会导致打印界面的内容奇奇怪怪,还没去了解详细原因哈哈哈哈)

<script lang="ts" setup>
import { ref,reactive,nextTick } from 'vue';
import { TbProduceOrderNoInfo } from '/@/api-services';
import printJS from 'print-js';
import moment from 'moment';
const props=defineProps({
    title:String
})

const state=reactive({
    isShowDialog:false,
    Datas:[] as Array<TbProduceOrderNoInfo>,
})

const emits = defineEmits(['handleQuery']);
const closeDialog=()=>{
    emits('handleQuery');
    state.isShowDialog=false;
}

const cancel=()=>{
    state.isShowDialog=false;
    closeDialog();
}

//预览+打印
const openDialog=async(row:any)=>{
   
   state.Datas=JSON.parse(JSON.stringify(row));

   state.isShowDialog=true;
}

const print=()=>{
   for(var i=0;i<state.Datas.length;i++){
      printJS({printable:`${state.Datas[i].id}`,type:"html",style:printStyle(),scanStyles:false})
   }
}

//直接打印不预览
const printrow=async(row:any)=>{
    state.Datas=JSON.parse(JSON.stringify(row));
    state.isShowDialog=true;
    //主界面form DOM加载完成
    nextTick(()=>{
            //弹窗加载完成
            nextTick(()=>{
                printJS({printable:`${state.Datas[0].id}`,type:"html",style:printStyle(),scanStyles:false})
                state.isShowDialog=false;
            })
        })
}

//打印界面的CSS样式
const printStyle=()=>{
    return `
.labelHeadBody{
    display: flex;justify-content:space-between;margin: 0; font-size: 16px;width: 100%; height:45px
}
.labelHeadBodyLeftHead{
    width: 30px;
}
.labelHeadBodyRightHead{
    width: 250px; height: 70px;display: flex;justify-content: center;
}
.lableBodytdrightfont{
    font-size:10px
}
.labelHeadBodyRightHeadTd{
    padding: 0;
    font-size: 14px;
    font-weight: bold;
    text-align: center;
    vertical-align: middle;
}
.labelBody{
    margin-left: 5px;
    margin-right: 5px;
}
.lableBodytdleft{
    width: 30%;
    font-weight: bold;
    vertical-align: bottom;
   
}

.lableBodytdright{
    width: 70%; 
    border-bottom: 1px solid;
}
.labelHeadBodyLeftHeadimage{
    width: 70px; height: 40px
}
.tableHead{
    height: 20px;
}
    `;
}



//预览、直接打印
defineExpose({openDialog,printrow})
</script>

标签前端样式代码:

<style>
.labelHeadBody{
    display: flex;justify-content:space-between;margin: 0; font-size: 16px;width: 100%;
}
.labelHeadBodyLeftHead{
    width: 30px;
}
.labelHeadBodyRightHead{
    width: 250px; height: 70px;display: flex;justify-content: center;
}

.labelHeadBodyRightHeadTd{
    padding: 0;
    font-size: 14px;
    font-weight: bold;
    text-align: center;
    vertical-align: middle;
}
.labelBody{
    margin-top: 10px;
    margin-left: 5px;
    margin-right: 5px;
}
.lableBodytdleft{
    width: 30%;
    font-weight: bold;
    vertical-align: bottom;
   
}
.lableBodytdright{
    width: 75%; 
    border-bottom: 1px solid;
}
.labelHeadBodyLeftHeadimage{
    width: 80px; height: 55px
}
.tableHead{
    height: 20px;
}
</style>

最后,如果需要带二维码的同学可以添加qrcode组件,以下是简单的实现(el-image、img标签中图片不显示的问题还没解决,迂回操作直接把生成的二维码图片设置成控件背景来处理,囧.........):

<template #default="scope">
                         <div :style="createQrcode(scope.row.eqNo)" ></div>
                          <!-- <el-image :scr="createQrcode1(scope.row.eqNo)" style="width: 60px;height: 60px;"></el-image> -->
</template>


import QRCode from 'qrcode'


//将生成的二维码设置成div的Style,不知道为嘛el-image绑定base64image图片不显示
const createQrcode=(text:string)=>{
    if(text==""||text==undefined||text==null) return "";
    let url1:any;
    url1="";  
    QRCode.toDataURL(text,(err,url)=>{
        if(err){
            console.error(err);
        }
        else{
            url1=url;
        }
    })
    return `background-image: url(${url1});background-position: center center;background-size: contain;background-repeat: no-repeat;;width:100%;height:60px`;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1963671.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电气数字化能为企业带来哪些助力?

本文主要从“电气行业概况” 和 “电气数字化核心价值”2个方面&#xff0c;为大家全方位解答“电气数字化能为企业带来哪些助力&#xff1f;” 一、电气行业概况 总体而言&#xff0c;我国电气行业是规模体量巨大的基础产业&#xff0c;目前存在平均效益不高、生产及交易效率…

linux-centos配置jdk环境变量

1、在官网下载适配的jdk到本地后&#xff0c;通过ssh工具将文件上传到 /etc目录下 2、使用命令 vim /etc/profile 在文件末尾加上 #set java environment JAVA_HOME/etc/jdk1.8 JRE_HOME/etc/jdk1.8/jre CLASS_PATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOM…

Codeforces Round 946 (Div. 3) C. Beautiful Triple Pairs (容斥原理)

注意这里的三元组是按顺序找出来的&#xff0c;不能够随便组合。 由于数组长度不算很大&#xff0c;我们可以实现一层循环。 根据题目&#xff0c;我们分别调取对于当前遍历到的三元组&#xff0c;第一个数不同其余数相同&#xff0c;第二个数不同其余数相同&#xff0c;第三个…

运维-6-采用LPG搭建轻量级日志收集系统

参考Grafana 安装配置教程 1 Grafana Grafana是一个通用的可视化工具。对于Grafana而言&#xff0c;Prometheus这类为其提供数据的对象均称为数据源&#xff08;Data Source&#xff09;。目前&#xff0c;Grafana官方提供了对&#xff1a;Graphite, InfluxDB, OpenTSDB, tde…

v-for遍历数据类型方式

第一种&#xff1a;数组 v-for"(item, index) in list" 属性作用item取数组的每一项的对象&#xff1b;index取数组的每一项的下标&#xff1b; html&#xff1a; <div v-for"(item, index) in list" :key"index"><span>名称&…

探索设计模式:组合模式

探索设计模式&#xff1a;组合模式 &#x1f9d0;1. 概念&#x1f3af;2. 作用&#x1f4e6;3. 用法&#x1f4e6;3.1 绘图示例&#x1f4e6;3.2 文件示例 &#x1f4bb;4. 使用场景 在软件设计中&#xff0c;组合模式&#xff08;Composite Pattern&#xff09;是一种结构型设…

WebLogic:弱口令,木马反弹连接

weblogic WebLogic 是 Oracle 公司开发的应用服务器&#xff0c;主要用作开发、集成、部署和管理大型分布式 Web 应用、网络应用和数据库应用的 Java 应用服务器。它在历史上曾出现过多个安全漏洞&#xff0c;其中包括弱口令、任意文件上传、SSRF、反序列化漏洞等 常见版本&a…

YOLOv8入门 | yaml文件解读,YOLOv8网络结构打印以及网络结构图绘制【小白必看】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

软考高级-系统架构设计师

2024广东深圳考试时间 报考人员可登录中国计算机技术职业资格网&#xff08;http://www.ruankao.org.cn&#xff09;进行网上报名&#xff0c;报名前须扫码绑定个人微信&#xff0c;不允许代报名。 上半年考试报名信息填报时间&#xff1a;2024年3月25日9:00&#xff0d;4月2日…

【ASR系列】【论文阅读】CIF

1. 概念学习 WER(word error rate): 单词错误率,是评价asr系统的一种重要指标,越低越好 是Continuous integrate-and-fire的简称,集成和发射,翻译成积分不太合理,可理解为求和 2. 思想 一个人说了几句话,在说第一句话的时候会不断地对输入的信号集成,说完这句话(达…

计算机毕业设计PySpark+Django高考志愿填报推荐系统 高考预测 高考大数据分析 Hadoop Spark 机器学习 深度学习 Python

在撰写关于《PySpark高考推荐系统》的论文时&#xff0c;推荐算法的实现通常会利用PySpark&#xff0c;这是Apache Spark的Python API。以下是一个使用PySpark中MLlib库的ALS&#xff08;交替最小二乘法&#xff09;算法来构建高考推荐系统的示例代码。在这个示例中&#xff0c…

短视频矩阵系统搭建教程,源码获取,部署上线指南

目录 一、短视频矩阵是什么&#xff1f; 二、搭建教程 1、前端界面开发 2、后端架构搭建 3、第三方视频平台对接 三、部分代码展示 一、短视频矩阵是什么&#xff1f; 短视频矩阵系统是一种集成了多元短视频平台功能的综合性管理工具&#xff0c;它汇聚了多个视频发布渠…

MyBatis-Plus知识总结

1. MP前瞻 官网&#xff1a;https://baomidou.com/ 1、MyBatis-Plus是什么&#xff1a;MyBatis-Plus&#xff08;简称MP&#xff09;是一个MyBatis的增强工具&#xff0c;它在MyBatis的基础上只做增强不做改变&#xff0c;为简化开发、提供效率而生。并且MP内部提供了丰富的 AP…

(已解决,附RDM工具解决方案)如何实现多个redis连接间指定key(键)的数据同步

目录 问题现象&#xff1a; 问题分析&#xff1a; 方法一-重复执行操作&#xff1a; 方法二-redis命令实现导出再导入&#xff1a; 方法三-使用rdb文件实现数据迁移 方法四-RDM工具自带的数据复制功能 总结&#xff1a; 解决方法&#xff1a; 方法一-重复执行…

SpringMVC(包括Servlet,会话技术)理解

目录 前言&#xff1a; Servlet&#xff1a; http请求的内容&#xff1a; 会话技术&#xff1a; Cookie&#xff1a; Session&#xff1a; 案例实现代码&#xff1a; 小总结&#xff08;感想&#xff09;&#xff1a; SpringMVC介绍&#xff1a; 调用流程&#xff1a…

最后一个单词的长度-string

58. 最后一个单词的长度 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int lengthOfLastWord(string s) {int right s.size()-1;while(s[right] ){right--;}int cnt 0;while(right > 0 && s[right] ! ){right--;cnt;}return cnt;} }; 注意…

达梦数据库系列—39.统计信息详解

目录 达梦统计信息 举例 统计信息的缺点 统计信息管理 手动收集 自动收集 查看统计信息 更新统计信息 删除统计信息 达梦统计信息 达梦数据库的统计信息分为表统计信息&#xff0c;列统计信息&#xff0c;索引统计信息。 表&#xff1a;计算表的行数、所占的页数目、…

二百五十、Linux——visudo 命令编辑 /etc/sudoers 文件时报错 “/etc/sudoers 忙,请稍后重试”

一、目的 在Linux上用visudo 命令编辑 /etc/sudoers 文件时报错&#xff0c;/etc/sudoers 忙&#xff0c;请稍后重试 [roothurys23 ~]# sudo visudo visudo: /etc/sudoers 忙&#xff0c;请稍后重试 二、原因分析 1 另一个 visudo 实例正在运行 如果另一个用户或同一个用户…

Mirror学习笔记(一) 简介

文章目录 一、常规学习&#xff1a;Mirror核心功能有服务器和主机 二、时间戳批处理时间戳 三、TCP和UDP四、CCU(同时在线人数)五、SyncDirection(同步方向)六、RTT&#xff08;往返时间&#xff09;七、Connection Quality&#xff08;连接质量&#xff09;八、Lag Compensati…

django档案馆集中管理系统-计算机毕业设计源码31775

目录 摘要 Abstract 第一章 绪论 1.1 选题背景及意义 1.2 国内外研究现状 1.3 研究方法 第二章 相关技术介绍 2.1 MySQL简介 2.2 Python 2.3 Django框架 2.4 Pycharm简介 第三章 档案馆集中管理系统系统分析 3.1 系统可行性分析 3.1.1 技术可行性 3.1.2 经济可行…