window.print打印pdf
1、前言 前端打印pdf就是使用原生的window.print()方法实现,这里有几个问题你会遇到。打印纸张大小,不同纸张大小,你需要相应调整表格宽度和最大分页高度分页时机,不适当的话会导致表格跨页分断背景色打印,这个是不能设置的,但是通过css属性可以实现打印时的css设置前端环境:vue+element ui2、代码实例<template><div><div i
1、前言
前端打印pdf就是使用原生的window.print()方法实现,这里有几个问题你会遇到。
- 打印纸张大小,不同纸张大小,你需要相应调整表格
宽度
和最大分页高度
- 分页时机,不适当的话会导致表格
跨页分断
- 背景色打印,这个是不能设置的,但是通过css属性可以实现
- 打印时的css设置
前端环境:vue+element ui
2、代码实例
<template>
<div>
<div id="toolBox">
<div class="toolBox">
<el-button type="primary" plain size="small" style="margin-top: 20px;width: 130px;" @click="saveAsPdf">
打印PDF
</el-button>
</div>
</div>
<div :id="tableConfig.pdfId" :class="tableConfig.pdfClass" v-for="(tableConfig,configIndex) in tableConfigList"
:key="configIndex">
<div class="thisPage">
<h1 style="text-align: center">window.print方法demo</h1>
</div>
<div class="thisPage" v-for="(data,index) in dataList" :key="index" :style="tableConfig.tableStyle">
<el-table :data="data" :header-cell-style="tableHeader" border>
<el-table-column column-key="col1_" prop="col1_" label="第一列"></el-table-column>
<el-table-column column-key="col2_" prop="col2_" label="第二列"></el-table-column>
<el-table-column column-key="col3_" prop="col3_" label="第三列"></el-table-column>
<el-table-column column-key="col4_" prop="col4_" label="第四列"></el-table-column>
<el-table-column column-key="col5_" prop="col5_" label="第五列"></el-table-column>
</el-table>
<el-divider></el-divider>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'windowPrint',
data() {
return {
data: {
col1_: '',
col2_: '',
col3_: '',
col4_: '',
col5_: ''
},
dataList: [],
tableHeader: {
'color': 'aliceblue',
'background-color': 'slateblue'
},
tableConfigList: [{
pdfId: 'comment_report',
pdfClass: '',
tableStyle: `'100%'`
}, {
pdfId: 'print_report',
pdfClass: 'comment_hide',
tableStyle: `width:1100px;`
}]
}
}, methods: {
getData() {
let keys = Object.keys(this.data);
let size = 35;
for (let i = 0; i < size; i++) {
this.dataList[i] = new Array();
for (let j = 0; j < i; j++) {
let tempData = {};
keys.forEach(key => {
tempData[key] = key + i + j;
})
this.dataList[i][j] = tempData;
}
}
this.dataList[size] = [];
},
saveAsPdf() {
let commentReport = document.getElementById("comment_report");
let printReport = document.getElementById("print_report");
let toolBox = document.getElementById("toolBox")
toolBox.className = "print_hide";
commentReport.className = "print_hide";
printReport.className = "print_content";
let thisPage = printReport.querySelectorAll('.thisPage');
let curHeight = 0;
let a3PageHeight = 1558;
for (let item of thisPage) {
let contentHeight = parseInt(window.getComputedStyle(item).height)
if ((curHeight + contentHeight) > a3PageHeight) {
console.log("a page")
item.style.pageBreakBefore = "always";
// 清空
curHeight = 0;
}
if(contentHeight<a3PageHeight){
curHeight += contentHeight
}else {
curHeight = contentHeight % a3PageHeight
}
console.log("item", contentHeight, curHeight);
}
setTimeout(() => {
window.print();
toolBox.className = "toolBox";
printReport.className = "comment_hide";
}, 1000
)
}
},
created() {
this.getData();
}
}
</script>
<style scoped>
.toolBox {
position: fixed;
top: 0;
right: 0;
width: 100%;
height: 50px;
line-height: 50px;
text-align: right;
background: rgba(0, 0, 0, 0.3);
box-shadow: 2px 2px 3px #e4e4e4;
z-index: 9999;
}
.toolBox .el-button {
margin: 0;
transform: translate(-50%, -40%);
}
@page {
size: A3;
margin: 0;
}
.comment_hide {
display: none;
}
@media print {
.print_hide {
display: none;
}
.print_content {
margin-top: 20px !important;
-webkit-print-color-adjust: exact;
-moz-print-color-adjust: exact;
-ms-print-color-adjust: exact;
print-color-adjust: exact;
}
}
</style>
3、代码解析
- 背景色打印
需要打印的内容包含在这个css属性里面的class即可
-webkit-print-color-adjust: exact;
-moz-print-color-adjust: exact;
-ms-print-color-adjust: exact;
print-color-adjust: exact;
-
打印时的css设置
@media print{}这个css里面的属性会在打印时才会运行渲染 -
打印纸张大小
@page {
size: A3;
margin: 0;
}
在@page里面可以设置纸张大小,这里设置的是A3大小,至于宽高,网页打印的宽高好像是跟屏幕有关,这里设置宽1100px刚好更我屏幕打印时的宽度相当,每页高度这里选用1558px,高度好像相对稳定。
- 分页时机
这里分页是根据你的控件高度计算而知的,当累计高度高于分页高度则将当前控件前插入分页符,设置方法如下:
item.style.pageBreakBefore = "always";
通过设置style为page-break-before:always实现
ps:网上全是page-break-after:always实现的,难道page-break-before不香么
-
html结构
1、这里是通过tableConfigList这个配置变量,控制两个大的div的id、class和table的宽度
2、每个需要分页的控件都用class="thisPage"标记,便于查找
3、绘制两次需要网页内容,一次是用于用户看的,一次是用于打印的隐藏内容,打印的时候,设置隐藏用户看的,显示打印的内容,实现直接打印,而不影响用于观感 -
解析saveAsPdf方法
saveAsPdf() {
let commentReport = document.getElementById("comment_report");
let printReport = document.getElementById("print_report");
let toolBox = document.getElementById("toolBox")
toolBox.className = "print_hide";
commentReport.className = "print_hide";
printReport.className = "print_content";
let thisPage = printReport.querySelectorAll('.thisPage');
let curHeight = 0;
let a3PageHeight = 1558;
for (let item of thisPage) {
let contentHeight = parseInt(window.getComputedStyle(item).height)
if ((curHeight + contentHeight) > a3PageHeight) {
console.log("a page")
item.style.pageBreakBefore = "always";
// 清空
curHeight = 0;
}
if(contentHeight<a3PageHeight){
curHeight += contentHeight
}else {
curHeight = contentHeight % a3PageHeight
}
console.log("item", contentHeight, curHeight);
}
setTimeout(() => {
window.print();
toolBox.className = "toolBox";
printReport.className = "comment_hide";
}, 1000
)
}
1、获取用于显示的report内容和用于打印的report内容
2、将toolBox、commentReport、printReport对应class的html元素,设置class为print时的才会渲染的class
3、控制page-break-before:always属性的设置,当加上当前元素,超过页高度,则当前元素设置style为page-break-before:always,提示print方法这里要分页
4、处理单页超过打印纸张大小问题,这里超过了,没有去处理,只处理了超过后下一个元素加上不超过纸张高度下,追加上下一个元素
5、最后要设置延时,不然会渲染不足。
demo地址:https://github.com/Hitvz/pdfoutput
参考博客:vue+element打印页面功能
更多推荐
所有评论(0)