在日常办公、文档处理或自动化流程中,我们经常会遇到 PDF 页面方向错误的问题------比如扫描件横置、部分页面倒置,或者从不同来源合并的 PDF 页向不统一。手动用 Adobe Acrobat 或其他工具逐页调整既耗时又低效。
幸运的是,借助 Python 和开源库 PyPDF2 (或其继任者 pypdf ),我们可以几行代码轻松实现 PDF 页面的自动旋转,甚至支持批量处理!本文将带你从零开始,完成一个实用的 PDF 页面方向调整脚本。
一、准备工作:安装依赖
推荐使用 pypdf(PyPDF2 的现代维护版本,性能更好、API 更清晰):
pip install pypdf
💡 注意:如果你仍在使用旧版
PyPDF2,大部分代码也兼容,但建议迁移到pypdf。
二、核心原理:PDF 页面的旋转机制
在 PDF 中,每个页面都有一个 /Rotate 属性,表示顺时针旋转角度,必须是 90 的整数倍(如 0、90、180、270)。
0:正常方向90:向右旋转 90°(横屏)180:倒置270:向左旋转 90°
通过修改该属性,即可无损调整页面显示方向,无需重新渲染图像或内容。
三、基础示例:旋转指定页面
以下代码将 PDF 的第 1 页(索引 0)顺时针旋转 90°:
python
from pypdf import PdfReader, PdfWriter
def rotate_page(input_pdf, output_pdf, page_number, rotation=90):
reader = PdfReader(input_pdf)
writer = PdfWriter()
for i, page in enumerate(reader.pages):
if i == page_number:
page.rotate(rotation) # 旋转角度(90, 180, 270)
writer.add_page(page)
with open(output_pdf, "wb") as f:
writer.write(f)
# 使用示例:旋转第1页(索引0)90度
rotate_page("input.pdf", "output_rotated.pdf", page_number=0, rotation=90)
✅
page.rotate()会累加旋转角度。若页面原本是 90°,再调用rotate(90)将变为 180°。如需强制设为某个方向 ,可先重置为 0:
page.rotate(-page.get("/Rotate", 0)),再设置新值。
四、进阶实战:批量处理所有页面
场景 1:将整个 PDF 所有页面统一旋转 180°(如全部倒置的扫描件)
scss
def rotate_all_pages(input_pdf, output_pdf, rotation=180):
reader = PdfReader(input_pdf)
writer = PdfWriter()
for page in reader.pages:
page.rotate(rotation)
writer.add_page(page)
with open(output_pdf, "wb") as f:
writer.write(f)
rotate_all_pages("scanned.pdf", "corrected.pdf", rotation=180)
场景 2:智能检测并修正"横置"页面(假设奇数页应为纵向,偶数页为横向)
ini
def smart_rotate_by_index(input_pdf, output_pdf):
reader = PdfReader(input_pdf)
writer = PdfWriter()
for i, page in enumerate(reader.pages):
if i % 2 == 1: # 偶数页(索引从0开始)
# 如果当前未旋转,则设为90度
current_rot = page.get("/Rotate", 0)
if current_rot == 0:
page.rotate(90)
writer.add_page(page)
with open(output_pdf, "wb") as f:
writer.write(f)
五、实用工具函数:命令行调用
将脚本封装为命令行工具,方便日常使用:
python
# pdf_rotate.py
import argparse
from pypdf import PdfReader, PdfWriter
def main():
parser = argparse.ArgumentParser(description="旋转 PDF 页面方向")
parser.add_argument("input", help="输入 PDF 文件路径")
parser.add_argument("output", help="输出 PDF 文件路径")
parser.add_argument("--angle", type=int, default=90, choices=[90, 180, 270], help="旋转角度")
parser.add_argument("--page", type=int, help="指定页码(从1开始),不填则旋转所有页")
args = parser.parse_args()
reader = PdfReader(args.input)
writer = PdfWriter()
for i, page in enumerate(reader.pages):
if args.page is None or i == args.page - 1:
page.rotate(args.angle)
writer.add_page(page)
with open(args.output, "wb") as f:
writer.write(f)
print(f"✅ 已保存至: {args.output}")
if __name__ == "__main__":
main()
使用方式:
lua
# 旋转第3页 270度
python pdf_rotate.py input.pdf output.pdf --page 3 --angle 270
# 全部页面旋转180度
python pdf_rotate.py input.pdf output.pdf --angle 180
六、注意事项与局限
- 仅修改元数据,不重绘内容:旋转是"视图级"操作,不影响原始文本或图像数据。
- 角度必须是 90 的倍数 :否则
rotate()会报错。 - 加密 PDF 需先解密 :
pypdf支持读取带密码的 PDF(reader.decrypt("password")),但无法修改加密文件。 - 保留书签与注释 :上述方法默认会丢失书签(outlines)。如需保留,需额外处理(
writer.add_outline_item())。
结语
通过 Python + pypdf,我们不仅解决了 PDF 页面方向问题,还构建了一个可复用、可扩展的文档处理工具。无论是个人整理资料,还是集成到企业自动化流程中,这类脚本都能显著提升效率。
🌟 小提示 :结合
watchdog库,你甚至可以实现"监控文件夹,自动修正新放入的 PDF 方向"!
从此,再也不用手动一页页拖拽旋转------让代码为你打工!