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。
 
             
             
             
             
            