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

JSPDF结合autotable实现所有页面添加带页码的页眉页脚

JSPDF搭配jspdf-autotable实现全页面统一带页码页眉页脚方案

问题现状

  • 已基于jspdf-autotable完成模拟数据表格的PDF导出流程,可正常生成基础PDF文件
  • 现有导出的PDF仅在最后一页展示自定义页眉,无法实现所有页面统一排布页眉、带页码的页脚
  • 原始可复现代码参考:CodeSandbox 示例

核心根因

  • 自定义HTML页眉是在表格全部生成完成后,通过doc.fromHTML(string)追加到文档末尾,导致所有自定义内容堆叠在最后一页,无法跨页复用
  • 未使用jspdf-autotable内置的跨页渲染钩子,没有为每一页预留固定的页眉、页脚边距空间
  • 初始代码中startY: doc.autoTable() + 70的取值逻辑错误,会额外触发一次空表格渲染,干扰文档布局计算

修复后完整实现代码

import jsPDF from "jspdf";
import "jspdf-autotable";
import { datas } from "./data";
import { renderToString } from "react-dom/server";
import PdfDocument from "./PdfDocument";

export default function App() {
  const columns = [
    { title: "Rank", dataKey: "Rank" },
    { title: "Name", dataKey: "Name" },
    { title: "count", dataKey: "count" }
  ];

  const rows = datas?.map((data) => ({
    Rank: data?.Rank,
    Name: data?.Name,
    count: data?.count
  }));

  const downloadPdf = () => {
    // 提前将自定义页眉HTML转成字符串,避免后续重复渲染
    const headerHtmlString = renderToString(<PdfDocument />);
    const doc = new jsPDF("p", "pt");
    doc.setFontSize(20);
    doc.setTextColor(40);
    doc.setFontStyle("normal");

    doc.autoTable(columns, rows, {
      // 修正startY取值:直接预留70pt的页眉空间,不再错误调用autoTable()
      startY: 70,
      // 上下边距适配页眉、页脚预留空间,避免内容重叠
      margin: { top: 70, bottom: 40, horizontal: 10 },
      styles: { overflow: "linebreak" },
      bodyStyles: { valign: "top" },
      columnStyles: { email: { columnWidth: "wrap" } },
      theme: "striped",
      showHead: "everyPage",
      // 利用内置钩子:每一页绘制完成后自动执行,实现全页统一内容渲染
      didDrawPage: () => {
        const pageWidth = doc.internal.pageSize.width;
        // 1. 每一页固定位置渲染页眉
        doc.setFontSize(14);
        doc.setTextColor(40);
        // 从第一页开始把自定义HTML页眉渲染到顶部固定位置
        doc.fromHTML(headerHtmlString, 10, 30, {
          width: pageWidth - 20
        });

        // 2. 每一页固定位置渲染居中页脚+页码
        const currentPage = doc.getCurrentPageInfo().pageNumber;
        const totalPage = doc.getNumberOfPages();
        doc.setFontSize(10);
        doc.setTextColor(100);
        doc.text(
          `第 ${currentPage} 页 / 共 ${totalPage} 页`,
          pageWidth / 2,
          doc.internal.pageSize.height - 20,
          { align: "center" }
        );
      }
    });

    doc.save("random.pdf");
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button onClick={downloadPdf}> Download PDF </button>
    </div>
  );
}

关键实现说明

  • 核心依赖:jspdf-autotable提供的didDrawPage钩子,会在每一页的内容绘制流程中触发,无需手动遍历所有页面即可实现全页统一内容渲染
  • 边距适配逻辑:将表格的顶部边距设置为和页眉预留高度一致、底部边距和页脚预留高度一致,从布局上避免表格内容和页眉、页脚发生重叠
  • 页码动态计算:通过doc.getCurrentPageInfo().pageNumber获取当前页码、doc.getNumberOfPages()获取全文档总页数,无需手动维护页码计数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 20:36:03