最近遇到一个需求,需要把页面中选中的试题打印出来A4纸的格式,因为之前未接触过此类需求,所以不知道如何下手。于是自己开始在网上找各种能用到的方法,阅读分析看哪个适合自己的需求。
使用浏览器打印
通过 window.print() 、document.execCommand('print’) 调用浏览器打印,但是直接使用浏览器打印虽然省事,打印的是整个网页,不能打印局部内容,无法满足我的打印需求。
如何实现局部打印呢,在网上找到了两种办法:
- 一种是把整个页面的内容替换成需要打印的dom内容,全局打印,最后在还原页面内容,这种方法个人感觉不好,便舍弃了;
- 另外一种是创建一个iframe,然后将需要打印的内容添加到iframe里,然后打印整个iframe,这里需要注意获取需要打印的dom添加到iframe时,样式表会丢失(行内样式不会),解决办法需要将这部分样式表在添加到Iframe内。 以下是相关代码
const printEvent = () => {
const printContentHtml = document.getElementById("printId")?.innerHTML; // 获取页面中需要打印的内容
const iframe = document.createElement("iframe") as any; // 创建iframe
iframe.setAttribute(
"style",
"position:absolute;width:794px;height:1123px;background:#000;left:-1100px;top:-1100px;"
); // 设置iframe的整体样式,不让他在页面中显示
document.body.appendChild(iframe); // 把iframe添加到body中
//contentDocument 属性能够以 HTML 对象来返回 iframe 中的文档。
const iframeDoc = iframe?.contentWindow!.document;
iframeDoc.write(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<!-- !!引入 控制iframe 打印的css -->
<!-- !!诱发 坑 的地方 -->
</head>
<body style="">
${printContentHtml}
</body>
</html>
`)
// 获取iframe html文件head
const head = iframeDoc.getElementsByTagName('head')
// 新建link标签
const linkTag = document.createElement('link')
linkTag.id = 'newstyle'
linkTag.href = `/theme/iframe.css`
linkTag.setAttribute('rel', 'stylesheet')
linkTag.setAttribute('type', 'text/css')
// 将link标签添加进iframe html文件的head里
head[0].append(linkTag)
iframe?.contentDocument!.close();
setTimeout(() => {
iframe?.contentWindow!.print(); // 调用浏览器打印iframe的内容
document.body.removeChild(iframe); // 从body中删除iframe
}, 0);
}
效果图
到这里实现局部打印的需求就完成了,下期更新如何实现分页打印
希望得到 jym 的指导评论,期待得到更优的方法指引