Python操作PDF文件
PDF(Portable Document Format,便携式文档格式)作为跨平台、格式固定的标准化文件,在办公和开发中无处不在 —— 合同签署、报告分享、学术论文分发都离不开它。日常工作中,我们常遇到提取 PDF 文本、批量加水印、加密敏感文档等需求,手动操作繁琐且易出错。今天就用 Python 手把手教你搞定这些操作,覆盖「读取编辑」「创建生成」全场景,代码直接复制可用!
一、核心工具准备:3 个必备三方库
Python 操作 PDF 的核心需求分两类:编辑现有 PDF(提取文本、旋转页面、加密、水印)和创建新 PDF,对应 3 个实用三方库,安装简单,国内用户建议用清华源加速:
# 1. PyPDF2(核心):读取/编辑现有PDF(提取文本、旋转、加密、水印)pip install PyPDF2 -i https://pypi.tuna.tsinghua.edu.cn/simple# 2. reportlab:创建空白PDF,添加文本/图片/字体pip install reportlab -i https://pypi.tuna.tsinghua.edu.cn/simple# 3. pdfminer.six(补充):优化中文文本提取,支持命令行快速操作pip install pdfminer.six -i https://pypi.tuna.tsinghua.edu.cn/simple
✨ 资源获取:文中用到的测试 PDF、字体文件、水印模板,可通过百度云盘获取:链接:https://pan.baidu.com/s/1rQujl5RQn9R7PadB2Z5g_g,提取码:e7b4
二、实战操作:从 PDF 提取文本(3 种方法)
提取文本是 PDF 操作最高频需求,比如提取合同关键信息、统计文档内容。下面分享 3 种方法,覆盖不同场景:
方法 1:PyPDF2(代码集成首选)
PyPDF2 轻量简洁,可直接整合到批量处理脚本中,但对中文提取支持一般,适合英文 / 简单中文 PDF:
import PyPDF2defextract_text_with_pypdf2(pdf_path):# 打开PDF文件(注意:路径需正确,相对路径需与脚本同目录)withopen(pdf_path, 'rb') as f:# 创建PDF读取对象(最新版本用PdfReader,替代旧版PdfFileReader) reader = PyPDF2.PdfReader(f)# 遍历所有页面,提取文本 total_text = ""for page_num, page inenumerate(reader.pages, 1):# 提取单页文本,空字符串表示无可用文本(如扫描版PDF) page_text = page.extract_text() or"" total_text += f"第{page_num}页:\n{page_text}\n"return total_text# 调用函数,提取test.pdf的文本result = extract_text_with_pypdf2("test.pdf")print(result)
⚠️ 易错点:扫描版 PDF(图片转 PDF)无法直接提取文本,需搭配 OCR 工具(如 pytesseract)。
方法 2:pdfminer.six(命令行快速提取)
# 安装后直接执行命令,格式:pdf2text.py + PDF路径pdf2text.py test.pdf# 进阶:提取文本并保存到文件(避免终端输出过长)pdf2text.py test.pdf -o 提取结果.txt
方法 3:pdfplumber(中文提取神器)
如果前两种方法提取中文乱码,试试 pdfplumber(需额外安装pip install pdfplumber),专为中文优化:
import pdfplumberdefextract_chinese_text(pdf_path):with pdfplumber.open(pdf_path) as pdf: total_text = ""for page_num, page inenumerate(pdf.pages, 1):# 精准提取中文,保留排版结构 page_text = page.extract_text() or"" total_text += f"第{page_num}页:\n{page_text}\n"return total_text# 调用函数print(extract_chinese_text("test.pdf"))
三、进阶操作:旋转页面、加密、批量水印
掌握基础提取后,再来解锁 3 个实用功能,解决办公痛点:
1. 旋转 PDF 页面(修复方向错误)
遇到横屏、倒置的 PDF,批量旋转更高效:
import PyPDF2defrotate_pdf(input_path, output_path):# 读取原始PDF reader = PyPDF2.PdfReader(input_path) writer = PyPDF2.PdfWriter() # 创建写入对象,保存处理后PDF# 自定义旋转规则:偶数页逆时针90度,奇数页顺时针90度for page_num, page inenumerate(reader.pages):if page_num % 2 == 0: rotated_page = page.rotate(-90) # 负数=逆时针else: rotated_page = page.rotate(90) # 正数=顺时针 writer.add_page(rotated_page)# 保存结果(必须用wb模式,二进制写入)withopen(output_path, 'wb') as f: writer.write(f)# 调用函数:处理XGBoost.pdf,输出temp.pdfrotate_pdf("XGBoost.pdf", "temp.pdf")print("页面旋转完成!")
✅ 技巧:旋转角度仅支持 90、180、270 度(90 的整数倍),其他角度无效。
2. 加密 PDF(保护敏感文档)
给合同、机密报告加密,设置统一口令,批量处理超方便:
import PyPDF2defencrypt_pdf(input_path, output_path, password): reader = PyPDF2.PdfReader(input_path) writer = PyPDF2.PdfWriter()# 复制所有页面到写入对象for page in reader.pages: writer.add_page(page)# 设置加密口令(支持简单密码,无特殊字符兼容性更好) writer.encrypt(password)# 保存加密后的PDFwithopen(output_path, 'wb') as f: writer.write(f)# 调用函数:给XGBoost.pdf加密,口令foobaredencrypt_pdf("XGBoost.pdf", "加密后的PDF.pdf", "foobared")print("PDF加密完成,打开需输入口令:foobared")
⚠️ 注意:PyPDF2 仅支持标准加密,密码丢失无法破解,务必牢记!
3. 批量添加水印(标识文档用途)
给 PDF 加 “机密”“草稿” 水印,避免滥用,支持奇偶页不同水印:
import PyPDF2defadd_watermark(input_pdf, watermark_pdf, output_pdf, odd_watermark=None):# 读取原始PDF和水印PDF main_reader = PyPDF2.PdfReader(input_pdf) watermark_reader = PyPDF2.PdfReader(watermark_pdf) writer = PyPDF2.PdfWriter()# 提取水印页(默认取第一页) base_watermark = watermark_reader.pages[0]# 若指定奇数页水印,读取第二个水印PDF odd_wm_page = PyPDF2.PdfReader(odd_watermark).pages[0] if odd_watermark else base_watermark# 遍历原始页面,批量添加水印for page_num, page inenumerate(main_reader.pages, 1):# 复制原始页(避免修改原页面) current_page = page# 选择水印:奇数页用专属水印,偶数页用基础水印 watermark = odd_wm_page if page_num % 2 == 1else base_watermark# 叠加水印(水印在上,原始页在下,顺序不可颠倒) current_page.merge_page(watermark) writer.add_page(current_page)# 保存结果withopen(output_pdf, 'wb') as f: writer.write(f)# 调用函数:基础用法(所有页同一水印)add_watermark("XGBoost.pdf", "watermark.pdf", "带水印的PDF.pdf")# 进阶用法(奇数页用watermark1.pdf,偶数页用watermark.pdf)# add_watermark("XGBoost.pdf", "watermark.pdf", "奇偶页不同水印.pdf", "watermark1.pdf")print("水印添加完成!")
✨ 技巧:水印 PDF 建议制作成半透明(如 50% 透明度),避免遮挡原始文本,可用 WPS/PS 制作。
四、从零创建 PDF:reportlab 实战
除了编辑现有 PDF,还能从零创建自定义 PDF(如报表、证书),用 reportlab 库轻松实现:
from reportlab.lib.pagesizes import A4from reportlab.pdfbase import pdfmetricsfrom reportlab.pdfbase.ttfonts import TTFontfrom reportlab.pdfgen import canvasdefcreate_custom_pdf(output_path):# 1. 创建画布对象,指定A4尺寸 c = canvas.Canvas(output_path, pagesize=A4) width, height = A4 # A4尺寸:595点(宽)× 842点(高)# 2. 插入图片(需确保图片路径正确) img = canvas.ImageReader("resources/guido.jpg")# drawImage(图片, x坐标, y坐标, 宽度, 高度),原点在页面左下角 c.drawImage(img, 20, height - 395, 250, 375)# 3. 新建页面(如需多页PDF) c.showPage()# 4. 注册中文字体(解决中文乱码核心步骤) pdfmetrics.registerFont(TTFont("青呱石头体", "resources/fonts/青呱石头体.ttf")) pdfmetrics.registerFont(TTFont("Vera", "resources/fonts/Vera.ttf"))# 5. 添加带样式的文本# 中文文本:橙红色、40号字、水平居中 c.setFont("青呱石头体", 40) c.setFillColorRGB(0.9, 0.5, 0.3, 1) # RGB颜色+透明度 c.drawString(width//2 - 120, height//2, "你好,世界!")# 英文文本:绿色、40号字、旋转18度 c.setFont("Vera", 40) c.setFillColorRGB(0, 1, 0, 0.5) c.rotate(18) # 顺时针旋转18度 c.drawString(250, 250, "hello, world!")# 6. 保存PDF(必须调用,否则文件不生成) c.save()# 调用函数,创建demo.pdfcreate_custom_pdf("resources/demo.pdf")print("PDF创建完成!")
⚠️ 易错点:中文乱码是因为未注册中文字体,需提前准备.ttf格式字体文件,路径不能错。
五、常见问题避坑指南
中文提取乱码:优先用 pdfplumber,其次 pdfminer.six,PyPDF2 适合英文;
水印不显示:检查水印 PDF 路径是否正确,叠加顺序是否为「原始页.merge_page (水印页)」;
代码报错 “无模块”:确认库名拼写(PyPDF2 首字母大写),重新安装库;
扫描版 PDF 提取失败:需搭配 OCR 工具(如pip install pytesseract),结合图片识别提取文本。
总结
Python 操作 PDF 的核心优势在于「批量处理」和「自动化」—— 一次写代码,终身免手动。今天分享的提取文本、旋转页面、加密、水印、创建 PDF,覆盖了 90% 的办公场景,代码直接复制可用。如果需要更复杂的功能(如合并多个 PDF、拆分 PDF、提取表格),可以在评论区告诉我,后续出进阶教程!赶紧动手试试,让 Python 帮你解放双手~