如何使用 Python 为 PDF 添加文本页眉和页脚

PDF 是文档分发和存档的标准格式,而页眉和页脚是正式文档中不可或缺的组成部分------公司名称、文档标题、章节信息、页码等元素都依赖它们来呈现。对于开发人员来说,手动为一份几十页甚至上百页的 PDF 添加页眉页脚显然不现实,尤其是当文档需要定期批量生成时,编程方式几乎是唯一可行的选择。

本文将介绍如何使用 Python 为 PDF 文档添加页眉和页脚,包括纯文本页眉页脚、图片页眉、为不同页面设置不同页眉,以及通过页面模板自动生成页码等内容。

为什么需要编程添加页眉页脚

在代码中处理 PDF 页眉页脚,相比手动编辑有几点实际优势:

  • 批量处理 - 用循环遍历所有页面,一次调用即可为整份文档添加统一的页眉页脚
  • 动态内容 - 页码、章节号等内容可以根据文档状态自动生成,无需人工维护
  • 样式一致 - 字体、颜色、对齐方式由代码统一控制,避免人工操作产生的差异

环境准备

本文使用 Spire.PDF 库实现 PDF 文档的处理,安装命令如下:

bash 复制代码
pip install Spire.PDF

该库提供完整的 PDF 创建和编辑能力。页眉页脚本质上是通过在页面画布(Canvas)上绘制文本、图片和线条来实现的。需要注意的是,PDF 的坐标系以页面左下角为原点,单位为点(1 点 = 1/72 英寸)。

添加文本页眉和页脚

为整份文档添加统一的文本页眉页脚,最常见的做法是遍历所有页面,在每个页面的画布上绘制内容。以下代码在每页顶部添加右对齐的页眉文本,在底部添加分隔线和页码:

python 复制代码
from spire.pdf.common import *
from spire.pdf import *

doc = PdfDocument()
doc.LoadFromFile("Input.pdf")
margin = doc.PageSettings.Margins

# 定义画笔、字体和对齐方式
pen = PdfPen(PdfBrushes.get_Black(), 0.75)
font = PdfTrueTypeFont("微软雅黑", 12.0, PdfFontStyle.Italic, True)
brush = PdfBrushes.get_Black()
format = PdfStringFormat(PdfTextAlignment.Right)
format.MeasureTrailingSpaces = True
space = font.Height * 0.75

for i in range(doc.Pages.Count):
    page = doc.Pages.get_Item(i)
    x = margin.Left
    width = page.Canvas.ClientSize.Width - margin.Left - margin.Right

    # 页眉:绘制分隔线 + 文本
    y = margin.Top - space
    page.Canvas.DrawLine(pen, x, y, x + width, y)
    page.Canvas.DrawString("内部资料", font, brush, x + width, y - font.Height, format)

    # 页脚:绘制分隔线 + 页码
    y = page.Canvas.ClientSize.Height - margin.Bottom + space
    page.Canvas.DrawLine(pen, x, y, x + width, y)
    label = "{0} / {1}".format(i + 1, doc.Pages.Count)
    page.Canvas.DrawString(label, font, brush, x + width, y + 1, format)

doc.SaveToFile("HeaderAndFooter.pdf")
doc.Close()

输出文档预览:

几个关键点的说明:

  • PdfTrueTypeFont 指定字体名称、字号和样式,PdfFontStyle.Italic 表示斜体,最后一个布尔参数表示是否嵌入字体
  • PdfStringFormat 控制文本对齐方式;MeasureTrailingSpaces = True 让右对齐时也计算尾随空格,保证位置精确
  • 页眉位于上边距上方、页脚位于下边距下方,font.Height * 0.75 用于在文本与分隔线之间留出合理间距

在页眉中插入图片

很多文档会在页眉放置公司 Logo。图片的插入同样在画布上进行,使用 PdfImage.FromFile() 加载图片后,调用 DrawImage() 指定绘制位置即可:

python 复制代码
headerImage = PdfImage.FromFile("Logo.png")
page.Canvas.DrawImage(headerImage, PointF(0.0, 0.0))

DrawImage() 的第二个参数是图片左上角的坐标。如果需要控制图片大小,可以额外传入宽度和高度参数(单位为点),例如将 Logo 缩小一半:

python 复制代码
page.Canvas.DrawImage(headerImage, 50.0, 20.0,
    headerImage.Width / 2.0, headerImage.Height / 2.0)

为不同页面设置不同的页眉

章节较多的文档通常需要每章使用不同的页眉。由于页眉是通过在具体页面上绘制实现的,因此只需按页面索引分别绘制即可:

python 复制代码
rect = RectangleF(PointF(0.0, 20.0), SizeF(doc.PageSettings.Size.Width, 50.0))

# 第 1 页:红色加粗、居中对齐
font1 = PdfTrueTypeFont("微软雅黑", 15.0, PdfFontStyle.Bold, True)
format1 = PdfStringFormat()
format1.Alignment = PdfTextAlignment.Center
doc.Pages[0].Canvas.DrawString("第一章 概述", font1, PdfBrushes.get_Red(), rect, format1)

# 第 2 页:黑色常规、左对齐
font2 = PdfTrueTypeFont("微软雅黑", 15.0, PdfFontStyle.Regular, True)
format2 = PdfStringFormat()
format2.Alignment = PdfTextAlignment.Left
doc.Pages[1].Canvas.DrawString("第二章 实现", font2, PdfBrushes.get_Black(), rect, format2)

这里通过 doc.Pages[索引] 直接访问指定页面,再为每页设置不同的字体、颜色和对齐方式。如果文档章节较多,可以先计算各章节对应的页码范围,再结合循环批量绘制。

使用页面模板统一管理页眉页脚

当页眉页脚需要作用于文档所有页面、且希望内容自动生效时,使用页面模板(PdfPageTemplateElement)是更优雅的方案。模板与页面内容分离,后续新增页面时会自动应用:

python 复制代码
from spire.pdf.common import *
from spire.pdf import *

# 创建文档,设置页面尺寸和边距
doc = PdfDocument()
doc.PageSettings.Size = PdfPageSize.A4()
doc.PageSettings.Margins = PdfMargins(50.0, 50.0, 50.0, 50.0)
pageSize = doc.PageSettings.Size

# 创建页眉模板:绘制 Logo 和分隔线
headerSpace = PdfPageTemplateElement(pageSize.Width, 50.0)
headerSpace.Foreground = False
image = PdfImage.FromFile("Logo.png")
headerSpace.Graphics.DrawImage(image, 50.0, 20.0, image.Width / 2.0, image.Height / 2.0)
pen = PdfPen(PdfBrushes.get_LightGray(), 1.0)
headerSpace.Graphics.DrawLine(pen, 50.0, 45.0, pageSize.Width - 50.0, 45.0)

# 创建页脚模板:使用自动字段绘制"第 x 页,共 y 页"
footerSpace = PdfPageTemplateElement(pageSize.Width, 50.0)
footerSpace.Foreground = False
footerSpace.Graphics.DrawLine(pen, 50.0, 0.0, pageSize.Width - 50.0, 0.0)
number = PdfPageNumberField()
count = PdfPageCountField()
compositeField = PdfCompositeField(
    PdfTrueTypeFont("微软雅黑", 10.0, PdfFontStyle.Regular, True),
    PdfBrushes.get_Black(), "第 {0} 页,共 {1} 页", [number, count])
compositeField.StringFormat = PdfStringFormat(PdfTextAlignment.Left, PdfVerticalAlignment.Top)
compositeField.Bounds = RectangleF(PointF(50.0, 5.0), SizeF(200.0, 20.0))
widget = PdfGraphicsWidget(compositeField.Ptr)
widget.Draw(footerSpace.Graphics)

# 将模板应用到文档的顶部和底部
doc.Template.Top = headerSpace
doc.Template.Bottom = footerSpace

# 添加页面并保存
doc.Pages.Add()
doc.SaveToFile("TemplateHeaderFooter.pdf", FileFormat.PDF)
doc.Close()

这里的关键是 PdfPageNumberFieldPdfPageCountField 两个自动字段:它们不存储具体数值,而是在渲染时自动替换为当前页码和总页数,因此无需手动遍历页面计算。PdfCompositeField 负责把多个字段组合到一段格式化文本中。模板对象的 Foreground 属性设为 False,表示模板内容位于页面内容的底层,不会遮挡正文。

实用技巧

  • 保留原有页面内容 :直接向已有页面绘制页眉页脚会覆盖正文。可以先通过 page.CreateTemplate() 将原页面保存为模板,在新页面中先绘制页眉页脚,再通过 PdfGraphicsWidget 将原内容绘制到底层,从而在不损坏内容的前提下添加页眉页脚。
  • 半透明效果 :调用 page.Canvas.SetTransparency(0.5) 可以降低后续绘制内容的透明度,让页眉页脚以类似水印的形式呈现,视觉上更柔和。
  • 注意字体嵌入PdfTrueTypeFont 构造函数的最后一个布尔参数控制字体是否嵌入文档,设为 True 可以保证文档在其他设备上打开时字体显示一致。

总结

本文介绍了使用 Python 为 PDF 文档添加页眉页脚的几种方式:通过画布绘制文本和图片实现自定义页眉页脚、按页面索引为不同页面设置不同内容,以及使用页面模板配合自动字段统一管理页码。实际开发中可以根据文档结构选择合适的方式------简单的统一页眉页脚用遍历绘制即可,需要自动页码或批量生成时,页面模板是更省心的选择。

掌握这些方法后,可以进一步结合查找替换、水印、图层等操作,构建完整的文档自动化处理流程。

相关推荐
星栈15 小时前
MCP 2026 史上最大架构重构:从会话握手到无状态协议
人工智能·后端
kisloy16 小时前
【爬虫入门第5讲】Python爬虫文本解析详解
开发语言·爬虫·python
IT_陈寒16 小时前
Vite静态资源路径这个坑差点让我加班到凌晨
前端·人工智能·后端
神经蛙199616 小时前
🌍 别再硬编码中文了!Python Web 项目国际化(i18n)完全指南
后端·python
二月龙16 小时前
Spring 事务失效的 8 种场景,很多老手依然频繁踩雷
后端
掘金酱16 小时前
「TRAE Work 实战帮」征文启动!你沉淀的经验,值得被看见!
前端·人工智能·后端
颜酱16 小时前
14 | 验证并修正 LLM 生成的 SQL
人工智能·python
长大198816 小时前
MyBatis 常见性能陷阱:N+1 查询、一级缓存踩坑解决方案
后端
用户18615580086016 小时前
MinIO Java 对接试用:从连接、上传到下载的完整示例
后端