一,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 = '<base href="'+window.location.origin+'" />',
styles = document.querySelectorAll('style,link')
for (var i = 0; i < styles.length; i++) {
if((styles[i].outerText && !styles[i].rel) || styles[i].rel){
str += styles[i].outerHTML
}
}
str +=
'<style>' +
(this.options.noPrint ? this.options.noPrint : '.no-print') +
'{display:none;}</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;'
// )
doc = f.contentDocument || f.contentWindow.document
doc.open()
doc.write(content)
doc.close()
w = f.contentWindow || f.contentDocument
var self = this
iframe.onload = function(){
self.toPrint(w)
setTimeout(function() {
document.body.removeChild(iframe)
}, 1000)
}
},
toPrint: function(frameWindow) {
try {
setTimeout(function() {
frameWindow.focus()
try {
if (!frameWindow.document.execCommand('print', false, null)) {
frameWindow.print()
}
} catch (e) {
frameWindow.print()
}
frameWindow.close()
}, 1000)
} 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
二,vue项目main.js中全局注册
import print from './plugins/print' // print plugins
window.Vue.use(print)
三(1), 页面中打印方法调用
举例:
printSignTable() {
const list = deepClone(this.dataList)
const printHtm = document.createElement('div')
new Array(Math.ceil(list.length / this.pageMaxNum)).join().split(',').forEach((s, i) => {
printHtm.appendChild(this.createTable(list.slice(i * this.pageMaxNum, (i + 1) * this.pageMaxNum), i * this.pageMaxNum))
})
const { totalTimes } = this.classInfo
const styles = `<style>
*{ margin: 0; padding: 0;}
ul,li{ list-style: none; box-sizing: border-box;}
@page{
size: A4 ${totalTimes > this.timesMaxNum ? 'landscape' : 'portrait'};
}
.title{
text-align: center;
font-size: 14px;
position: relative;
margin: 0px auto 2px;
padding-top: ${totalTimes > this.timesMaxNum ? '20px' : '30px'};
}
</style>`
printHtm.innerHTML += styles
this.$print(printHtm)
}
三(2),调用组件页面发起打印
PrintRefundAudit组件页面
<template>
<div class="print-refund-audit-box">
<div v-for="item in printTimes" :key="item" class="item-box">
<div class="form-title">退费申请表</div>
<div :class="studentInfo.bankName && studentInfo.bankName.length > 17 ? 'student-info more-text':'student-info'">
<div>
<div>校区</div>
<div>{{ studentInfo.campusName }}</div>
<div>退费ID</div>
<div>{{ studentInfo.refundRecordNo }}</div>
<div>申请日期</div>
<div>{{ studentInfo.applyTime | parseTime('y年m月d日') }}</div>
</div>
<div>
<div>学员姓名</div>
<div>{{ studentInfo.studentName }}</div>
<div>家长姓名</div>
<div/>
<div>联系电话</div>
<div>{{ studentInfo.studentPhone }}</div>
</div>
<div>
<div>开户姓名</div>
<div>{{ studentInfo.bankCardPayee }}</div>
<div>银行卡号</div>
<div>{{ studentInfo.bankcardNo }}</div>
<div>开户行</div>
<div>{{ studentInfo.bankName }}</div>
</div>
</div>
<div class="class-table">
<el-table :data="classInfo">
<el-table-column
width="195"
prop="className"
label="班级名称"
/>
<el-table-column
width="45"
prop="subjectLabel"
label="学科名称"
/>
<el-table-column
width="45"
prop="season"
label="退费期别"
/>
<el-table-column
:formatter="(row) => row.payAttendCount ? (row.payAttendCount + '/' +row.haveAttendNumber + '/' +row.refundAttendNumber) : null"
width="80"
label="支付/已上/退费课次"
/>
<el-table-column
width="65"
prop="paymentSinglePrice"
label="单价"
/>
<el-table-column
width="145"
prop="paymentNo"
label="支付ID"
/>
<el-table-column
width="80"
prop="extraRefundAmount"
label="额外退费"
/>
<el-table-column
width="80"
prop="classRefundAmount"
label="退费金额"
/>
</el-table>
</div>
</div>
<div class="total-amount">
<div class="left">
<div>
<div>退费原因</div>
<div>{{ studentInfo.refundReason }}</div>
</div>
<div>
<div>经办人</div>
<div>{{ studentInfo.applierName }}</div>
</div>
</div>
<div class="right">
<div>
<div>课程退费</div>
<div class="price">¥{{ parseFloat(courseRefund).toFixed(2) }}</div>
</div>
<div>
<div>其他退费</div>
<div class="price">¥{{ parseFloat(otherRefund).toFixed(2) }}</div>
</div>
<div class="bold">
<div>退费合计</div>
<div class="price">¥{{ parseFloat(totalRefund).toFixed(2) }}</div>
</div>
<div class="bold">
<div>家长确认签字</div>
</div>
</div>
</div>
<div class="footer">{{ item === 1 ? '第一联 家长联': '第二联 存根联' }}</div>
</div>
</div>
</template>
<script>
import logo from '@/assets/images/gray-logo.png'
export default {
name: 'PrintRefundAudit',
props: {
printList: {
type: Object,
default: () => {}
}
},
data() {
return {
printTimes: [1, 2],
classInfo: [],
studentInfo: {},
totalRefund: 0,
courseRefund: 0,
otherRefund: 0,
openopen: '',
url: logo
}
},
watch: {
classInfo(val) {
if (val.length < 10) {
this.classInfo.push({ className: '' })
}
},
printList(val) {
this.classInfo = val.refundOrderForPrint
const { studentName, applyTime, bankName, bankcardNo, bankCardPayee, refundRecordNo, studentPhone, campusName, refundReason, applierName, remitAmount, otherRefundAmount, classRefundAmount } = val
this.totalRefund = remitAmount
this.courseRefund = classRefundAmount
this.otherRefund = otherRefundAmount
this.studentInfo = { studentName, applyTime, bankName, bankcardNo, bankCardPayee, refundRecordNo, studentPhone, campusName, refundReason, applierName }
}
},
created() {
}
}
</script>
<style lang="scss" scoped>
</style>
父组件调用打印子组件
<print-refundAudit
ref="PrintRefundAudit"
:print-list="printRefundAuditList"
/>
import PrintRefundAudit from '@/components/Print/PrintRefundAudit'
export default {
components: {
PrintRefundAudit
},
父组件方法调用
<el-button
type="text"
@click="printRefundForm(row.id)"
>打印</el-button>
<el-button
:disabled="!multipleSelection.length"
type="primary"
@click="printRefundForm('')"
>批量打印</el-button>
printRefundForm(id) {
let ids = ''
if (id) {
ids = id
} else {
ids = this.multipleSelection.map(item => item.id).join(',')
}
findBigRefundOrderListForPrint({ ids: ids }).then(res => {
this.printRefundAuditList = res.data.printInfo
this.$nextTick(() => {
this.$print(this.$refs['PrintRefundAudit'])
})
})
},