vue3-print-nb实现打印pdf分页

安装插件

npm install vue3-print-nb --save

vue3 引入

import print from 'vue3-print-nb' // 打印插件
app.use(print)

使用
这里使用的是对象配置方式

对象配置方式——在js中定义一个对象,对象中可配置打印区域相关属性,在需要打印的单据内容最外面的div设置唯一的id,id值为js对象中的id值,在打印弹框里的打印按钮设置自定义属性v-print,该属性值为打印区域的对象

<a-button type="primary" @click="printing" v-print="printObj">打印</a-button>const printObj = {id: "mypdf", // 这里是要打印元素的IDpopTitle: "&nbsp", // 打印的标题extraCss: "", // 打印可引入外部的一个 css 文件extraHead: "", // 打印头部文字preview: false, // 是否启动预览模式,默认是falsepreviewTitle: '中铜国际贸易集团有限公司', // 打印预览的标题previewPrintBtnLabel: '预览结束,开始打印', // 打印预览的标题下方的按钮文本,点击可进入打印zIndex: 10002, // 预览窗口的z-index,默认是20002,最好比默认值更高previewBeforeOpenCallback() {console.log('正在加载预览窗口!')},previewOpenCallback() { console.log('已经加载完预览窗口,预览打开了!') }, // 预览窗口打开时的callbackbeforeOpenCallback() {console.log('开始打印之前!')}, // 开始打印之前的callbackopenCallback() {console.log('执行打印了!')}, // 调用打印时的callbackcloseCallback() { console.log('关闭了打印工具!') }, // 关闭打印的callback(无法区分确认or取消)clickMounted() {console.log('点击v-print绑定的按钮了')},
}

分页分为俩种情况
第一种:打印单据有2个以上,打印时需要自动分页打印,且每一页内容不超出一页(固定的数据)
单据内容的最外层的div设置样式page-break-before:always,即可在打印时自动分页

@media print {.section {page-break-before: always;/* 在每个部分之前始终开始新页面 */// margin: 20px 0; /* 为了使打印页面更清晰,可以添加一些上下间距 */margin-top: 0;}
}

第二种:打印单据有2个以上,打印时需要自动分页打印,内容连续且不固定,
如图所示打印 一行被截断 不满足需求
在这里插入图片描述
自动分页 : 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度,
当内容未超过pdf一页显示的范围,无需分页
通过class="paging"的容器进行分割,考虑到每张A4纸高度固定,所以通过判断每个class为paging的容器高度累加,大于纸张高度时,就给上一个class为paging的容器加上style=“page-break-pageBreakBefore:always”

// 动态计算 分页
const PAGE_HEIGHT = 1100 // A4纸高度
const printing = () => {const splitDoms = document.getElementsByClassName('paging')console.log(splitDoms)let startY = 0 // 占用A4纸的高度,从每页第一个poetry div的top值开始累加for (let i = 0; i < splitDoms.length; i++) {const splitDom = splitDoms[i]const splitValue = splitDom.getBoundingClientRect()console.log(splitDom.getBoundingClientRect())if (startY === 0) {startY = splitValue.top}const pageHeight = splitValue.bottom - startY// 当加上当前div的高度大于A4纸高度时,给前一个div加上分页标识if (pageHeight > PAGE_HEIGHT) {console.log(i)startY = 0if (i > 0) {splitDoms[i - 1].style.pageBreakBefore = 'always'; // 给前一个元素添加分页符}}}
}

动态计算后的分页展示
在这里插入图片描述

打印功能完整代码(安装好包,导入包后,可直接复制粘贴使用)

<template><div><a-button type="primary" style="margin-right: 10px;" @click="printing" v-print="printObj">打印</a-button><!-- <a-button type="primary" style="margin-right: 10px;" @click="downPdf">下载PDF</a-button> --></div><div style="overflow-y: auto;padding: 20px;"><div class="main" id="mypdf"><div class="title fd">客商评价明细表</div><div class="fd">供应商名称: <span>xxxxxxxxxxxxxxxxxxx</span> 编号:xxxxxxxxxxxxxxxxx</div><table border="1" class="techniques" style="margin-top: 1px;width: 100%;"><tr><td style="width: 130px;text-align: center;">拟开展业务</td><td colspan="3">xxxxxxxxxxxxxxxxxxxxxx</td><td class="tec" :colspan="5">评价明细情况</td></tr><tr><!-- <td style="width: 130px;text-align: center;">因素</td> --><td style="width: 130px;text-align: center;">主要指标</td><td style="width: 100px;text-align: center;">指标类型</td><td style="width: 150px;">评分标准</td><td style="width: 100px" class="tec">标准分数</td><td v-for="item in 5" class="tec">姓名{{ item }}</td></tr><tbody v-for="item in baseList" class="paging" style="height: 1px;"><tr><!-- <td style="width: 130px;text-align: center;">{{ item.factor }}</td> --><td style="width: 130px;text-align: center;">{{ item.factor }}</td><td style="width: 100px;text-align: center;">否决项</td><td>{{ item.scoringcriteria }}</td><td style="width: 100px;text-align: center;"><div style="display: flex;"><div style="display: flex; align-items: center;"><div class="tag"><!-- <check-outlined class="tagIcon" /> --></div><div></div></div><div style="display: flex; align-items: center;"><div class="tag"><!-- <check-outlined class="tagIcon" /> --></div><div></div></div></div></td><td v-for="item in item.peo" class="tec">{{ item }}</td></tr></tbody><tbody v-for="item in orditemLsit" :key="item.id" class="paging"><tr v-for="(val, index) in item.scoringcriteria" :key="val.id"><td style="width: 130px;text-align: center;" v-if="index === 0":rowspan="item.scoringcriteria.length">{{ item.factor }}</td><td style="width: 100px;text-align: center;" v-if="index === 0":rowspan="item.scoringcriteria.length">5</td><td style="width: 130px;">{{ val.title }}</td><td style="width: 100px;" class="tec">{{ val.score }}</td><template v-for="items in 5"><td class="tec" v-if="index === 0" :rowspan="item.scoringcriteria.length">{{ items }}</td></template></tr></tbody></table></div></div>
</template><script setup>let baseList = [{factor: '公司及董监高失信',mainindex: '公司及董监高是否被列为失信执行人员',score: '否决项',scoringcriteria: '公司及董监高被列为失信执行人员',standardScore: '',peo: 5},{factor: '成立年限',mainindex: '成立年限',score: '否决项',scoringcriteria: '公司成立年限小于3年',standardScore: '',peo: 5},{factor: '信用评价',mainindex: '第三方征信系统的评级',score: '否决项',scoringcriteria: '偿债能力预警(对应征信报告的第4级),如无第三方征信报告,则可从客商资产质量、资产负债率、营运管理、竞争力情况等方面进行综合评价,如资产质量较差,偿债能力较差,或存在大量诉讼案件或最近2年有重大行政处罚记录,需警惕',standardScore: '',peo: 5},{factor: '净资产',mainindex: '最新年度或半年度净资产',score: '否决项',scoringcriteria: '最新年度或半年度净资产总额小于500万元',standardScore: '',peo: 5},{factor: '业务范围',mainindex: '业务范围',score: '否决项',scoringcriteria: '有与公司同类自营贸易业务的民营企业',standardScore: '',peo: 5},{factor: '经营性现金净流量',mainindex: '经营性现金净流量',score: '否决项',scoringcriteria: '连续三年经营性现金净流量为负',standardScore: '',peo: 5},{factor: '所有者权益与实收资本关系',mainindex: '所有者权益与实收资本关系',score: '否决项',scoringcriteria: '所有者权益总额连续三年小于实收资本金额',standardScore: '',peo: 5},{factor: '境内供应商未提供最近三年审计报告',mainindex: '境内供应商未提供最近三年审计报告',score: '否决项',scoringcriteria: '境内供应商未提供最近三年审计报告',standardScore: '',peo: 5},
]let orditemLsit = [{factor: '成立年限',score: '5',scoringcriteria: [{title: '成立年限5年(含)以上',score: '5'},{title: '成立年限3年(含)至5年',score: '3'},{title: '成立年限3年(不含)以下',score: '1'},],standardScore: '',peo: 5},{factor: '实缴注册资本金',score: '5',scoringcriteria: [{title: '8000万元(含) 以上    ',score: '5'},{title: '4000万元(含) 至8000万元 ',score: '4'},{title: '1000万元(含) 至4000万元      ',score: '3'},{title: '1000万元(不含)以下至4000万元      ',score: '1'},],standardScore: '',peo: 5},{factor: '企业性质',score: '5',scoringcriteria: [{title: '国有A股上市,央企三级以上公司    以上    ',score: '5'},{title: '上市公司,省属大型国企',score: '4'},{title: '国有非上市',score: '3'},{title: '其它(非国企、非上市)',score: '1'},],standardScore: '',peo: 5},{factor: '企业性质',score: '5',scoringcriteria: [{title: '国有A股上市,央企三级以上公司    以上    ',score: '5'},{title: '上市公司,省属大型国企',score: '4'},{title: '国有非上市',score: '3'},{title: '其它(非国企、非上市)',score: '1'},],standardScore: '',peo: 5},{factor: '企业性质',score: '5',scoringcriteria: [{title: '国有A股上市,央企三级以上公司    以上    ',score: '5'},{title: '上市公司,省属大型国企',score: '4'},{title: '国有非上市',score: '3'},{title: '其它(非国企、非上市)',score: '1'},],standardScore: '',peo: 5},
]const printObj = {id: "mypdf", // 这里是要打印元素的IDpopTitle: "&nbsp", // 打印的标题extraCss: "", // 打印可引入外部的一个 css 文件extraHead: "", // 打印头部文字preview: false, // 是否启动预览模式,默认是falsepreviewTitle: '中铜国际贸易集团有限公司', // 打印预览的标题previewPrintBtnLabel: '预览结束,开始打印', // 打印预览的标题下方的按钮文本,点击可进入打印zIndex: 10002, // 预览窗口的z-index,默认是20002,最好比默认值更高previewBeforeOpenCallback() {console.log('正在加载预览窗口!')},previewOpenCallback() { console.log('已经加载完预览窗口,预览打开了!') }, // 预览窗口打开时的callbackbeforeOpenCallback() {console.log('开始打印之前!')}, // 开始打印之前的callbackopenCallback() {console.log('执行打印了!')}, // 调用打印时的callbackcloseCallback() { console.log('关闭了打印工具!') }, // 关闭打印的callback(无法区分确认or取消)clickMounted() {console.log('点击v-print绑定的按钮了')},
}const PAGE_HEIGHT = 1100 // A4纸高度
const printing = () => {const splitDoms = document.getElementsByClassName('paging')console.log(splitDoms)let startY = 0 // 占用A4纸的高度,从每页第一个poetry div的top值开始累加for (let i = 0; i < splitDoms.length; i++) {const splitDom = splitDoms[i]const splitValue = splitDom.getBoundingClientRect()console.log(splitDom.getBoundingClientRect())if (startY === 0) {startY = splitValue.top}const pageHeight = splitValue.bottom - startY// 当加上当前div的高度大于A4纸高度时,给前一个div加上分页标识if (pageHeight > PAGE_HEIGHT) {console.log(i)startY = 0if (i > 0) {splitDoms[i - 1].style.pageBreakBefore = 'always'; // 给前一个元素添加分页符}}}
}</script><style lang="scss" scoped>
.main {width: 900px;margin: 0 auto;
}.title {font-size: 19px;margin-bottom: 10px;line-height: 33px;text-align: center;
}.techniques {width: 100%;border-color: #000;font-family: "宋体", "SimSun", sans-serif;
}.techniques,
.techniques th,
.techniques td {border-collapse: collapse;line-height: 22px;font-size: 13px
}.fd {font-weight: bold;
}.tec {text-align: center;
}.tag {width: 14px;height: 14px;border-radius: 2px;text-align: center;color: #fff;border: 1px solid #333;font-weight: 700;// margin-left: 10px;// margin-right: -10px;margin: 0 5px;position: relative;.tagIcon {position: absolute;font-size: 12px;top: 1px;left: -20px;z-index: 111;color: #000;}
}@page {size: auto A4 landscape;margin-top: 20mm;
}@media print {.section {page-break-before: always;/* 在每个部分之前始终开始新页面 */// margin: 20px 0; /* 为了使打印页面更清晰,可以添加一些上下间距 */margin-top: 0;}
}
</style>

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Django】在vscode中新建Django应用并新增路由

文章目录 打开一个终端输入新建app命令在app下的views.py内写一个视图app路由引入该视图项目路由引入app路由项目(settings.py)引入app&#xff08;AntappConfig配置类&#xff09;运行项目 打开一个终端 输入新建app命令 python manage.py startapp antapp在app下的views.py内…

MySQL第一阶段:多表查询、事务

继续我的MySQL之旅&#xff0c;继续上篇的DDL、DML、DQL、以及一些约束&#xff0c;该到了多表查询和事务的学习总结&#xff0c;以及相关的案例实现&#xff0c;为未来的复习以及深入的理解做好知识储备。 目录 多表查询 连接查询 内连接 外连接 子查询 事务 事务简介…

为什么用LeSS?

实现适应性 LeSS是一个产品开发的组织系统&#xff0c;旨在最大化一个组织的适应性。关于适应性&#xff08;或者敏捷性&#xff0c;也就是敏捷开发的初衷&#xff09;我们是指优化&#xff1a; 以相对低的成本改变方向的能力&#xff0c;主要是基于通过频繁交付产生的探索。从…

pyuic5将ui文件转换为py文件报错:one input ui-file must be specified;no element found;

ERROR 1 文件命名不规范Solution 1:文件命名不能有空格 ERROR 2未选中ui文件 Solution 2:选中要转换成py 的文件

writing classes ... [xxx of xxxx] 执行时间太长

一、问题展示 二、解决方法 打开设置【File - Settings…】修改堆大小

使用vfbox网关实现modbus opc profinet iec61850等协议间的转换

在当今物联网&#xff08;IoT&#xff09;与工业自动化日益融合的时代背景下&#xff0c;协议转换网关作为连接不同设备与系统之间的桥梁&#xff0c;扮演着至关重要的角色。VFBox协议转换网关&#xff0c;作为这一领域内的佼佼者&#xff0c;以其高效、灵活、可靠的性能&#…

鸿蒙APP架构及开发入门

1.鸿蒙系统 1.1 什么是鸿蒙 鸿蒙是一款面向万物互联时代的、全新的分布式操作系统。 在传统的单设备系统能力基础上&#xff0c;鸿蒙提出了基于同一套系统能力、适配多种终端形态的分布式理念&#xff0c;能够支持手机、平板、智能穿戴、智慧屏、车机、PC、智能音箱、耳机、…

从代码层面熟悉UniAD,开始学习了解端到端整体架构

0. 简介 最近端到端已经是越来越火了&#xff0c;以UniAD为代表的很多工作不断地在不断刷新端到端的指标&#xff0c;比如最近SparseDrive又重新刷新了所有任务的指标。在端到端火热起来之前&#xff0c;成熟的模块化自动驾驶系统被分解为不同的独立任务&#xff0c;例如感知、…

【Django】网上蛋糕商城后台-商品管理

1.商品管理功能 当管理员点击商品管理时&#xff0c;发送服务器请求 path(admin/goods_list/, viewsAdmin.goods_list), # 处理商品列表请求 def goods_list(request):try:type request.GET["type"]except:type 0try:ym request.GET["ym"]except:ym …

基于微信小程序+SpringBoot+Vue的刷题系统(带1w+文档)

基于微信小程序SpringBootVue的刷题系统(带1w文档) 基于微信小程序SpringBootVue的刷题系统(带1w文档) 本系统是将网络技术和现代的管理理念相结合&#xff0c;根据试题信息的特点进行重新分配、整合形成动态的、分类明确的信息资源&#xff0c;实现了刷题的自动化&#xff0c;…

Springboot 多数据源事务

起因 在一个service方法上使用的事务,其中有方法是调用的多数据源orderDB 但是多数据源没有生效,而是使用的primaryDB 原因 spring 事务实现的方式 以 Transactional 注解为例 (也可以看 TransactionTemplate&#xff0c; 这个流程更简单一点)。 入口&#xff1a;ProxyTransa…

电商项目之如何判断线程池是否执行完所有任务

文章目录 1 问题背景2 前言3 4种常用的方法4 代码4.1 isTerminated()4.2 线程池的任务总数是否等于已执行的任务数4.3 CountDownLatch计数器4.4 CyclicBarrier计数器 1 问题背景 真实生产环境的电商项目&#xff0c;常使用线程池应用于执行大批量操作达到高性能的效果。应用场景…

基于Python的房产数据分析系统的设计与实现(源码+lw+部署文档+讲解等)

文章目录&#xff1a; 目录 详细视频演示 设计文档详细参考 技术开发的参考技术栈&#xff01; 2.1 Python语言 2.2 Django框架 2.3 MySQL 2.4 Hadoop介绍 2.5 Scrapy介绍 4.2 系统结构设计 4.3 数据库设计 界面设计与功能实现 5.1系统登录注册实现 5.2管理员模块…

[Meachines] [Easy] Admirer Adminer远程Mysql反向+Python三方库函数劫持权限提升

信息收集 IP AddressOpening Ports10.10.10.187TCP:21,22,80 $ nmap -p- 10.10.10.187 --min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 22/tcp open ssh OpenSSH 7.4p1 Debian 10deb9u7 (protocol 2.0) | ssh-hostkey: | …

Golang零基础入门课_20240726 课程笔记

视频课程 最近发现越来越多的公司在用Golang了&#xff0c;所以精心整理了一套视频教程给大家&#xff0c;这个只是其中的第一部&#xff0c;后续还会有很多。 视频已经录制完成&#xff0c;完整目录截图如下&#xff1a; 课程目录 01 第一个Go程序.mp402 定义变量.mp403 …

微信公众号获取用户openid(PHP版,snsapi_base模式)

微信公众号获取用户openid的接口有2个&#xff1a;snsapi_base、snsapi_userinfo 详情见微信公众号开发文档&#xff1a;https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html 本文介绍用PHP方式调用snsapi_base接口获取微信用户…

机器学习课程学习周报五

机器学习课程学习周报五 文章目录 机器学习课程学习周报五摘要Abstract一、机器学习部分1.1 向量序列作为模型输入1.1.1 文字的向量表达1.1.2 语音的向量表达 1.2 自注意力机制原理1.2.1 自注意力机制理论1.2.2 矩阵运算自注意力机制 1.3 多头自注意力1.4 位置编码1.5 截断自注…

什么是Socket、Socket在Java中的应用、Socket和SocketChannel区别

目录 什么是Socket TCP\IP UDP体系结构 Socket和TCP\IP的关系 Socket在Java中的应用 Socket和SocketChannel的区别 SocketChannel和Selector的关系 服务器的设计演化历程---多线程版 服务器的设计演化历程---线程池版 服务器的设计演化历程---Selector版 参考链接 什么…

Docker 搭建Elasticsearch详细步骤

本章教程使用Docker搭建Elasticsearch环境。 一、拉取镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:8.8.2二、运行容器 docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-n

【前端 14】Vue常见指令

Vue常见指令 Vue.js 是一个构建用户界面的渐进式框架&#xff0c;它通过一系列简洁的指令&#xff08;Directives&#xff09;来增强HTML的功能&#xff0c;使得开发者能够更加方便地构建出响应式的Web应用。本文将详细讲解Vue中的几个核心指令&#xff1a;v-bind、v-model、v…