window.print()实现局部打印及遇到的问题
公司的一个后台管理系统需要实现打印一个签收单,我选择用window.print()实现打印,但是遇到了一些问题;需求实现的效果:
打印时需要隐藏顶部的按钮,只打印中间的签收单,我们这个项目是vue+elementui实现,原本这个表单是用element组建件实现的,但是打印时会出现各种样式乱掉的问题,最后我放弃了组件自己写样式;
原本代码
<template>
<div
class="download-receipt"
>
<el-button
class="download-receipt__print"
type="primary"
size="mini"
@click="goBack"
>
返回
</el-button>
<el-button
class="download-receipt__print"
type="primary"
size="mini"
@click="print"
>
打印签收单
</el-button>
<div
id="print"
class="download-receipt__content"
>
<h2 class="download-receipt__title">
卡册领用签收单
</h2>
<h3>基础信息</h3>
<div
class="download-receipt__line"
style="height: auto;"
>
<p
class="download-receipt__lable"
style="width: 149px;display: flex;align-items: center;justify-content: flex-start;"
>
申请单编号
</p>
<div
style="width: 448px;height: auto;word-break: break-all;display: flex;align-items: center;justify-content: flex-start;padding: 10px;"
>
{{ cardookReceiptData.sysNo }}
</div>
</div>
<div
class="download-receipt__line"
style="height: auto;"
>
<p
class="download-receipt__lable"
style="width: 149px;display: flex;align-items: center;justify-content: flex-start;"
>
客户名称
</p>
<div
style="width: 448px;height: auto;word-break: break-all;display: flex;align-items: center;justify-content: flex-start;padding: 10px;"
>
{{ cardookReceiptData.bigCustomerName }}
</div>
</div>
<div class="download-receipt__line">
<div class="download-receipt__line--item">
<p
class="download-receipt__lable"
style="width: 149px;"
>
申请日期
</p>
<span
class="download-receipt__value"
style="width: 148.5px;"
>
{{ cardookReceiptData.applyDate }}
</span>
</div>
<div class="download-receipt__line--item">
<p
class="download-receipt__lable"
style="border-left: 1px solid #000;width: 149px;"
>
购买用途
</p>
<span
class="download-receipt__value"
style="width: 148.5px;"
>
{{ cardookReceiptData.purchasePurposeTypeName }}
</span>
</div>
</div>
<div class="download-receipt__line">
<div class="download-receipt__line--item">
<p
class="download-receipt__lable"
style="width: 149px;"
>
联系人
</p>
<span
class="download-receipt__value"
style="width: 148.5px;"
>
{{ cardookReceiptData.contactsName }}
</span>
</div>
<div class="download-receipt__line--item">
<p
class="download-receipt__lable"
style="border-left: 1px solid #000;width: 149px;"
>
联系电话
</p>
<span
class="download-receipt__value"
style="width: 148.5px;"
>
{{ cardookReceiptData.contactsPhone }}
</span>
</div>
</div>
<div class="download-receipt__line">
<p
class="download-receipt__lable"
style="width: 149px;"
>
收货地址
</p>
<div
style="width: 448px;height: auto;word-break: break-all;display: flex;align-items: center;justify-content: flex-start;padding: 10px;"
>
{{ cardookReceiptData.address }}
</div>
</div>
<div
class="download-receipt__line"
style="border-bottom: 1px solid #000;height: auto;"
>
<p
class="download-receipt__lable"
style="width: 149px;display: flex;align-items: center;justify-content: flex-start;"
>
单据编号
</p>
<div
style="width: 448px;height: auto;word-break: break-all;display: flex;align-items: center;justify-content: flex-start;padding: 10px;"
>
{{ cardookReceiptData.jiCaiSysNo }}
</div>
</div>
<h3>卡册信息</h3>
<div class="download-receipt__table">
<div class="download-receipt__table--head">
<p
class="download-receipt__table--item"
>
卡册名称
</p>
<p
class="download-receipt__table--item"
>
价位
</p>
<p
class="download-receipt__table--item"
>
折扣
</p>
<p
class="download-receipt__table--item"
>
数量
</p>
<p
class="download-receipt__table--item"
>
合计金额
</p>
<p
class="download-receipt__table--item download-receipt__table--item__last"
>
卡册号段
</p>
</div>
<div
v-for="(applyCard, index) in applyCardItems"
:key="index"
class="download-receipt__table--body"
>
<p
class="download-receipt__table--item"
style="border-right: 1px solid #000;border-bottom: 1px solid #000;"
>
{{ applyCard.cardName }}
</p>
<p
class="download-receipt__table--item"
style="border-right: 1px solid #000;border-bottom: 1px solid #000;"
>
{{ applyCard.cardPrice }}
</p>
<p
class="download-receipt__table--item"
style="border-right: 1px solid #000;border-bottom: 1px solid #000;"
>
{{ applyCard.discount }}
</p>
<p
class="download-receipt__table--item"
style="border-right: 1px solid #000;border-bottom: 1px solid #000;"
>
{{ applyCard.quantity }}
</p>
<p
class="download-receipt__table--item"
style="border-right: 1px solid #000;border-bottom: 1px solid #000;"
>
{{ applyCard.totalAmount }}
</p>
<p
class="download-receipt__table--item download-receipt__table--item__last"
style="border-right: 1px solid #000;border-bottom: 1px solid #000;"
>
{{ applyCard.cardNumberSegment }}
</p>
</div>
</div>
<div
class="download-receipt__line"
style="border-bottom: 1px solid #000;height: auto;border-top: none;"
>
<p
class="download-receipt__lable"
style="width: 158px;display: flex;align-items: center;justify-content: flex-start;"
>
总金额(数字)
</p>
<div
style="width: 441px;height: auto;word-break: break-all;display: flex;align-items: center;justify-content: flex-start;padding: 10px;"
>
{{ cardookReceiptData.totalAmount }}
</div>
</div>
<div
class="download-receipt__line"
style="border-bottom: 1px solid #000;height: auto;border-top: none;"
>
<p
class="download-receipt__lable"
style="width: 158px;display: flex;align-items: center;justify-content: flex-start;"
>
总金额(大写)
</p>
<div
style="width: 441px;height: auto;word-break: break-all;display: flex;align-items: center;justify-content: flex-start;padding: 10px;"
>
{{ cardookReceiptData.totalAmountByChinese }}
</div>
</div>
<h3>注意事项</h3>
<h5 class="download-receipt__tips">
领用人需承诺将领用的卡册如数安全交付给客户,一旦领用,后期如出现任何问题,由领用者个人承担责任。
</h5>
<div
class="download-receipt__line"
style="border-bottom: 1px solid #000;"
>
<div class="download-receipt__line--item">
<p class="download-receipt__lable">
领用人签字
</p>
<span class="download-receipt__value" />
</div>
<div class="download-receipt__line--item">
<p
class="download-receipt__lable"
style="border-left: 1px solid #000;"
>
收货人签字
</p>
<span class="download-receipt__value" />
</div>
</div>
</div>
</div>
</template>
<script lang='ts'>
import { Component, Vue, Prop, Watch, Provide } from 'vue-property-decorator'
import { fetchContractDetail } from '@/api/cardBookOnline'
@Component({
name: 'downloadreceipt'
})
export default class extends Vue {
@Prop({ default: 0 }) private cardBookSysNo!: number
private cardookReceiptData: any = {}
get applyCardItems() {
return this.cardookReceiptData.applyCardItems || []
}
private async created() {
const { id } = this.$route.query
const res = await fetchContractDetail({ cardApplySysNo: Number(id) })
this.cardookReceiptData = res.data.data || {}
}
// 打印前把原本的body页面保留下来,等打印后再重新复值过去,打印的内容去#print的innerHTML,虽然打印之后把body的内容还原了,但是页面的点击事件都无效了,需要刷新页面还原;
private print() {
const print: any = document.getElementById('print') || {}
const bdhtml = window.document.body.innerHTML
const printHtml = print.innerHTML
window.document.body.innerHTML = printHtml
window.print()
window.document.body.innerHTML = bdhtml
window.location.reload()
}
private goBack() {
this.$router.back()
}
}
</script>
<style>
p {
margin: 0;
padding: 0;
}
.el-dialog {
width: 680px;
}
.download-receipt__content {
width: 600px;
margin: 0 auto;
}
.download-receipt__print {
margin: 10px;
}
.download-receipt__line {
width: 600px;
display: flex;
height: 50px;
border-top: 1px solid #000;
border-left: 1px solid #000;
border-right: 1px solid #000;
}
.download-receipt__line--item {
display: flex;
}
.download-receipt__lable {
margin: 0;
padding: 0;
font-weight: 600;
color: #000;
width: 150px;
line-height: 50px;
background: #dfe6ec;
padding: 0 10px;
border-right: 1px solid #000;
}
.download-receipt__value {
width: 150px;
line-height: 50px;
padding: 0 10px;
}
.download-receipt__table {
width: 600px;
border-top: 1px solid #000;
border-left: 1px solid #000;
}
.download-receipt__table--head {
display: flex;
}
.download-receipt__table--body {
display: flex;
}
.download-receipt__table--item {
width: 79px;
min-height: 50px;
display: flex;
align-items: center;
justify-content: center;
word-break: break-all;
}
.download-receipt__table--head .download-receipt__table--item {
border-right: 1px solid #000;
border-bottom: 1px solid #000;
font-weight: 600;
}
.download-receipt__table--item__last {
padding: 5px;
width: 204px;
}
.download-receipt__title {
width: 600px;
text-align: center;
}
.download-receipt__tips {
width: 600px;
word-wrap: break-word;
}
</style>
局部打印的功能虽然实现了,但是打印的时候会出现打印两页的情况,第二页是一个空白页;
一直找不到原因,查阅了很多资料,说是如果打印元素的第一个子元素是h1~h5标签会出现打印两页,第二页空白的情况,然后就对现在的代码进行了一些修改,在#print元素里加了一个div包裹里面的子元素,又把第一个h2元素换成了div;
修改后的代码
<template>
<div
class="download-receipt"
>
<el-button
class="download-receipt__print"
type="primary"
size="mini"
@click="goBack"
>
返回
</el-button>
<el-button
class="download-receipt__print"
type="primary"
size="mini"
@click="print"
>
打印签收单
</el-button>
<div
id="print"
class="download-receipt__content"
>
<div id="print_body">
<div class="download-receipt__title">
卡册领用签收单
</div>
<h3>基础信息</h3>
<div
class="download-receipt__line"
style="height: auto;"
>
<p
class="download-receipt__lable download-receipt__flex"
style="width: 149px;"
>
申请单编号
</p>
<div
class="download-receipt__flex download-receipt__break"
style="width: 448px;"
>
{{ cardookReceiptData.sysNo }}
</div>
</div>
<div
class="download-receipt__line"
style="height: auto;"
>
<p
class="download-receipt__lable download-receipt__flex"
style="width: 149px;"
>
客户名称
</p>
<div
class="download-receipt__break"
style="width: 448px;"
>
{{ cardookReceiptData.bigCustomerName }}
</div>
</div>
<div class="download-receipt__line">
<div class="download-receipt__line--item">
<p
class="download-receipt__lable"
style="width: 149px;"
>
申请日期
</p>
<span
class="download-receipt__value"
style="width: 148.5px;"
>
{{ cardookReceiptData.applyDate }}
</span>
</div>
<div class="download-receipt__line--item">
<p
class="download-receipt__lable"
style="border-left: 1px solid #000;width: 149px;"
>
购买用途
</p>
<span
class="download-receipt__value"
style="width: 148.5px;"
>
{{ cardookReceiptData.purchasePurposeTypeName }}
</span>
</div>
</div>
<div class="download-receipt__line">
<div class="download-receipt__line--item">
<p
class="download-receipt__lable"
style="width: 149px;"
>
联系人
</p>
<span
class="download-receipt__value"
style="width: 148.5px;"
>
{{ cardookReceiptData.contactsName }}
</span>
</div>
<div class="download-receipt__line--item">
<p
class="download-receipt__lable"
style="border-left: 1px solid #000;width: 149px;"
>
联系电话
</p>
<span
class="download-receipt__value"
style="width: 148.5px;"
>
{{ cardookReceiptData.contactsPhone }}
</span>
</div>
</div>
<div class="download-receipt__line">
<p
class="download-receipt__lable"
style="width: 149px;"
>
收货地址
</p>
<div
class="download-receipt__flex download-receipt__break"
style="width: 448px;"
>
{{ cardookReceiptData.address }}
</div>
</div>
<div
class="download-receipt__line"
style="border-bottom: 1px solid #000;height: auto;"
>
<p
class="download-receipt__lable download-receipt__flex"
style="width: 149px;"
>
单据编号
</p>
<div
class="download-receipt__flex download-receipt__break"
style="width: 448px;"
>
{{ cardookReceiptData.jiCaiSysNo }}
</div>
</div>
<h3>卡册信息</h3>
<div class="download-receipt__table">
<div class="download-receipt__table--head">
<p
class="download-receipt__table--item"
>
卡册名称
</p>
<p
class="download-receipt__table--item"
>
价位
</p>
<p
class="download-receipt__table--item"
>
折扣
</p>
<p
class="download-receipt__table--item"
>
数量
</p>
<p
class="download-receipt__table--item"
>
合计金额
</p>
<p
class="download-receipt__table--item download-receipt__table--item__last"
>
卡册号段
</p>
</div>
<div
v-for="(applyCard, index) in applyCardItems"
:key="index"
class="download-receipt__table--body"
>
<p
class="download-receipt__table--item"
style="border-right: 1px solid #000;border-bottom: 1px solid #000;"
>
{{ applyCard.cardName }}
</p>
<p
class="download-receipt__table--item"
style="border-right: 1px solid #000;border-bottom: 1px solid #000;"
>
{{ applyCard.cardPrice }}
</p>
<p
class="download-receipt__table--item"
style="border-right: 1px solid #000;border-bottom: 1px solid #000;"
>
{{ applyCard.discount }}
</p>
<p
class="download-receipt__table--item"
style="border-right: 1px solid #000;border-bottom: 1px solid #000;"
>
{{ applyCard.quantity }}
</p>
<p
class="download-receipt__table--item"
style="border-right: 1px solid #000;border-bottom: 1px solid #000;"
>
{{ applyCard.totalAmount }}
</p>
<p
class="download-receipt__table--item download-receipt__table--item__last"
style="border-right: 1px solid #000;border-bottom: 1px solid #000;"
>
{{ applyCard.cardNumberSegment }}
</p>
</div>
</div>
<div
class="download-receipt__line"
style="border-bottom: 1px solid #000;height: auto;border-top: none;"
>
<p
class="download-receipt__lable download-receipt__flex"
style="width: 158px;"
>
总金额(数字)
</p>
<div
class="download-receipt__flex download-receipt__break"
style="width: 441px;"
>
{{ cardookReceiptData.totalAmount }}
</div>
</div>
<div
class="download-receipt__line"
style="border-bottom: 1px solid #000;height: auto;border-top: none;"
>
<p
class="download-receipt__lable download-receipt__flex"
style="width: 158px;"
>
总金额(大写)
</p>
<div
class="download-receipt__flex download-receipt__break"
style="width: 441px;"
>
{{ cardookReceiptData.totalAmountByChinese }}
</div>
</div>
<h3>注意事项</h3>
<h5 class="download-receipt__tips">
领用人需承诺将领用的卡册如数安全交付给客户,一旦领用,后期如出现任何问题,由领用者个人承担责任。
</h5>
<div
class="download-receipt__line"
style="border-bottom: 1px solid #000;"
>
<div class="download-receipt__line--item">
<p class="download-receipt__lable">
领用人签字
</p>
<span class="download-receipt__value" />
</div>
<div class="download-receipt__line--item">
<p
class="download-receipt__lable"
style="border-left: 1px solid #000;"
>
收货人签字
</p>
<span class="download-receipt__value" />
</div>
</div>
</div>
</div>
</div>
</template>
<script lang='ts'>
import { Component, Vue, Prop, Watch, Provide } from 'vue-property-decorator'
import { fetchContractDetail } from '@/api/cardBookOnline'
@Component({
name: 'downloadreceipt'
})
export default class extends Vue {
@Prop({ default: 0 }) private cardBookSysNo!: number
private cardookReceiptData: any = {}
get applyCardItems() {
return this.cardookReceiptData.applyCardItems || []
}
private async created() {
const { id } = this.$route.query
const res = await fetchContractDetail({ cardApplySysNo: Number(id) })
this.cardookReceiptData = res.data.data || {}
}
private print() {
const print: any = document.getElementById('print') || {}
const bdhtml = window.document.body.innerHTML
const printHtml = print.innerHTML
window.document.body.innerHTML = printHtml
window.print()
window.document.body.innerHTML = bdhtml
window.location.reload()
}
private goBack() {
this.$router.back()
}
}
</script>
<style>
p {
margin: 0;
padding: 0;
}
.el-dialog {
width: 680px;
}
.download-receipt__content {
width: 600px;
margin: 0 auto;
}
.download-receipt__print {
margin: 10px;
}
.download-receipt__line {
width: 600px;
display: flex;
height: 50px;
border-top: 1px solid #000;
border-left: 1px solid #000;
border-right: 1px solid #000;
}
.download-receipt__line--item {
display: flex;
}
.download-receipt__lable {
margin: 0;
padding: 0;
font-weight: 600;
color: #000;
width: 150px;
line-height: 50px;
background: #dfe6ec;
padding: 0 10px;
border-right: 1px solid #000;
}
.download-receipt__flex {
display: flex;
align-items: center;
justify-content: flex-start;
}
.download-receipt__break {
height: auto;
word-break: break-all;
padding: 10px;
}
.download-receipt__value {
width: 150px;
line-height: 50px;
padding: 0 10px;
}
.download-receipt__table {
width: 600px;
border-top: 1px solid #000;
border-left: 1px solid #000;
}
.download-receipt__table--head {
display: flex;
}
.download-receipt__table--body {
display: flex;
}
.download-receipt__table--item {
width: 79px;
min-height: 50px;
display: flex;
align-items: center;
justify-content: center;
word-break: break-all;
}
.download-receipt__table--head .download-receipt__table--item {
border-right: 1px solid #000;
border-bottom: 1px solid #000;
font-weight: 600;
}
.download-receipt__table--item__last {
padding: 5px;
width: 204px;
}
.download-receipt__title {
width: 600px;
font-size: 30px;
font-weight: bold;
line-height: 40px;
text-align: center;
}
.download-receipt__tips {
width: 600px;
word-wrap: break-word;
}
</style>
实现的效果:
这样问题就解决了;