如何让Puppeteer生成正确适配屏幕@media查询的PDF
Puppeteer生成PDF时screen媒体查询失效的解决方案
问题现象
使用Puppeteer 21.1.1生成PDF时,设置width: '1400px',但CSS中@media (min-width: 1250px)的规则不生效,仅当把阈值改为1050px时才触发;同时page.setViewport设置对PDF渲染无效果。
解决方案
调整代码执行顺序和PDF生成参数,确保媒体查询能匹配设置的宽度:
修改后的代码
const browser = await puppeteer.launch({ args: ['--no-sandbox'], headless: "new" }); const page = await browser.newPage(); // 先设置视口,确保后续内容加载时使用该尺寸 await page.setViewport({ width: 1400, height: 900, deviceScaleFactor: 1 }); // 提前设置媒体类型为screen await page.emulateMediaType('screen'); // 加载内容 await page.setContent(content, { waitUntil: 'networkidle0' }); // 生成PDF时移除默认边距,确保设置的宽度为实际可用宽度 const pdfBuffer = await page.pdf({ width: '1400px', height: '900px', printBackground: true, margin: { top: 0, right: 0, bottom: 0, left: 0 } }); await browser.close();
原因说明
- 执行顺序问题:
setViewport和emulateMediaType必须在setContent之前调用,否则内容加载时不会应用这些设置,媒体查询会基于初始默认视口计算。 - PDF默认边距影响:Puppeteer生成PDF时默认带有边距(约1cm),会导致实际渲染的可用宽度小于设置的
width值。比如设置1400px宽度,减去左右边距后实际宽度可能不足1250px,使得min-width:1250px的媒体查询无法触发。移除边距后,实际宽度与设置值一致,媒体查询即可正常匹配。 - New Headless模式特性:新版无头模式(
headless: "new")下,PDF渲染的视口逻辑与旧版有差异,必须严格遵循先设置视口再加载内容的顺序才能生效。
内容的提问来源于stack exchange,提问作者Ivan Gusev
相关产品推荐
相关产品推荐

