(本文所有打印方式最终都是调用 window.print()
来打印)
项目需要一个 Web 打印功能,要求也很简单,就是打印一些查询到的表单、表格数据。
最简单的打印方式:
window.print();
window.print()
是原生方法,主流浏览器都可用,调用系统打印功能,打印当前页面。
存在的问题:
- 会打印当前页面所有内容,而很多都不需要;
- 打印没有预览(Chrome 除外),打印前都不知道会打印什么;
- 打印页面不好设计、动态填充数据。
方式一:@media print
CSS 样式默认是显示器 @media screen
,而显示器(screen
)和打印机(printer
)是两种设备,在显示器中看到的样式,打印出来可能会完全不同。
显示器使用像素 px
,而打印机使用毫米 mm
、厘米 cm
、英寸 in
、磅 pt
(1/72 英寸)。
可以专门设计一套样式,作为打印样式。
参考: https://www.html.cn/archives/4731 https://www.cnblogs.com/ylz-blog/p/5260894.html
引入文件时:
<link rel="stylesheet" href="print.css" media="print" />
或者,在通用样式文件中:
/* .css 中 */
@media print {
.print-content {
display: block;
}
.screen-content {
display: none;
}
}
@media print .print-content {
display: block;
}
或者,在 import
时:
/* .css 文件中*/
@import url(print-style.css) print;
@media print {
@import "print-style.css";
body {
font-size:8pt;
}
}
<!-- .html 文件中 -->
<style type="text/css">
@import url(print-style.css) print;
</style>
或者,在 html
文件中:
<style media="print">
.print-content {
display: block;
}
</style>
<p media="print" >网页上看不见,打印时可见</p>
使用 @page
设置打印页面属性,如页眉页脚、纸张大小、方向、页边距、分页等。
/* .css 中*/
@page :pseudo-class {
size: A4 landscape;
margin:2cm;
}
@media print {
@page:right{
@bottom-left {
margin: 10pt 0 30pt 0;
border-top: .25pt solid #666;
content: "Our Cats";
font-size: 9pt;
color: #333;
}
@bottom-right {
margin: 10pt 0 30pt 0;
border-top: .25pt solid #666;
content: counter(page);
font-size: 9pt;
}
@top-right {
content: string(doctitle);
margin: 30pt 0 10pt 0;
font-size: 9pt;
color: #333;
}
}
}
方式二:页面替换
原理:
将页面中不需要打印的部分去掉,替换为需要打印的部分,然后用 window.print()
打印整个页面
在 html 中做标记(开始结束点,ID),哪些可以打印
<!-- html -->
<!--startprint-->
<div id="printcontent" style="display:none">
打印内容
</div>
<!--endprint-->
然后在 js 中找到需要打印的部分,用此替换整个页面
// js
// 用开始结束标记
function doPrint() {
let bdhtml=window.document.body.innerHTML;
let sprnstr="<!--startprint-->"; //开始打印标识字符串有17个字符
let eprnstr="<!--endprint-->"; //结束打印标识字符串
let prnhtml=bdhtml.substr(bdhtml.indexOf(sprnstr)+17); //从开始打印标识之后的内容
prnhtml=prnhtml.substring(0,prnhtml.indexOf(eprnstr)); //截取开始标识和结束标识之间的内容
window.document.body.innerHTML=prnhtml; //把需要打印的指定内容赋给body.innerHTML
window.print(); //调用浏览器的打印功能打印指定区域
window.document.body.innerHTML=bdhtml;//重新给页面内容赋值;
return false;
}
// 用 id 选取
function doPrint2(){
bdhtml=window.document.body.innerHTML;
let jubuData = document.getElementById("printcontent").innerHTML;
window.document.body.innerHTML= jubuData;
window.print();
window.document.body.innerHTML=bdhtml;//重新给页面内容赋值;
return false;
}
存在的问题:
执行 doPrint()
方法后,页面显示内容产生了变化,并且在之后 HTML 虽然还原回去了,但样式可能会发生变化,form 表单也会失效,和原先的页面不一样了。
方式三:iframe
// js
function doPrint3(){
//判断iframe是否存在,不存在则创建iframe
var iframe=document.getElementById("print-iframe");
// 或者在创建前,先删除
if(!iframe){
var el = document.getElementById("printcontent");
iframe = document.createElement('IFRAME');
var doc = null;
iframe.setAttribute("id", "print-iframe");
iframe.setAttribute('style', 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;');
document.body.appendChild(iframe);
doc = iframe.contentWindow.document;
//这里可以自定义样式
//doc.write("<LINK rel="stylesheet" type="text/css" href="css/print.css">");
doc.write('<div>' + el.innerHTML + '</div>');
doc.close();
iframe.contentWindow.focus();
}
iframe.contentWindow.print();
if (navigator.userAgent.indexOf("MSIE") > 0){
document.body.removeChild(iframe);
}
}
方式四:onbeforeprint, onafterprint 事件
onbeforeprint, onafterprint
打印前、打印后触发的事件。
HTML 中 :
<!-- html -->
<body onbeforeprint="myScript1" onafterprint="myScript2"></body>
<body>
<div onbeforeprint="myScript1" onafterprint="myScript2"></div>
</body>
JS 中:
// js
window.onbeforeprint=function(){myScript1};
window.onafterprint=function(){myScript2};
// 或者
window.addEventListener("beforeprint", myScript1);
window.addEventListener("onafterprint", myScript2);