You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Puppeteer生成PDF时部分元素无法渲染的问题求助

Puppeteer导出PDF时Boxicons图标元素缺失的排查与解决方案

问题描述

服务器生成的报表网页显示正常,但使用Puppeteer将报表转换为PDF时,<i class="bx bxs-checkbox me-2 font-22 text-info"></i>这类Boxicons复选框图标元素缺失。所有CSS类已正常加载,网页端渲染无问题,但PDF中始终无法显示该元素。

效果对比

  • 预期效果:显示蓝色复选框图标
  • 实际PDF效果:复选框图标位置空白(百分比数值差异忽略)

排查思路与解决方案

1. 字体加载未完成导致渲染失败

Boxicons属于图标字体,Puppeteer在headless模式下可能未等待字体完全加载就生成PDF,导致图标无法渲染。

  • 解决办法:
    • 替换固定等待时间为等待图标元素的字体加载完成,例如通过waitForFunction检测元素的字体:
      await page.waitForFunction(() => {
        const icon = document.querySelector('.bx.bxs-checkbox');
        if (!icon) return false;
        const computedFont = window.getComputedStyle(icon).fontFamily;
        return computedFont.includes('boxicons');
      }, { timeout: 10000 });
      
    • 在CSS的@font-face规则中添加font-display: swap,确保字体加载前先显示占位:
      @font-face {
        font-family: 'boxicons';
        src: url('path/to/boxicons.ttf') format('truetype');
        font-display: swap;
      }
      

2. Headless模式渲染差异

旧版Chrome Headless模式与有头模式的渲染逻辑存在差异,可能导致图标字体无法正常渲染。

  • 解决办法:
    将Puppeteer启动参数中的headless: true改为新版Headless模式:
    const browser = await puppeteer.launch({
        headless: "new", // 使用新版Headless,更接近有头Chrome渲染效果
        args: [
            '--no-sandbox', 
            '--disable-setuid-sandbox', 
            '--allow-file-access-from-files',
            '--start-maximized'
        ],
        defaultViewport: null
    });
    

3. 打印媒体查询隐藏元素

检查页面CSS中是否存在@media print规则,意外隐藏了图标元素。

  • 排查与解决:
    • 搜索CSS中的@media print块,确认是否有针对.bx或.bxs-checkbox的display: none、visibility: hidden等属性。
    • 如果存在,修改规则确保图标元素在打印时可见,或者给图标元素添加强制可见的样式:
      @media print {
        .bx.bxs-checkbox {
          display: inline-block !important;
          visibility: visible !important;
        }
      }
      

4. 资源加载时机不充分

虽然使用了networkidle2和固定3秒等待,但可能图标资源加载延迟,导致PDF生成时元素未渲染。

  • 解决办法:
    替换固定等待为等待图标元素可见:
    // 替换 await page.waitForTimeout(3000)
    await page.waitForSelector('.bx.bxs-checkbox', { visible: true, timeout: 10000 });
    

5. PDF配置与页面尺寸不匹配

页面viewport尺寸与PDF导出的尺寸不一致,可能导致元素被截断或未正确渲染。

  • 解决办法:
    在page.pdf()配置中添加preferCSSPageSize: true,让PDF优先使用页面的CSS页面尺寸设置:
    const pdf = await page.pdf({ 
      width: '11.7in',
      height: '16.54in',
      scale: 1,
      margin: {
        top: 0,
        right: 0,
        bottom: 0,
        left: 0
      },
      printBackground: true,
      preferCSSPageSize: true // 启用该选项
    });
    

内容的提问来源于stack exchange,提问作者TangoMike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 03:05:12