
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()
这里的关键是 PdfPageNumberField 和 PdfPageCountField 两个自动字段:它们不存储具体数值,而是在渲染时自动替换为当前页码和总页数,因此无需手动遍历页面计算。PdfCompositeField 负责把多个字段组合到一段格式化文本中。模板对象的 Foreground 属性设为 False,表示模板内容位于页面内容的底层,不会遮挡正文。
实用技巧
- 保留原有页面内容 :直接向已有页面绘制页眉页脚会覆盖正文。可以先通过
page.CreateTemplate()将原页面保存为模板,在新页面中先绘制页眉页脚,再通过PdfGraphicsWidget将原内容绘制到底层,从而在不损坏内容的前提下添加页眉页脚。 - 半透明效果 :调用
page.Canvas.SetTransparency(0.5)可以降低后续绘制内容的透明度,让页眉页脚以类似水印的形式呈现,视觉上更柔和。 - 注意字体嵌入 :
PdfTrueTypeFont构造函数的最后一个布尔参数控制字体是否嵌入文档,设为True可以保证文档在其他设备上打开时字体显示一致。
总结
本文介绍了使用 Python 为 PDF 文档添加页眉页脚的几种方式:通过画布绘制文本和图片实现自定义页眉页脚、按页面索引为不同页面设置不同内容,以及使用页面模板配合自动字段统一管理页码。实际开发中可以根据文档结构选择合适的方式------简单的统一页眉页脚用遍历绘制即可,需要自动页码或批量生成时,页面模板是更省心的选择。
掌握这些方法后,可以进一步结合查找替换、水印、图层等操作,构建完整的文档自动化处理流程。