Vue3+TypeScript+printjs 实现标签批量打印功能
前言:临时性需求没怎么接触过前端,代码实现有问题及优化点希望大佬可以留言告知一下
开发工具: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`;
}
相关文章:

Vue3+TypeScript+printjs 实现标签批量打印功能
前言:临时性需求没怎么接触过前端,代码实现有问题及优化点希望大佬可以留言告知一下 开发工具:VS CODE 界面开发:Vue3TypeScriptElementPlus 打印组件:Print-JS 前端打印入口图: 标签页面: …...

微信文件如何直接打印及打印功能在哪里设置?
在数字化时代,打印需求依旧不可或缺,但传统打印店的高昂价格和不便操作常常让人头疼。幸运的是,琢贝打印作为一款集便捷、经济、高效于一体的网上打印平台,正逐渐成为众多用户的首选。特别是通过微信小程序下单,更是让…...
dataX -20240804-master分支
1、相关报错 Error: java.io.IOException: java.lang.RuntimeException: ORC split generation failed with exception: org.apache.orc.impl.SchemaEvolution$IllegalEvolutionException: ORC does not support type conversion from file type struct<nanos:int> (10)…...

【网络】传输层
传输层 一、预备知识1、端口号1、端口号范围划分2、知名端口号3、两个问题4、netstat && iostate5、pidof6、谈下面协议始终铭记两个问题 二、UDP协议(简单)1、UDP协议端格式2、UDP的特点3、面向数据报4、UDP缓冲区 三、TCP协议(重点…...

学生管理系统之更新和删除、筛选
学生管理系统之更新和删除 建立新的窗口 添加组件 进行布局 使用Widget把二个放在一块,作为一列,然后全选进行栅格布局,最后添加弹簧进行微调。 编写增加的槽函数 在主函数中调用对话框...

教您一键批量下载拼多多批发图片信息,节省时间
图片是电商的核心展示手段,高质量、吸引人的图片能显著提升商品吸引力,增强用户体验,促进购买决策。良好的视觉呈现有助于品牌形象的塑造,提高转化率和客户满意度,对电商平台的流量和销售业绩具有直接影响。 使用图快…...

基于微信小程序的微课堂笔记的设计与实现(源码+论文+部署讲解等)
博主介绍:✌全网粉丝10W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术栈介绍:我是程序员阿龙ÿ…...

去噪扩散恢复模型
去噪扩散恢复模型 Bahjat Kawar 计算机科学系 以色列海法理工学院 bahjat.kawarcs.technion.ac.il Michael Elad 计算机科学系 以色列海法理工学院 eladcs.technion.ac.il Stefano Ermon 计算机科学系 美国加利福尼亚州斯坦福大学 ermoncs.stanford.edu …...
Stable Diffusion 官方模型V1.5版本下载
模型描述 Stable Diffusion的官方模型更适合绘制偏写实的风格,如果您想绘制二次元之类的风格,可以考虑下载本站的其它模型。 安装方法 将模型下载后,将会得到一个名为****.ckpt格式的文件,将该文件剪切至你的Stable Diffusion本…...

【算法】双指针-OJ题详解1
双指针-OJ题 移动零(点击跳转)原理讲解代码实现 复写零(点击跳转)原理讲解代码实现 快乐数(点击跳转)原理讲解代码实现 盛最多水的容器(点击跳转)原理讲解代码实现 有效三角形的个数…...

29 两个任务切换(1)
1 这里涉及到进程的切换与之前的 特权级的切换还是不一样的。 2 给每个进程 在 GDT表中,分配一个 TSS, 这个TSS中 保存着这个进程 所用到的 通用寄存器段寄存器 3个可能的栈, 当进行 进程切换的时候,就是切换到 另一个 TSS表&am…...
正则表达式概述
一、正则表达式概述 正则表达式(Regular Expression,简称regex或regexp)是一种强大的文本处理工具,它使用一种特定的模式来描述和匹配一系列符合某个句法规则的字符串。在Python中,我们可以使用re模块来操作正则表达式…...

【C语言】Top K问题【建小堆】
前言 TopK问题:从n个数中,找出最大(或最小)的前k个数。 在我们生活中,经常会遇到TopK问题 比如外卖的必吃榜;成单的前K名;各种数据的最值筛选 问题分析 显然想开出40G的空间是不现实的&#…...
Rust 程序设计语言学习——并发编程
安全且高效地处理并发编程是 Rust 的另一个主要目标。并发编程(Concurrent programming),代表程序的不同部分相互独立地执行,而并行编程(parallel programming)代表程序不同部分同时执行,这两个…...

联邦学习研究综述【联邦学习】
文章目录 0 前言机器学习两大挑战: 1 什么是联邦学习?联邦学习的一次迭代过程如下:联邦学习技术具有以下几个特点: 2 联邦学习的算法原理目标函数本地目标函数联邦学习的迭代过程 3 联邦学习分类横向联邦学习纵向联邦学习联邦迁移…...
深入理解Python中的列表推导式
深入理解Python中的列表推导式 在Python编程中,列表推导式(List Comprehension)是一种简洁而强大的语法,用于创建和操作列表。它不仅提高了代码的可读性,还能显著减少代码的行数。本文将详细介绍什么是列表推导式,如何使用它,以及一些实际应用示例,帮助读者更好地理解…...

Android 实现左侧导航栏:NavigationView是什么?NavigationView和Navigation搭配使用
目录 1)左侧导航栏效果图 2)NavigationView是什么? 3)NavigationView和Navigation搭配使用 4)NavigationView的其他方法 一、实现左侧导航栏 由于Android这边没有直接提供左侧导航栏的控件,所以我尝试了…...

如何快速下载拼多多图片信息,效率高
图片是电商吸引顾客的关键因素,高质量的商品图片能提升产品吸引力,增强用户购买欲望。良好的视觉展示有助于建立品牌形象,提高转化率。同时,图片也是商品信息的主要传递媒介,对消费者决策过程至关重要。 使用图快下载器…...
windows 10下,修改ubuntu的密码
(1)在搜索框里面输入cmd,然后点击右键,选择管理员打开 Microsoft Windows [版本 10.0.22631.3880] (c) Microsoft Corporation。保留所有权利。 C:\Windows\System32>C: C:\Windows\System32>cd ../../ C:\>cd Users\ASUS\AppData\Local\Micros…...
【MySQL】慢sql优化全流程解析
定位慢sql 工具排查慢sql 调试工具:Arthas运维工具:Skywalking 通过以上工具可以看到哪个接口比较慢,并且可以分析SQL具体的执行时间,定位到哪个sql出了问题。 启用慢查询日志 慢查询日志记录了所有执行时间超过指定参数(lon…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...