html怎样插入页码转pdf_插页码html转pdf法【要点】

页码必须用 CSS @page 规则配合 counter(page) 实现,Puppeteer 需启用 displayHeaderFooter: true,且 @page 必须位于顶层 CSS;分节页码需结合 counter-reset 与 counter-increment 控制。

HTML 转 PDF 时页码只能靠 CSS `@page` 实现

原生 HTML 不支持 `第1页` 这类写法在 PDF 中自动更新页码——浏览器打印或工具(如 wkhtmltopdf、WeasyPrint、Puppeteer)生成 PDF 时,页码必须由 CSS 的 @page 规则控制,且仅对块级内容生效。JavaScript 动态插入的页码文本在 PDF 渲染阶段早已失效。

@page + counter(page) 插入基础页码

这是最通用、兼容性最好的方式,适用于 Puppeteer、wkhtmltopdf、WeasyPrint 等主流工具(注意:部分旧版 wkhtmltopdf 对 counter() 支持不完整,建议用 0.12.6+)。

@page {
  @bottom-center {
    content: "第 " counter(page) " 页";
  }
}
  • counter(page) 是唯一被广泛支持的页码变量,不能写成 pagepages
  • @bottom-center 可替换为 @top-right@bottom-left 等,但位置关键词必须严格匹配(大小写敏感)
  • 不能在 @page 内使用 class、id 或 JS 表达式;所有样式需内联或通过 @page { margin: 2cm; } 控制

Puppeteer 中需显式启用 printBackgrounddisplayHeaderFooter

很多人写了 @page 却没显示页码,根本原因是 Puppeteer 默认禁用页眉页脚渲染。即使 CSS 正确,也必须传参开启:

await page.pdf({
  path: 'output.pdf',
  format: 'A4',
  displayHeaderFooter: true,
  printBackground: true,
  headerTemplate: '',
  footerTemplate: '第  页'
});
  • displayHeaderFooter: true 是硬性前提,否则 @page 中的 @top/@bottom 完全不生效
  • footerTemplateheaderTemplate 是字符串 HTML,其中 class="pageNumber"class="totalPages" 会被 Puppeteer

    自动替换(仅限这两个 class 名)
  • printBackground: true 确保背景色、边框等正常输出,否则页脚可能空白

页码起始值与分节控制要用 counter-resetcounter-increment

封面、目录、正文需要不同页码格式(如封面无页码、目录用罗马数字、正文用阿拉伯数字),纯靠 @page 不够,得结合 HTML 结构和 CSS 计数器:

body { counter-reset: page 0; }
.section-cover { counter-reset: page; }
.section-toc { counter-reset: page; }
.section-main { counter-reset: page 1; }

@page {
  @bottom-center {
    content: counter(page, decimal);
  }
}

.section-toc::before {
  counter-increment: page;
  content: "";
}
  • counter-reset: page N 重置页码计数器,N 是起始值(0 表示第一页显示为 1)
  • 必须配合 counter-increment: page 才能推进计数,否则页码始终为重置值
  • 分节页码在 WeasyPrint 中效果稳定;Puppeteer 的 footerTemplate 不支持动态计数器,只能靠服务端预生成 HTML 分节
页码不是“插”进去的,是 PDF 渲染引擎在分页时按规则注入的。最容易忽略的是:displayHeaderFooter: true 这个开关,以及 @page 规则必须放在顶层 CSS(不能套在 .container 里),否则整段规则静默失效。