0


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”

// 动态计算 分页constPAGE_HEIGHT=1100// A4纸高度constprinting=()=>{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绑定的按钮了')},}constPAGE_HEIGHT=1100// A4纸高度constprinting=()=>{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>
标签: pdf vue.js 前端

本文转载自: https://blog.csdn.net/weixin_45653441/article/details/140710543
版权归原作者 故事与九 所有, 如有侵权,请联系我们删除。

“vue3-print-nb实现打印pdf分页”的评论:

还没有评论