JavaScript使用window.print()打印页面:样式设置、精确分页以及局部打印
大部分浏览器提供打印页面的功能,直接使用浏览器的打印功能是直接将整个页面打印出来,并且是自动分页。
很多时候直接打印整个页面并不能满足我们的需要。有三方面的需求我们可能要考虑:
- 样式设置:打印的样式和页面显示的样式不同,需要对设置打印样式。
- 精确分页:需要根据具体的内容进行精确分页。
- 局部打印:不需要打印整个页面,只需要打印页面的部分。
html示例
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>打印</title>
</head>
<body>
<div>内容1</div>
<div>内容2</div>
<input onclick="print()" value="点击打印" type="button">
</body>
</html>
样式设置
页面打印默认会应用当前的样式。如果我们需要对打印的样式做定制的设置,可以使用@media print媒体属性。@media print里定义的样式只会应用于打印,不会应用于页面显示。
例如让内容1的字体打印为斜体:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>打印</title>
<style>
@media print{
.italic {font-style: italic}
}
</style>
</head>
<body>
<div class="italic">内容1</div>
<div>内容2</div>
<input onclick="print()" value="点击打印" type="button">
</body>
</html>
精确分页
默认情况下,调用window.print()会根据页面的内容自动分页。如示例,因为页面的内容少,在一个打印页面就可以容纳,所以是不会分页。
但如果有需求要把"内容1"和“内容2”分为两页打印,那该怎么办呢?
CSS的page-break-after属性可以用来做分页,它的值为:
- auto:默认。如果必要则在元素后插入分页符。
- always:在元素后插入分页符。
- avoid:避免在元素后插入分页符。
- left:在元素之后足够的分页符,一直到一张空白的左页为止。
- right:在元素之后足够的分页符,一直到一张空白的右页为止。
- inherit:规定应该从父元素继承 page-break-after 属性的设置。
auto和always所有浏览器都支持,后面四个值浏览器支持程度不同。
添加page-break-after:always精确分页:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>打印</title>
<style>
@media print{
.page-break {page-break-after:always;}
}
</style>
</head>
<body>
<div class="page-break">内容1</div>
<div>内容2</div>
<input onclick="print()" value="点击打印" type="button">
</body>
</html>
局部打印
默认情况下,window.print()会把整个页面打印处理。如示例里的按钮“点击打印"也是会被打印出来,显然这是我们不想要的。
有两种方法可以对实现局部打印:
- 对不打印的内容隐藏起来
- 把打印的内容添加到新的窗口打印
隐藏打印内容
CSS有两个属性可以用来隐藏显示内容:
- visibility:设置为hidden,内容不显示,但是在内容显示的地方会变成空白。
- display:设置为none。内容会被隐藏,原来内容所在的元素如同删除一样,不显示空白。
一般情况下,打印页面会使用display:none。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>打印</title>
<style>
@media print{
.page-break {page-break-after:always;}
.nonprint{display:none}
}
</style>
</head>
<body>
<div class="page-break">内容1</div>
<div>内容2</div>
<input class="nonprint" onclick="print()" value="点击打印" type="button">
</body>
</html>
在新窗口打印
但要打印的内容少,不打印的内容多且分散,这种情况下隐藏不打印内容就不太好。一般的策略是新建一个窗口,把要打印的内容添加到新的窗口在打印。
需要注意的是:把打印内容添加到新窗口不要把样式添加进去。
示例
printInNewWindow(containerId, style) {
var html = document.getElementById(containerId).innerHTML;
var win= window.open('', '打印', 'height=400,width=600');
win.document.write('<html><head><title></title>');
win.document.write('<style>'+style+'</style>');
win.document.write('</head><body >');
win.document.write(html);
win.document.write('</body></html>');
win.document.close(); // IE >= 10 不能少
win.focus(); // IE >= 10
win.print();
win.close();
}
当然,样式也可以使用css文件。在新窗口打开需要加载css文件,在调用打印前最好调用setTimeout()做下延时。
示例
printInNewWindow(containerId, cssLinks) {
var html = document.getElementById(containerId).innerHTML;
var win= window.open('', '打印', 'height=400,width=600');
win.document.write('<html><head><title></title>');
if(cssLinks && cssLinks.length > 0) {
cssFiles.forEach((cssLink) => {
win.document.write('<link rel="stylesheet" href="'+ cssLink +'" type="text/css" />');
});
}
win.document.write('</head><body >');
win.document.write(html);
win.document.write('</body></html>');
win.document.close(); // IE >= 10 不能少
win.focus(); // IE >= 10
setTimeout(()=> { //延时
win.print();
win.close();
},500);
}
总结
本文主要介绍了如何解决window.print()打印页面时可能要考虑的三个问题:样式设置、精确分页以及局部打印。除了使用window.print()。jquery也提供了一个用于打印的插件PrintArea。