当前位置: 首页 > news >正文

vue 打印、自定义打印、页面打印、隐藏页眉页脚

        花了一天时间搞了个打印功能,现则将整体实现过程进行整理分享。先来看看效果图:

1、页面展示为:

2、重组页面打印格式为:这里重组页面的原因是客户要求为一行两列打印 !内容过于多的行则独占一行显示完整。

 整体实现:

在你的项目的components目录下创建如下目录及文件:

 将以下代码粘贴到这个print.js文件中:

// 打印类属性、方法定义
/* eslint-disable */
const Print = function (dom, options) {if (!(this instanceof Print)) return new Print(dom, options);this.options = this.extend({'noPrint': '.no-print'}, options);if ((typeof dom) === "string") {this.dom = document.querySelector(dom);} else {this.isDOM(dom)this.dom = this.isDOM(dom) ? dom : dom.$el;}this.init();
};
Print.prototype = {init: function () {var content = this.getStyle() + this.getHtml();this.writeIframe(content);},extend: function (obj, obj2) {for (var k in obj2) {obj[k] = obj2[k];}return obj;},getStyle: function () {var str = "",styles = document.querySelectorAll('style,link');for (var i = 0; i < styles.length; i++) {str += styles[i].outerHTML;}str += "<style>" + (this.options.noPrint ? this.options.noPrint : '.no-print') + "{display:none;}</style>";// str += "<style>html,body,div{height: auto!important;font-size:14px}</style>";return str;},getHtml: function () {var inputs = document.querySelectorAll('input');var textareas = document.querySelectorAll('textarea');var selects = document.querySelectorAll('select');for (var k = 0; k < inputs.length; k++) {if (inputs[k].type == "checkbox" || inputs[k].type == "radio") {if (inputs[k].checked == true) {inputs[k].setAttribute('checked', "checked")} else {inputs[k].removeAttribute('checked')}} else if (inputs[k].type == "text") {inputs[k].setAttribute('value', inputs[k].value)} else {inputs[k].setAttribute('value', inputs[k].value)}}for (var k2 = 0; k2 < textareas.length; k2++) {if (textareas[k2].type == 'textarea') {textareas[k2].innerHTML = textareas[k2].value}}for (var k3 = 0; k3 < selects.length; k3++) {if (selects[k3].type == 'select-one') {var child = selects[k3].children;for (var i in child) {if (child[i].tagName == 'OPTION') {if (child[i].selected == true) {child[i].setAttribute('selected', "selected")} else {child[i].removeAttribute('selected')}}}}}return this.dom.outerHTML;},writeIframe: function (content) {var w, doc, iframe = document.createElement('iframe'),f = document.body.appendChild(iframe);iframe.id = "myIframe";//iframe.style = "position:absolute;width:0;height:0;top:-10px;left:-10px;";iframe.setAttribute('style', 'position:absolute;width:0;height:0;top:-10px;left:-10px;');w = f.contentWindow || f.contentDocument;doc = f.contentDocument || f.contentWindow.document;doc.open();doc.write(content);doc.close();var _this = thisiframe.onload = function () {_this.toPrint(w);setTimeout(function () {document.body.removeChild(iframe)}, 100)}},toPrint: function (frameWindow) {try {setTimeout(function () {frameWindow.focus();try {if (!frameWindow.document.execCommand('print', false, null)) {frameWindow.print();}} catch (e) {frameWindow.print();}frameWindow.close();}, 10);} catch (err) {console.log('err', err);}},isDOM: (typeof HTMLElement === 'object') ?function (obj) {return obj instanceof HTMLElement;} :function (obj) {return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string';}
};
const MyPlugin = {}
MyPlugin.install = function (Vue, options) {// 4. 添加实例方法Vue.prototype.$print = Print
}
export default MyPlugin

 在views目录下创建重组页面,即要实现的打印页面。目录及页面文件如下:

粘贴以下代码进入index.vue组件中:注意阅读并分析这里面的实现,预留功能为一行N列实现,栅格布局计算!

<template><el-dialog :title="title" :visible.sync="visible" width="148mm" :before-close="handleClose" center append-to-body><div class="w-100 h-100"><div class="w-100" ref="print"><div class="header-view w-100"><div class="title-view w-100 single-line">{{ printData.title }}</div></div><div class="w-100 body-view"><div class="print-section" v-for="(item, tindex) in printData.data" :key="item"><div class="section-view">{{ item.title }}</div><el-row class="row-view bd-right" v-for="(a, aindex) in item.child" :key="a":class="{ 'bd-top': aindex == 0 }"><el-col :span="rowSpan" v-for="(p, index) in a.child" class="col-view flex-row":class="{ 'bd-left': index == 0 }"><div class="main-lb cell-view":class="[index > 0 ? 'bd-left' : '', `lb_${tindex}_${aindex}_${index}`]">{{ p.label| textFilter}}</div><div class="value-lb cell-view":class="[p.singLine ? 'value-pre' : '', `vlb_${tindex}_${aindex}_${index}`]">{{p.value}}</div></el-col></el-row><el-row class="row-view bd-right"><el-col :span="12" class="col-view flex-row bd-left"><div class="main-lb cell-view">备注</div><div class="value-lb cell-view" style="height: 50px;"></div></el-col></el-row></div></div></div></div><div slot="footer" class="w-100 flex-row no-print" style="height: 44px;"><el-button class="el-icon-printer" type="primary" @click="handlePrint">打印</el-button></div></el-dialog>
</template>
<script>export default{name: 'pagePrinter',components: {},data() {return {visible: false,inMobile: false,printData: {'title': '','titleClass': null,'subTitle': '','subTitleClass': null,'data': []},rowSpan: 12}},props:{title: {type: String,default: () => null},//是否随机项目printMap: {type: Object,default: () => {return {'title': '','titleClass': null,'subTitle': '','subTitleClass': null,'data': []}}},},watch: {printMap: {deep: true,handler(val) {if (val) {this.updatePrintData()}}},},created() {},filters: {textFilter(val) {let v = val.replace(/:/g, '');return v}},methods: {handleClose() {this.visible = false;this.$emit('update:visible', false)this.$emit('close', {})},updatePrintData() {this.inMobile = this.isMobile()let m = {'title': this.printMap.title,'titleClass': this.printMap.titleClass,'subTitle': this.printMap.subTitle,'subTitleClass': this.printMap.subTitleClass,'data': this.printMap.data}let dataList = []let col = 24 / this.rowSpanthis.printMap.data.forEach(e => {let ae = {title: e.title,child: []}let list = []e.child?.forEach((c, cdex) => {c.span = this.rowSpanlist.push(c)if (list.length % col == 0 || cdex == e.child.length - 1 || c.singLine) {if (c.singLine) {list.forEach(n => {n.singLine = truelet cx = {child: [n]}ae.child.push(cx)})}else {let cx = {child: list}ae.child.push(cx)}list = []}});dataList.push(ae)});m.data = dataListthis.printData = mthis.visible = truethis.$nextTick(() => {dataList.forEach((a, aindex) => {a.child.forEach((b, bindex) => {let maxHeight = 0b.child.forEach((c, cindex) => {let csName = `.lb_${aindex}_${bindex}_${cindex}`let atarget = document.querySelector(csName)let aht = atarget.offsetHeightlet bsName = `.vlb_${aindex}_${bindex}_${cindex}`let btarget = document.querySelector(bsName)let bht = btarget.offsetHeightmaxHeight = Math.max(maxHeight, Math.max(aht, bht))atarget.style.height = maxHeight + 'px';btarget.style.height = maxHeight + 'px';});b.child.forEach((c, cindex) => {let csName = `.lb_${aindex}_${bindex}_${cindex}`let atarget = document.querySelector(csName)let bsName = `.vlb_${aindex}_${bindex}_${cindex}`let btarget = document.querySelector(bsName)atarget.style.height = maxHeight + 'px';btarget.style.height = maxHeight + 'px';});});})})},handlePrint() {this.$print(this.$refs.print);},}}
</script><style lang="scss" scoped>
.header-view {width: 100%;padding: 10px 0px;//border-bottom: 1px solid #ccc;
}.section-view {font-size: 12px;text-align: left;color: #333;margin-left: 10px;padding-bottom: 5px;
}.title-view {font-size: 18px;text-align: center;color: black;
}.cnt-view {height: calc(100% - 44px);
}.body-view {height: calc(100% - 64px);
}.bd-left {border-left: 1px solid #ccc;
}.bd-right {border-right: 1px solid #ccc;
}.bd-top {border-top: 1px solid #ccc;
}.row-view {border-bottom: 1px solid #ccc;
}.flex-row {display: flex;flex-direction: row;justify-content: center;align-items: center;
}.cell-view {//min-height: 38px;display: flex;flex-direction: row;justify-content: flex-start;align-items: center;
}.main-lb {font-size: 10px;color: #444;width: 40%;font-weight: 500;padding-left: 5px;//border-right: 1px solid #ccc;
}.value-lb {font-size: 11px;color: black;width: 60%;border-left: 1px solid #ccc;white-space: pre-line;word-break: break-all;padding: 4px 10px;
}.value-pre {white-space: pre;
}::v-deep {.el-dialog {width: 100%;//height: 100%;}.el-dialog__body {height: 100%;padding: 10px 20px;}.el-dialog--center {margin-top: 30px !important;margin-bottom: 30px !important;}.el-divider--horizontal {margin: 0;}.is-horizontal {height: 0px;display: none;}.el-scrollbar__wrap {overflow-x: hidden;}
}//隐藏页眉页脚
@media print {body {margin: 0;padding: 0;}@page {margin: 0 10px;}header,footer {display: none;}
}
</style>

隐藏页眉页脚: 

//隐藏页眉页脚
@media print {body {margin: 0;padding: 0;}@page {margin: 0 10px;}header,footer {display: none;}
}

 在使用打印功能的父组件页面中引入上述子组件;

 

组装数据格式为,传到打印页面,最终打印页面会计算布局,根据一行显示多少列来遍历child进行布局后显示打印页面。

singLine意即为是否独占一行打印显示,封装数据后传入组件内部会根据预设来布局显示完成打印预览及打印功能。

[{"title": "起搏器工作情况:","child": [{"label": "植入型号:","value": "MDT-SEDRL1","singLine": false},{"label": "随访时间","value": "2024-05-23 11:26:41","singLine": false},{"label": "模式","value": "DDDR","singLine": false},{"label": "基础频率:","value": "60(bpm)","singLine": false},{"label": "最大跟踪频率:","value": "130(bpm)","singLine": false},{"label": "更多频率:","value": "否","singLine": false},{"label": "心房阈值:","value": "0.5(V)","singLine": false},{"label": "心房脉宽:","value": "0.4(ms)","singLine": false},{"label": "心房输出电压:","value": "1.5(V)","singLine": false},{"label": "心房电极阻抗","value": "738(Ω)","singLine": false},{"label": "心房感知:","value": ">2.8(mV)","singLine": false},{"label": "心房起搏比例:","value": "74.8(%)","singLine": false},{"label": "右室阈值:","value": "0.625(V)","singLine": false},{"label": "右室脉宽:","value": "0.4(ms)","singLine": false},{"label": "右室输出电压:","value": "2.0(V)","singLine": false},{"label": "右室电极阻抗:","value": "385(Ω)","singLine": false},{"label": "右室感知:","value": "5.6-8.0(mV)","singLine": false},{"label": "右室起搏比例:","value": "2.5(%)","singLine": false},{"label": "PAV间期:","value": "150/120-320/290(ms)","singLine": false},{"label": "起搏器预计使用年限:","value": "10","singLine": false},{"label": "电池电压:","value": "2.79(V)","singLine": false},{"label": "磁铁频率:","value": "100","singLine": false},{"label": "电池阻抗:","value": "181(Ω)","singLine": false},{"label": "ICD/CRTD选项:","value": "否","singLine": false},{"label": "CRT选项","value": "否","singLine": false},{"label": "是否有心律失常:","value": "是","singLine": false},{"label": "何种心律失常:","value": "室性心动过速、房性心动过速","singLine": false},{"label": "心律失常信息:","value": "2023-04-18  VHR A/V:116/180bpm  1  3S  /;\\n2023-06-30  AHR  A/V:191/128bpm  1  14min54s  /;\\n","singLine": true},{"label": "是否放电:","value": "否","singLine": false},{"label": "其他情况登记:","value": "2 VHR 3S 2023.4.18;2024.1.17 \\n86 AHR 37S-1h13min36s  2023.6.26-2023.7.6 ","singLine": false}]}
]

相关文章:

  • kotlin基础之协程
  • 【5.基础知识和程序编译及调试】
  • 第十三章 进程与线程
  • 探秘URL的奥义:JavaScript中轻松获取页面参数值的N种姿势【含代码示例】
  • 基于文本来推荐相似酒店
  • 最新文章合集
  • 前端加密的方式汇总
  • 【OpenCV 基础知识 13】高斯平滑处理图像
  • vue实现页面渲染时候执行某需求
  • Vue 前端加框 给div加红色框框 js实现
  • 【PB案例学习笔记】-12秒表实现
  • 【PostgreSQL17新特性之-事务级别超时参数transaction_timeout】
  • 虚拟机改IP地址
  • NIFT和BMP批量互相转换(matlab)
  • 【数据结构:排序算法】堆排序(图文详解)
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • css属性的继承、初识值、计算值、当前值、应用值
  • Git的一些常用操作
  • Joomla 2.x, 3.x useful code cheatsheet
  • JWT究竟是什么呢?
  • node入门
  • Python 基础起步 (十) 什么叫函数?
  • 关于List、List?、ListObject的区别
  • 技术发展面试
  • 前端技术周刊 2019-02-11 Serverless
  • 区块链技术特点之去中心化特性
  • 温故知新之javascript面向对象
  • 7行Python代码的人脸识别
  • ​​​【收录 Hello 算法】9.4 小结
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #vue3 实现前端下载excel文件模板功能
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • (02)Hive SQL编译成MapReduce任务的过程
  • (6)添加vue-cookie
  • (CVPRW,2024)可学习的提示:遥感领域小样本语义分割
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (补充)IDEA项目结构
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (回溯) LeetCode 131. 分割回文串
  • (理论篇)httpmoudle和httphandler一览
  • (转)Oracle 9i 数据库设计指引全集(1)
  • (转)visual stdio 书签功能介绍
  • (转)负载均衡,回话保持,cookie
  • .gitignore不生效的解决方案
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • .one4-V-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • .xml 下拉列表_RecyclerView嵌套recyclerview实现二级下拉列表,包含自定义IOS对话框...
  • [Android] 修改设备访问权限