目录
方法二:利用iframe,iframe.contentWindow.print()
前端实现打印功能的方法有很多,大家在网上随便一搜就是一大堆,在这里,我主要选择一个我觉得比较好一点的实现方式来进行解释描述:
方法一:window.print()
这个命令默认打印整个页面的内容,所以,如果想要实现局部打印功能的话,就要重新给body赋值,并且后续执行完之后再还原回去,这样的话会造成一些非预期的结果,**很麻烦,**并且在当前也操作,window.document.body的内容重新渲染,打印完会有刷新,影响用户的体验,所以不推荐*,*但还是简单介绍一下:
//(1)首先获得元素的html内容(这里建议如果有样式最好是用内联样式的方式)
var newstr = document.getElementById(myDiv).innerHTML;//得到需要打印的元素HTML
//(2)保存当前页面的整个html,因为window.print()打印操作是打印当前页的所有内容,所以先将当前页面保存起来,之后便于恢复。
var oldstr = document.body.innerHTML;//保存当前页面的HTML
//(3)把当前页面替换为打印内容HTML
document.body.innerHTML = newstr;
//(4)执行打印操作
window.print();
//(5)还原当前页面
document.body.innerHTML = oldstr;
方法二:利用iframe,iframe.contentWindow.print()
这个与方法一的区别就是,取消打印后可以完整保留当前访问页面的内容,不需要影响原页面,需要注意的是,在你生成新的iframe内的html时,样式可能会有影响,加载不完全(全局样式特别),需要单独引入一些你自己的样式,我比较推荐这个,所以来重点说明一下:
// 1、获取需要打印的部分
const printArea = this.getElementById(document.body,"rx-form-container");
// 2、引入打印的专有CSS样式
var strStyleCSS="<link href='/rxform.css' type='text/css' rel='stylesheet'>";
var antdesignCSS="<link href='/antdesign.css' type='text/css' rel='stylesheet'>";
let printCSS=" <link href='/print.css' type='text/css' rel='stylesheet'> ";
// 3、拼接字符串
var strFormHtml=strStyleCSS +antdesignCSS + printCSS+"<body>"+domEl.innerHTML+"</body>";
// 4、创建 iframe 标签
var iframe = document.createElement('IFRAME');
var doc = null;
iframe.setAttribute('style','position:absolute;width:0;height:0;left:-500px;top:-500px;');
// 5、浏览器插入 iframe
document.body.appendChild(iframe);
doc = iframe.contentWindow.document;
// 引入打印的专有CSS样式
// doc.write("<LINK rel='stylesheet' type='text/css' href='/print.css'>");
doc.write(printHTML);
doc.close();
iframe.contentWindow.focus();
// 注意:等待加载完调用打印,否则样式外联css显示有问题
iframe.contentWindow.addEventListener('load', function() {
// 6、开始打印
iframe.contentWindow.print();
// 7、删除iframe
document.body.removeChild(iframe);
})
这样写虽然不会影响原页面,但是需要我们把打印的内容及样式用JS来生成,如果打印的内容很多,或者样式很复杂的话,那就是一个大工程,难免不方便,所以如何解决问题呢?我在查度娘的时候,发现了一种方式:将要打印的内容生成一个图片然后放在iframe中,利用html2canvas 生成截图,但是我并未校验(因为本人项目主要是打印表单流程,没有很复杂,嘻嘻),所以,这里我就简单复制一下大佬的,最后也放置了链接,如果有需要也可以去大佬博客看看:
// 打印账单
printBill () {
this.printDisabled = true // 点击打印按钮禁止重复点击
setTimeout(_ => { // 按钮显示为禁止了再去执行截图功能
html2canvas(this.$refs.reconciliationWrapper, {
backgroundColor: null,
scale: 1.3
}).then((canvas) => {
let dataURL = canvas.toDataURL('image/png')
this.$refs.iframe.contentWindow.document.body.innerHTML = '' // 清空上一次打印的内容
this.$refs.iframe.contentWindow.document.write('<html><head><style media="print">@page { margin: 0mm 10mm; }body{margin-top: 50px; text-align: center;}</style></head><body><img src=' + dataURL + '></body></html>')
setTimeout(_ => {
this.$refs.iframe.contentWindow.print()
}, 0)
this.printDisabled = false
})
}, 100)
}
然后将截图放在iframe中的img打印,截图一般会有些模糊,调整html2canvas的参数scale,放大缩小的比例,要根据实际情况调整。
方法三:使用第三方库或插件
除了使用浏览器自带的打印功能外,还可以使用第三方库或插件来实现更高级的打印操作,例如打印指定区域、打印多个页面等。
常用的打印插件有 Print.js、html2canvas、jPrintArea等。这里以 Print.js 为例,演示如何使用该插件实现前端打印功能。
首先,需要在 head
标签中引入 Print.js
插件:
<head>
<script src="/path/to/Print.js"></script>
</head>
然后,在页面中需要打印的元素上添加 class
属性或 ID 属性:
<div id="print-content">
<!-- 这里是需要打印的内容 -->
</div>
最后,在触发打印的按钮的点击事件中,使用 Print.js
插件的 printHtml
方法来触发打印操作:
function onPrint() {
// 获取需要打印的内容
const content = document.getElementById('print-content').innerHTML;
// 调用 printHtml 方法触发打印操作
window.printHtml({
printable: content,
onAfterPrint: function() {
// 打印完成后的操作
}
});
}
在上述代码中,我们使用了 window.printHtml
方法来触发打印操作。该方法接受一个配置对象,其中包含需要打印的内容和打印完成后的回调函数。
需要注意的是,使用第三方插件能够提供更为定制化的打印功能,但是在使用前需要对插件的相关文档进行仔细的阅读和熟悉,确保能够正确地使用插件完成打印功能。
提供一个完整的范例:
当用户想要打印页面时,我们可以向用户提供打印功能。而实现页面打印的主要步骤如下:
1. 设计打印布局
在进行打印之前,我们需要首先设计打印布局以确保打印内容能够在有限的纸张大小上清晰地展示。我们需要定义一个专门的打印样式表来控制样式和布局。这个样式表可以包含在主样式表中,也可以在header标签中单独引用。比较重要的是我们需要在这个样式表中使用@media print
来为网页在打印模式下设置独立的样式,以适应打印的需求。因为我们的网页布局和打印页面布局还是有很大的区别,如margin,padding等样式设置等。
可以通过一个简单的示例来说明:
@media print {
/* 隐藏不必须要打印的元素 */
header, nav, .no-print {
display: none;
}