---
title: "使用页眉和页脚扩展您的 PDF 导出"
description: "学习如何使用 Export PDF 扩展，自定义 PDF 导出的页眉和页脚。"
canonical_url: "https://tiptap.zhcndoc.com/conversion/export/pdf/headers-footers"
---

# 使用页眉和页脚扩展您的 PDF 导出

学习如何使用 Export PDF 扩展，自定义 PDF 导出的页眉和页脚。

- **1. 激活试用或订阅**

  在您的账号中开始[免费试用](https://cloud.tiptap.dev/v2?trial=true)或[订阅 Start 计划](https://cloud.tiptap.dev/v2/billing)。
- **2. 从私有注册表安装**

  若要安装此前端扩展，请按照[设置指南](https://tiptap.zhcndoc.com/guides/pro-extensions.md)认证访问 Tiptap 的私有 npm 注册表。

`@tiptap-pro/extension-export-pdf` 扩展内置支持自定义导出文档的页眉和页脚。您可以为首页、奇数页和偶数页配置不同的页眉和页脚。

## 页眉和页脚槽位值

每个页眉和页脚槽位（`default`、`first`、`even`）都接受以下形态之一。可在各槽位间自由混用和匹配；选择最符合您数据的那一种。

| 形态                           | 示例                                         | 说明                                                               |
| ---------------------------- | ------------------------------------------ | ---------------------------------------------------------------- |
| 纯文本                          | `'Company name, 2026'`                     | 渲染为无样式的页眉/页脚。                                                    |
| 字符串化的 Tiptap JSONContent     | `JSON.stringify(myHeaderDoc)`              | 预先序列化的 Tiptap 节点。渲染时会保留富文本格式（粗体、斜体、链接等）。                         |
| Tiptap JSONContent 对象        | `{ type: 'doc', content: [/* … */] }`      | 直接传入的 Tiptap 节点。与字符串化 JSONContent 的保真度相同，但无需执行 `JSON.stringify`。 |
| `docx` `Header` / `Footer`   | `new Docx.Header({ children: [/* … */] })` | 对段落和运行项提供完整的 DOCX 级别控制。需要 `@tiptap-pro/extension-export-docx`。   |
| 返回 `Header` / `Footer` 的异步工厂 | `() => convertHeader({ node })`            | 在执行导出时按需构建。典型用法：使用 DOCX 扩展中的 `convertHeader` / `convertFooter`。  |

Tiptap JSONContent 对象**必须**包含一个 `type` 字段。该扩展在运行时使用它来区分 Tiptap 节点和 `docx` 实例。不包含 `type` 且又不是 `Header` / `Footer` 实例的对象会被丢弃，并通过 `console.warn` 提示有问题的值；它们绝不会被转发到 DOCX 序列化器。

在 TypeScript 中，这些会收敛为两个别名（`type` 要求被编码在 `TiptapNodeContent` 中）：

```ts
import type { JSONContent } from '@tiptap/core'
import type { Footer, Header } from 'docx'

type TiptapNodeContent = JSONContent & { type: string }

type HeaderSlotValue = string | TiptapNodeContent | Header | (() => Promise<Header>)
type FooterSlotValue = string | TiptapNodeContent | Footer | (() => Promise<Footer>)
```

前三种形态可直接与 `@tiptap-pro/extension-export-pdf` 一起使用。`Header` / `Footer` 实例以及异步工厂形态需要安装 `@tiptap-pro/extension-export-docx`；它们会走优先使用 DOCX 的导出路径，并按需加载，因此不会影响仅使用 PDF 的消费者。

## 页眉配置

`headers` 对象用于配置运行中的页眉。每个槽位都接受一个[页眉槽位值](#header-and-footer-slot-values)。

| 属性                   | 类型                | 说明                                                      |
| -------------------- | ----------------- | ------------------------------------------------------- |
| `evenAndOddHeaders`  | `boolean`         | 是否为奇数页和偶数页使用不同的页眉。                                      |
| `differentFirstPage` | `boolean`         | 是否在第一页使用不同的页眉。当为 `true` 时，第一页使用 `first` 值而不是 `default`。 |
| `default`            | `HeaderSlotValue` | 每一页的标准默认页眉；当 `evenAndOddHeaders` 启用时，则表示奇数页页眉。          |
| `first`              | `HeaderSlotValue` | 第一页的页眉。仅在 `differentFirstPage` 为 `true` 时使用。            |
| `even`               | `HeaderSlotValue` | 偶数页的页眉。仅在 `evenAndOddHeaders` 为 `true` 时使用。             |

## 页脚配置

`footers` 对象与 `headers` 相同。每个槽位都接受一个[页脚槽位值](#header-and-footer-slot-values)。

| 属性                   | 类型                | 说明                                                      |
| -------------------- | ----------------- | ------------------------------------------------------- |
| `evenAndOddFooters`  | `boolean`         | 是否为奇数页和偶数页使用不同的页脚。                                      |
| `differentFirstPage` | `boolean`         | 是否在第一页使用不同的页脚。当为 `true` 时，第一页使用 `first` 值而不是 `default`。 |
| `default`            | `FooterSlotValue` | 每一页的标准默认页脚；当 `evenAndOddFooters` 启用时，则表示奇数页页脚。          |
| `first`              | `FooterSlotValue` | 第一页的页脚。仅在 `differentFirstPage` 为 `true` 时使用。            |
| `even`               | `FooterSlotValue` | 偶数页的页脚。仅在 `evenAndOddFooters` 为 `true` 时使用。             |

## 完整示例

```js
import { ExportPdf } from '@tiptap-pro/extension-export-pdf'

const editor = new Editor({
  extensions: [
    // 其他扩展...
    ExportPdf.configure({
      token: 'YOUR_TOKEN',
      headers: {
        evenAndOddHeaders: true,
        default: '我的文档 - 机密',
        first: '欢迎阅读我的文档',
        even: '我的文档 - 偶数页',
      },
      footers: {
        evenAndOddFooters: true,
        default: '公司名称 - 保留所有权利',
        first: '草稿版本 1.0',
        even: '公司名称 - 偶数页页脚',
      },
    }),
    // 其他扩展...
  ],
})

// 使用页眉和页脚导出
editor
  .chain()
  .exportPdf({
    onCompleteExport(result) {
      const url = URL.createObjectURL(result)
      const a = document.createElement('a')

      a.href = url
      a.download = '带页眉页脚的文档.pdf'
      a.click()

      URL.revokeObjectURL(url)
    },
  })
  .run()
```

## 简单的页眉和页脚

如果不需要为奇数页和偶数页使用不同的页眉，可以只提供 `default` 值：

```js
ExportPdf.configure({
  token: 'YOUR_TOKEN',
  headers: {
    default: '我的文档标题',
  },
  footers: {
    default: '页脚 - 公司名称',
  },
})
```

## 通过 Tiptap JSONContent 提供富文本页眉

直接在任意槽位上传入一个 Tiptap JSONContent 节点。如果您已经在内存中拥有该节点，并且不想手动构建一个 `Docx.Header`，这会很有用：

```js
ExportPdf.configure({
  token: 'YOUR_TOKEN',
  headers: {
    default: {
      type: 'doc',
      content: [
        {
          type: 'paragraph',
          content: [
            { type: 'text', marks: [{ type: 'bold' }], text: '我的文档' },
            { type: 'text', text: ' · 机密' },
          ],
        },
      ],
    },
  },
})
```

## Docx Header / Footer 示例

如果您需要对段落属性、对齐方式和运行样式进行完全控制，可以传入一个 `docx` `Header` / `Footer` 实例（或返回其实例的异步工厂）。这要求在安装 PDF 扩展的同时也安装 `@tiptap-pro/extension-export-docx`：

```ts
import { Docx, convertHeader } from '@tiptap-pro/extension-export-docx'

ExportPdf.configure({
  token: 'YOUR_TOKEN',
  headers: {
    // 直接的 Docx.Header 实例
    default: new Docx.Header({
      children: [
        new Docx.Paragraph({
          children: [new Docx.TextRun({ text: '我的文档' })],
        }),
      ],
    }),
    // 异步工厂：按需将 Tiptap 节点转换为 Docx.Header
    first: () =>
      convertHeader({
        node: {
          type: 'doc',
          content: [
            { type: 'paragraph', content: [{ type: 'text', text: '欢迎' }] },
          ],
        },
      }),
  },
})
```
