我的知识记录

Python批量给PDF添加页码 底部居中教程

用Python+PyPDF2+reportlab给整本PDF每页底部自动添加页码,支持自定义位置、字体大小、批量处理文件夹。

场景痛点

合并多个PDF后总页数变多,但原文件没有统一页码,或者扫描件本身不带页码。手动用Word排版再转PDF太慢,用Adobe一份份加也繁琐。用Python脚本自动在每页底部居中打上"第 X 页 / 共 Y 页",批量处理一整个文件夹,几十秒搞定。

用到的库

pip install PyPDF2 reportlab

完整代码

# -*- coding: utf-8 -*-
"""
给 PDF 每页底部添加页码
"""
import io
import os
from PyPDF2 import PdfReader, PdfWriter, Transformation
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4


def _make_number_overlay(width: float, height: float, page_no: int, total: int) -> bytes:
"""
生成一个只有页码文字的透明 overlay PDF 字节流
"""
buf = io.BytesIO()
c = canvas.Canvas(buf, pagesize=(width, height))
# 在页面底部居中写 "第 X 页 / 共 Y 页"
text = f"- {page_no} / {total} -"
c.setFont("Helvetica", 10)
# 底部距边距 30pt,水平居中
c.drawCentredString(width / 2, 30, text)
c.save()
buf.seek(0)
return buf.read()


def add_page_numbers(src_path: str, out_path: str) -> None:
"""
给 PDF 每页底部加页码
"""
reader = PdfReader(src_path)
writer = PdfWriter()
total = len(reader.pages)

for i, page in enumerate(reader.pages, start=1):
# 取原页尺寸(point 为单位)
w = float(page.mediabox.width)
h = float(page.mediabox.height)

# 生成该页对应的 overlay
overlay_bytes = _make_number_overlay(w, h, i, total)
overlay_reader = PdfReader(io.BytesIO(overlay_bytes))
overlay_page = overlay_reader.pages[0]

# merge_page 把 overlay 叠加到原页上(overlay 在上面)
page.merge_page(overlay_page)
writer.add_page(page)

with open(out_path, "wb") as f:
writer.write(f)
print(f"已加页码 -> {out_path}(共 {total} 页)")


def batch_add(folder: str) -> None:
"""
批量处理文件夹下所有 PDF
"""
for name in os.listdir(folder):
if not name.lower().endswith(".pdf"):
continue
src = os.path.join(folder, name)
out = os.path.join(folder, name.replace(".pdf", "_已加页码.pdf"))
try:
add_page_numbers(src, out)
except Exception as e:
print(f"失败 {name}: {e}")


if __name__ == "__main__":
add_page_numbers("原文件.pdf", "原文件_已加页码.pdf")
# 批量:
# batch_add("./待加页码")

代码讲解

  • 思路分两步:① 用 reportlab 生成一个和原页同样大小的透明PDF,里面只有页码文字;② 用 PyPDF2 的 merge_page() 把它叠加到原页上。
  • page.mediabox.width/height 拿到原页尺寸(PDF单位是 point,1pt=1/72英寸)。
  • c.drawCentredString(width/2, 30, ...) 在底部距边距 30pt 处水平居中写页码。
  • merge_page(overlay_page) 把两个页面内容合成一页,原内容在下、页码在上。
  • 批量函数遍历文件夹,自动输出"原名_已加页码.pdf",不覆盖原文件。

运行结果

生成 原文件_已加页码.pdf,每页底部居中都有 - 1 / 28 - 样式的页码。用任意PDF阅读器翻到底部即可看到。

注意事项

  • reportlab 内置字体只支持英文,中文页码会显示成方块。如果要写"第 X 页"中文,需要 c.setFont("STSong-Light", 10) 并注册中文字体(见reportlab CIDFont)。
  • 页码会盖在原内容之上,如果原页底部本来就有内容,可能遮挡,可调 y 坐标或换到顶部。
  • merge_page 是透明叠加,不会改变原页面的矢量内容,所以文件大小基本不变。
  • 扫描件PDF加页码同样有效,因为页码是后叠加的矢量文本。

Python批量给PDF添加页码 底部居中教程

标签:

更新时间:2026-09-14 21:41:26

上一篇:Python给PDF添加文字水印:PyMuPDF批量防泄密

下一篇:Python给PDF添加图片水印:Logo铺满每页防篡改