在批量处理 PDF 文档时,经常需要给已有文档统一添加页码。借助 Spire.PDF for Python,我们可以直接在现有 PDF 的画布上绘制动态页码,不需要先生成 PDF 再二次合并。

本文示例实现:在 PDF 页脚居中绘制页码,并重点讲解 如何自定义页码的显示样式 (例如 第 X 页、X / Y 等不同格式),以及如何通过坐标把页码摆放到任意位置(页脚靠左 / 居中 / 靠右,或页眉任意位置)。
单位说明:PDF 坐标单位为 point,1 point = 1/72 英寸;页面坐标系原点在页面左上角,X 向右、Y 向下。
先安装依赖库:
pip install spire.pdf添加页码的核心是两组 "动态域":
它们是动态的,不是写死的字符串,所以即使页面数量变化,页码也会自动保持正确。
PdfCompositeField 可以把静态文本模板和动态域组合成一行完整文本。 页码的显示样式,就是由这段模板字符串决定的 ,我们只需修改它即可。
基本用法:
compositeField = PdfCompositeField(font, brush, "模板文本", [域1, 域2, ...])其中 {0} 依次对应列表里的第一个域,{1} 对应第二个域,以此类推。
下面示例使用 第 {0} 页,共 {1} 页 的样式,页码居中显示,并附带一条分隔线:
from spire.pdf.common import *
from spire.pdf import *
# 创建 PdfDocument 对象
doc = PdfDocument()
# 加载本地 PDF 文件
doc.LoadFromFile("input.pdf")
# 定义支持中文的宋体字体、画刷、画笔
font = PdfTrueTypeFont("宋体", 14.0, PdfFontStyle.Regular, True)
brush = PdfBrushes.get_Black()
pen = PdfPen(brush, 1.0)
# 设置边距
leftMargin = 54.0
rightMargin = 54.0
bottomMargin = 72.0
# 页码域:当前页码、总页数
pageNumberField = PdfPageNumberField()
pageCountField = PdfPageCountField()
# 组合域,使用中文页码模板
compositeField = PdfCompositeField(font, brush, "第 {0} 页,共 {1} 页", [pageNumberField, pageCountField])
# 遍历所有页面
for i in range(doc.Pages.Count):
page = doc.Pages.get_Item(i)
pageSize = page.Size
# 在页脚绘制分隔线
page.Canvas.DrawLine(
pen,
leftMargin,
pageSize.Height - bottomMargin + 15.0,
pageSize.Width - rightMargin,
pageSize.Height - bottomMargin + 15.0
)
# 测量页码文本所占宽度,用于居中计算
text = "第 {} 页,共 {} 页".format(i + 1, doc.Pages.Count)
pageNumberSize = font.MeasureString(text)
# 设置页码坐标:水平居中
compositeField.Location = PointF(
(pageSize.Width - pageNumberSize.Width) / 2,
pageSize.Height - bottomMargin + 18.0
)
# 绘制页码
compositeField.Draw(page.Canvas, 0.0, 0.0)
# 保存新文件
doc.SaveToFile("Output/CenterAlignedPageNumbers.pdf")
# 释放资源
doc.Dispose()页码长什么样,只取决于模板字符串和放入的动态域。下面是几种常用样式,只需替换 PdfCompositeField 的第三个参数(以及按需调整要传入的域):
第 X 页只需要页码域,不传总页数域:
compositeField = PdfCompositeField(
font, brush, "第 {0} 页", [pageNumberField]
)X / YcompositeField = PdfCompositeField(
font, brush, "{0} / {1}", [pageNumberField, pageCountField]
)第 X 页 / 共 Y 页compositeField = PdfCompositeField(
font, brush, "第 {0} 页 / 共 {1} 页", [pageNumberField, pageCountField]
)共 Y 页compositeField = PdfCompositeField(
font, brush, "共 {1} 页", [pageNumberField, pageCountField]
)说明:即使某个域没有出现在模板里,它仍会被创建并传入列表,但不会显示;模板里写的字段顺序和数量可以自由组合,前后缀文字(如 "第"、"页"、"共"、"/")都可以随意调整,符合你的排版需求即可。
页码位置完全由 compositeField.Location = PointF(x, y) 决定:
x = (页面宽度 - 文本宽度) / 2x = leftMarginx = pageSize.Width - pageNumberSize.Width - rightMargin下面是同时设置样式和位置的示例(页脚右侧 + X / Y 样式):
compositeField = PdfCompositeField(font, brush, "{0} / {1}", [pageNumberField, pageCountField])
for i in range(doc.Pages.Count):
page = doc.Pages.get_Item(i)
pageSize = page.Size
text = "{} / {}".format(i + 1, doc.Pages.Count)
pageNumberSize = font.MeasureString(text)
# 右对齐:X 坐标 = 页面宽度 - 文本宽度 - 右边距
compositeField.Location = PointF(
pageSize.Width - pageNumberSize.Width - rightMargin,
pageSize.Height - bottomMargin + 18.0
)
compositeField.Draw(page.Canvas, 0.0, 0.0)宋体,如果运行环境找不到,可替换为 "微软雅黑" 等其他支持中文的字体。bottomMargin 或 topMargin,给页脚 / 页眉留出更多空白。这套方案把 "页码显示什么样式"(模板字符串)和 "显示在什么位置"(坐标)完全解耦,两者都可以自由定制。你只需改模板字符串就能切换 第 X 页、X / Y、第 X 页,共 Y 页 等任意格式,改 Location 坐标就能把页码放到页脚或页眉的任意位置,非常适合批量处理 PDF 时统一规范页码格式。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。