@media print 仅在打印预览或 window.print() 时生效,日常浏览不可见;需用 media="print" 的 link 或内联 @media print 样式,避免 display: none、CSS Grid/Flex 深度嵌套、缺失宽高属性的图片;Puppeteer 导出需预装中文字体并用 @font-face 内联;页眉页脚须绝对定位+@page 预留边距,页码建议分页独立重置。

打印样式表没生效,@media print 为什么被忽略
浏览器默认只在「打印预览」或触发 window.print() 时才启用 @media print,日常浏览中完全不可见——这不是 bug,是设计行为。常见错误是把打印样式写在 JS 动态插入的 style 标签里,或放在 <link rel="stylesheet"> 但漏了 media="print" 属性。
- 必须用
<link rel="stylesheet" href="print.css" media="print">或内联<style>@media print { ... }</style> - 避免用
display: none隐藏导航栏/侧边栏——它会彻底删掉内容,导致页眉页脚错位;改用visibility: hidden+height: 0+overflow: hidden组合更稳妥 - Chrome 和 Edge 对
background-color默认不打印(即使写了-webkit-print-color-adjust: exact),必须显式加print-color-adjust: exact
window.print() 触发后 PDF 导出空白或截断
调用 window.print() 后直接关闭页面、跳转路由,或在打印弹窗打开期间执行 DOM 清理(比如 Vue 的 beforeUnmount、React 的 useEffect cleanup),都会导致内容被销毁,PDF 生成失败。
- 确保打印逻辑完成前不卸载组件/清空容器:可加
setTimeout(() => { /* 清理 */ }, 2000)等待打印窗口关闭(注意:无可靠回调,只能估时) - 避免在打印样式中依赖 CSS Grid 或 Flex 嵌套过深——部分 PDF 打印引擎(如 Chromium 的 headless 模式)对复杂布局解析不稳定,优先用
float或inline-block做分栏 - 图片务必带
width和height属性(非仅 CSS 设置),否则打印时易因加载延迟或尺寸未定导致空白块
用 Puppeteer 导出 PDF 时字体丢失或中文乱码
Puppeteer 默认运行在无图形界面的 Linux 环境(如 Docker),系统缺少中文字体,font-family: "Microsoft YaHei", sans-serif 会直接 fallback 到无 Unicode 支持的默认字体。
- 启动时必须指定字体路径:
args: ['--font-render-hinting=none', '--disable-font-antialiasing']不起作用,真正有效的是在目标机器上安装字体(如 Ubuntu:安装fonts-wqy-zenhei包) - CSS 中避免只写
font-family: SimSun——Linux 下无此字体名,统一用font-family: "Noto Sans CJK SC", "Source Han Sans SC", sans-serif并确保该字体文件已通过@font-face加载(base64 内联最稳) - 设置
pdfOptions.format = 'A4'时,若 HTML 有固定width: 1200px,可能被压缩变形;建议用pdfOptions.width = '210mm'+pdfOptions.height = '297mm'显式控制
打印页眉页脚被截断或重复出现
浏览器原生打印的页眉页脚(如网址、页码)无法用 CSS 完全控制,且与 @page 规则冲突。很多开发者误以为 @page { @top-center { content: "Report"; } } 能覆盖默认页眉,其实它只在支持 CSS Paged Media 的引擎(如 Prince、Antenna House)中有效,Chrome/Firefox 不支持。
立即学习“前端免费学习笔记(深入)”;
- 唯一可靠方式:用绝对定位模拟页眉页脚,配合
@page { margin: 1.5cm; }预留空间,并给 body 设padding-top: 2cm避免内容顶到物理页眉区 - 页码用
counter-increment+counter-reset实现,但注意 Chrome 的 counter 在跨页时偶有重置异常,建议每页用独立<div class="page">包裹并手动设counter-reset: page n - 避免在
@media print中修改body { margin: 0 }——这会让页边距失效,直接导致内容贴边甚至被裁切
事情说清了就结束。真正难的不是导出动作本身,而是让同一份 HTML 在不同打印上下文(用户 Ctrl+P、Puppeteer headless、企业级 PDF 渲染服务)里保持一致——字体、分页、尺寸、资源加载时机,每个点都得单独验证。



















