用 iframe 实现局部打印需动态创建隐藏 iframe,注入目标 HTML 和内联打印 CSS(如 @page { size: A4; margin: 10mm; }),等待内容及图片加载完成后再调用 print();跨域时不可操作 contentDocument,应降级为 @media print 或服务端方案。

iframe 打印的基本流程
不是直接给 iframe 写内容就完事,得完整构造一个可独立渲染的文档环境:
- 动态创建一个隐藏的
<iframe>元素(不依赖预设的 iframe 标签) - 获取目标区域的 HTML(比如
document.getElementById('print-area').innerHTML) - 把 HTML 写入 iframe 的
contentDocument或contentWindow.document - 注入打印专用的 CSS(如重置页边距、设置 A4 尺寸、隐藏非必要元素)
- 等 iframe 内容加载完成(监听
onload),再调用iframe.contentWindow.print() - 打印完成后可选移除 iframe,保持 DOM 干净
关键细节:CSS 必须内联写入 iframe
主页面的 @media print 样式不会自动生效到 iframe 里。必须把打印样式显式写进 iframe 的 <head> 中:
- 用
document.createElement('style')创建样式节点 - 内容示例:
@page { size: A4; margin: 10mm; } body { margin: 0; font-size: 12pt; } - 追加到 iframe 的
document.head,不能靠外部 link 或主页面样式继承
图片和资源加载要等稳了再打
如果打印内容含图片,直接写入后立刻 print 可能打出空白或错位:
- 在写入
body.innerHTML后,手动检查图片是否complete - 对未加载完的图片,监听
onload和onerror,全部就绪再触发 print - 简单做法:用
Promise.all(imgPromises)等待所有图片加载完成
跨域 iframe 无法操作 contentDocument
如果 iframe 的 src 是外域地址(比如不同子域名、第三方服务),浏览器会阻止脚本访问其内容:
立即学习“前端免费学习笔记(深入)”;
- 此时不能用动态注入 HTML 的方式,只能改用服务端生成打印页,或前端跳转新窗口
- 同源前提下才可用
iframe.contentDocument;否则建议改用@media print配合 visibility 控制 - Vue/React 项目中,推荐封装为可复用的打印组件,自动处理同源判断与 fallback



















