背景 👣
近期公司提出了一个新需求,希望前端能实现线上打印检测数据报告的页面,考虑到页面内容以数据为主,页面长度基本一页内,功能只需要打印,直接使用window.print()即可实现
遇到的问题 👆
利用iframe存放打印的内容,需要把样式也放进iframe中,不然iframe中是没有样式的,由于项目并没有单独打包CSS文件,因此只能通过原生属性 document.styleSheets 读取vue单页面组件加载过的所有css样式,筛选出对应的报告样式
贴上代码 👾
<template>
<div>
<div id="printContent" class="wrapper">报告内容</div>
<iframe id="printf" width="0" height="0" frameborder="0" />
<sButton text="打印" @click="atPrint" />
</div>
</template>
export default {
methods: {
// 打印PDF
atPrint() {
// 样式的部分
const styleSheet = this.getCssBlock();
// 要打印的部分
let printhtml = '<style>' + styleSheet + '</style>' + document.getElementById('printContent').innerHTML;
// 生成并打印ifrme
let f = document.getElementById('printf');
f.contentDocument.write(printhtml);
f.contentDocument.close();
f.contentWindow.print();
},
getCssBlock() {
const cssBlock = document.styleSheets;
const styleData = [...cssBlock].reverse().find(({ cssRules }) => {
return [...cssRules].find((rule) => {
return ['.print_title'].includes(rule.selectorText.replace(/\[.+\]/, ''));
});
});
return styleData.ownerNode.innerText;
}
}
};