前段时间使用到打印的功能,做为 CV 工程师当然是 copy 了很多代码,但很多都有小坑,最后还是自己动手,并整理了一下小坑(留着下次 copy 方便)
打印是通过 **window.print() **方法实现的,打印的内容是当前的页面。但是实际应用过程中打印的东西往往是局部的某一小块儿,这篇文章要介绍的也是局部打印。
法一:取出局部内容放到 body 里
思路:
代码:
<div id="content">
<div class="print-box">
<div class="print-box-image">
<img [src]=cardData.faceImageUrl class="faceImage" id="print-faceImage">
</div>
<ul class="information-box">
<li class="information-list">
<span class="list-content-name">{{cardData.idCardName}}</span>
</li>
<li class="information-list">
<span class="list-content-company">{{cardData.company.name}}</span>
</li>
</ul>
<div class="print-box-qr">
<qr-code [value]="cardData.id + ''" [size]="80"></qr-code>
</div>
</div>
</div>
const initialBody=window.document.body.innerHTML;// 存储当前body中的内容
var printBody= document.getElementById("content").innerHTML;// 要打印的部分
window.document.body.innerHTML= printBody;// 把需要打印的部分赋给body
window.print();// 打印
window.document.body.innerHTML=bdhtml;//重新给页面内容赋值;
样式问题:
正常css里的样式不会在打印纸中显示,正确的打印样式设置姿势如下:
- @media print{}
小坑:
// 开始我的操作是这样的,把要打印的部分的 id 直接设置在 print-box 这里,发现样式不生效
<div id="content" class="print-box">
</div>
// 然后改成了这样,样式才生效
<div id="content">
<div class="print-box">
</div>
</div>
打印后事件处理问题:
打印后,页面上绑定的事件都失效
解决: ** window.location.reload()** 重新加载页面
但是页面重新加载体验上不是很好,因此,我后面还是选用了加 iframe 的方法
法二:iframe 打印
思路:
图片加载问题:
页面中的图片往往要通过 http 请求得到,而请求的操作是异步的,因此当完成上面的操作后,打印预览里往往显示不到图片,因此这里需要加一个 iframe.onload 方法,等 iframe 完全加载完成再执行打印。
iframe.onload = function(){
// 打印
}
代码:
print() {
const content = document.getElementById("content").innerHTML;
const iframe = <HTMLInputElement>document.createElement('IFRAME');
iframe.setAttribute('style', 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;');
document.body.appendChild(iframe);
const doc = (<HTMLIFrameElement> <unknown>iframe).contentWindow.document;
doc.write(content);
const ys="ul li {list-style: none;}.print-box {width: 300px;margin: 10px auto;border: 1px #5C5C5C solid;}.print-box-image {width: 150px;height: 200px;margin: 20px auto;}.faceImage {width: 150px;height: 200px;}.information-box {margin: 0;padding: 0;text-align: center;}.list-content-name {font-size: 30px;font-weight: 500;}.print-box-qr {margin-bottom: 10px;text-align: center;}";
const style=document.createElement("style");
style.innerText=ys;
doc.getElementsByTagName("head")[0].appendChild(style)
doc.close();
iframe.onload = function(){
(<HTMLIFrameElement> <unknown>iframe).contentWindow.focus();
(<HTMLIFrameElement> <unknown>iframe).contentWindow.print();
};
return false;
}