使用Puppeteer+Chart.js生成PDF出现大量空白页问题求助
解决Puppeteer生成Chart.js图表PDF时的大量空白页问题
核心问题原因
- Chart.js自动生成的尺寸监测元素(
.chartjs-size-monitor系列)在打印/PDF生成流程中,会触发异常布局计算,导致页面高度被无限拉伸 - 原flex容器CSS存在语法错误,可能引发布局混乱
- Puppeteer生成PDF时固定页面高度,且未等待Chart.js完全渲染,导致内容高度计算偏差
解决方案步骤
1. 彻底隐藏Chart.js尺寸监测元素(打印样式)
在CSS中添加打印专属样式,完全屏蔽Chart.js的尺寸监测元素,避免其干扰页面高度计算:
@media print { .chartjs-size-monitor, .chartjs-size-monitor-expand, .chartjs-size-monitor-shrink { display: none !important; position: static !important; height: 0 !important; width: 0 !important; visibility: hidden !important; } }
2. 修复flex容器的CSS语法错误
原代码存在分号缺失和拼写错误,修正后保证布局正常:
.flex-container { display: flex; justify-content: space-between; flex-flow: row wrap; align-content: stretch; align-items: stretch; }
3. 优化Puppeteer生成逻辑
- 移除固定页面高度配置,让Puppeteer根据实际内容自动分页
- 替换
sleep为精准等待Chart.js渲染完成的逻辑,避免内容未加载完全就生成PDF - 添加
printBackground: true确保图表颜色/背景正常显示
修改后的TypeScript代码:
private async convertation(data: any, currentRepo: string) { try { const res = await this.getTemplateHtml(); const template = hb.compile(res, { strict: true }); const html = template(data); fs.writeFileSync("./res/index.html", html); const browser = await puppeteer.launch({ args: ["--no-sandbox"] }); const [repoOwner, repoName] = currentRepo.split('/'); const outfile = `./output/testdata/${repoOwner}-${repoName}.pdf`; if (fs.existsSync(outfile)) { fs.unlinkSync(outfile); } const page = await browser.newPage(); // 设置合适的视口,提高设备缩放因子保证PDF清晰度 await page.setViewport({ width: 1366, height: 768, deviceScaleFactor: 2 }); // 加载页面并等待网络请求完成 await page.goto('http://localhost:7000/index.html', { timeout: 0, waitUntil: 'networkidle0' }); // 等待所有Chart.js图表渲染完成(监听canvas元素的chart实例状态) await page.waitForFunction(() => { const canvasElements = Array.from(document.querySelectorAll('canvas')); return canvasElements.every(el => { const chartInstance = (el as any).chart; return chartInstance && chartInstance.rendered; }); }, { timeout: 10000 }); // 生成PDF,使用A4格式(或自定义宽度,不固定高度) await page.pdf({ path: outfile, scale: 1, format: 'A4', displayHeaderFooter: false, printBackground: true, }); await browser.close(); console.log("PDF Generated"); } catch (err) { console.error(err); } }
内容的提问来源于stack exchange,提问作者jaskar
相关产品推荐
相关产品推荐

