本文主要介绍如何在框架内实现网页打印功能,即在不用获取DOM的情况下将网页打印出来;
应公司项目开发需求,需要在react框架基础上实现网页的打印,普通的js打印都是通过获取DOM元素来确定需要打印的区域,然而React一类的框架采用虚拟DOM,无法获取真实DOM元素,想到一个办法就是前端实现一个有当前页面样式的HTML模板,发送到后端,后端把模板赋值返回给前端,前端获取到HTML文件,打印这个文件便可。当然这并不适用于任何情况,但也是网页打印的一种方式。
实现步骤
- 写一个HTML模板文件
贡献我的模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>打印模板</title>
<style>
</style>
</head>
<body>
<div class="content">
<div class="header">
<div class="Fileds-createtime item">
文档生成时间:
<script>
var date = new Date();
var now = date.toLocaleTimeString();
var Month = date.getMonth() + 1;
var Date = date.getFullYear() + '年' + Month + '月' + date.getDate() + '日' + now;
window.document.write(Date);
</script>
</div>
</div>
<table align='left' cellspacing="0">
<tr class="sub">
<th class="header-left">活动</th>
<th class="header-left"></th>
<th class="header-left"></th>
<th class="header-left"></th>
</tr>
<tr class="tr">
<td>创建时间:</td>
<td></td>
<td>完成时间:</td>
<td></td>
</tr>
<tr class="tr">
<td>开始时间:</td>
<td></td>
<td>结束时间</td>
<td></td>
</tr>
</table>
</div>
</body>
<script>
window.onload = function (){
window.print();
window.close();
};
</script>
</html>
模板需要有当前页面需打印部分的样式,我使用的表格将字段列出,后端会查找相应的字段进行赋值。
需要显示文档生成时间,用js拼接了一下时间。
补充:用到了一个之前不常用的方法
toLocaleTimeString()
看方法名就知道他会将当前时间转换成一个字符串
当这个HTML从后台传过来并打开时会执行以下js:
<script>
window.onload = function (){
window.print();
window.close();
};
</script>
直接调用原生的js打印,弹出浏览器打印框,当点击取消打印时即关闭这个页面;
模板写好后要发给后端,上传到服务器,收到前端发送的请求时调用模板文件
向后端发请求
- 首先请求是GET请求,传参方式也是用字符串的形式和
token
一起拼接到URL上,不过参数要求要经过base64转码才可以,一开始还去找了老半天react框架中base64的依赖,没想到在node model里本来就有;
- 首先请求是GET请求,传参方式也是用字符串的形式和
现在前端需要做的就只是将转码的参数以及
token
拼接到url后,成为一个完整的url,然后需要打印的时候触发事件打开这个url触发打印
因为需要打开一个新的链接,所以要在新页面打开,一开始我是在新的标签页去打开这个页面,打开页面后也会随即执行html里的js调出打印预览,在新标签页打开这个页面我用的window.open()
属性
后来觉得体验不太好,换成在当前页面弹出新窗口的形式,并且想要新窗口全屏覆盖,查了一些资料,最终实现了:
只需
myWin.moveTo(0, 0);
myWin.resizeTo(screen.availWidth, screen.availHeight);
即可设置弹出的新窗口全屏覆盖;
好了,现在可以实现网页打印了!
本文的介绍大概就到这里,希望可以帮助到有同样需求的人