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

Puppeteer生成PDF时页眉页脚与内容缩放不一致问题求助

Puppeteer生成PDF时页眉页脚缩放不一致的修复方案

问题描述

使用Puppeteer结合Nunjucks渲染模板生成发票PDF时,调用page.pdf()发现页眉页脚的缩放比例大于正文内容:设置的12px字体在页眉页脚中显示更大,边距也存在同样的缩放偏差,需要让页眉页脚与内容保持一致的缩放比例。

修复方案

方案1:修正页眉页脚模板样式,统一缩放与宽度

  1. 修复语法错误:先修正页眉模板中的样式语法问题,比如将padding: 0 1.9cm);里的多余括号改为padding: 0 1.9cm;。
  2. 匹配正文可打印宽度:A4纸的实际可打印宽度需减去左右边距,将页眉页脚的max-width: 21cm;改为max-width: 19cm;,同时添加margin: 0 auto;确保居中对齐。
  3. 添加缩放控制:给页眉页脚外层容器添加缩放样式,根据实际偏差调整比例,抵消原生渲染的缩放差异:
transform: scale(0.9);
transform-origin: top left;
width: calc(100% / 0.9); /* 抵消缩放导致的宽度收缩 */

修改后的页眉模板示例:

<div style="
    -webkit-print-color-adjust:exact;
    width: 100%;
    max-width: 19cm;
    margin: 0 auto;
    position: relative;
    background: #00c1af;
    padding: 0;
    transform: scale(0.9);
    transform-origin: top left;
    width: calc(100% / 0.9);
">
    {% if quote.display_rules.title != null %}
    <div class="invoice-title {{quote.display_rules.title}}" style="
            font-family: 'Roboto', sans-serif !important;
            font-weight: bold !important;
            color: #212529 !important;
            position: absolute;
            -webkit-font-smoothing: antialiased !important;
            -moz-osx-font-smoothing: grayscale !important;
            -webkit-print-color-adjust: exact !important;
            font-smooth: always !important;
            font-size: 15px;
            top: 2cm;
            right: 2cm;
        ">
        {{ quote.title }}
    </div>
    {% endif %}
    <div class="invoice-header" style="
        background: #ffff00;
        width: 100%;
        margin: 0;
        padding: 0 1.9cm;
    ">
        {% if (quote.style and quote.style.header and quote.style.header.image) or (quote.company_logo) %}
        <div class="logo-wrapper {{fullWidthHeader}}" style="height:{{quote.style.header.height }}px;margin:{{quote.style.header.margin}}px">
            {% if headless_mode !== 'true' %}
            {% if quote.company_logo %}
            <img class="logo" src="{{ quote.company_logo }}" alt="" style="position: relative; width: auto;height: 100%;max-height: 100%;"/>
            {% else %}
            <img class="logo" src="{{ quote.style.header.image }}" alt="" style="position: relative; width: auto;height: 100%;max-height: 100%;"/>
            {% endif %}
            {% endif %}
        </div>
        {% endif %}
        <div class="invoice-name" style="
            font-family: 'Roboto', sans-serif !important;
            color: #212529 !important;
            -webkit-font-smoothing: antialiased !important;
            -moz-osx-font-smoothing: grayscale !important;
            -webkit-print-color-adjust: exact !important;
            font-smooth: always !important;
            font-weight: bold !important;
            font-size: 15px;
        ">
            <span>
                {{ $t('documents.' + (quote.language or 'fr-FR') + '.' + quote.name.trim()) }} {{ quote.number }}
            </span>
            <span class="invoice-date">
                {{ $t("documents." + (quote.language or 'fr-FR') + ".from") }} {{ moment(quote.date).format($t("date." + (quote.language or 'fr-FR') + ".format")) }}
            </span>
        </div>
    </div>
</div>

方案2:用CSS固定定位替代Puppeteer原生页眉页脚

彻底规避原生页眉页脚的独立渲染差异,将页眉页脚嵌入正文模板,通过CSSposition: fixed实现每页重复显示:

  1. 在正文模板(QUOTE_TPL)顶部添加页眉容器:
<div class="pdf-header" style="
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: {{ foundQuote.style.header.height + 80 }}px;
    -webkit-print-color-adjust:exact;
    background: #00c1af;
">
    <!-- 原页眉模板内容 -->
</div>
  1. 在正文模板底部添加页脚容器:
<div class="pdf-footer" style="
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    height: 80px;
    -webkit-print-color-adjust:exact;
">
    <!-- 原页脚模板内容 -->
</div>
  1. 调整正文内容边距,避免被页眉页脚遮挡:
body {
    margin-top: {{ foundQuote.style.header.height + 80 }}px;
    margin-bottom: 80px;
}
  1. 修改PDF生成代码,移除原生页眉页脚相关参数:
await page.pdf({
  path: filePath,
  format: 'A4',
  margin: {
    top: 0,
    bottom: 0,
    left: '1cm',
    right: '1cm'
  }
});

该方案的优势是页眉页脚与正文共享同一渲染环境,缩放比例完全一致。

方案3:统一页面视口设置

在调用page.setContent()前,设置匹配A4比例的页面视口,让页眉页脚的默认缩放与正文对齐:

await page.setViewport({
  width: 1200,
  height: 1697, // A4纸比例对应的像素尺寸
  deviceScaleFactor: 1,
});

同时确保页眉页脚与正文的字体单位统一使用px。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 11:40:25