📚 你是否曾经被PDF文件搞得焦头烂额?加密的打不开,内容复制不了,表格数据提取困难?别担心,Python来帮你!本文带你掌握10个超实用的PDF处理技巧,让你的工作效率翻倍!
大家好,我是逍遥,今天,我们聊聊用Python玩转PDF。
技巧一:PDF文件的基本读取
首先,我们需要安装一个强大的PDF处理库——PyPDF2。
# 安装PyPDF2
pip install PyPDF2
安装好后,我们就可以轻松读取PDF文件了:
# 导入PyPDF2
from PyPDF2 import PdfReader
# 打开PDF文件
reader = PdfReader("example.pdf")
# 获取页面数量
page_count = len(reader.pages)
print(f"PDF文件共有{page_count}页")
# 读取第一页内容
page = reader.pages[0]
text = page.extract_text()
print(text)
这段代码可以帮你获取PDF的页数,并提取第一页的文本内容。如果你想读取整个PDF的内容,可以这样写:
# 读取整个PDF内容
all_text = ""
for page_num in range(len(reader.pages)):
page = reader.pages[page_num]
all_text += page.extract_text()
print(all_text)
技巧二:PDF文件的基本信息提取
了解PDF的基本信息,比如作者、标题、创建时间等,这在文档管理中非常有用:
# 导入库
from PyPDF2 import PdfReader
# 打开PDF文件
reader = PdfReader("example.pdf")
# 获取PDF元数据
metadata = reader.metadata
if metadata:
print(f"标题: {metadata.title}"
)
print(f"作者: {metadata.author}")
print(f"主题: {metadata.subject}")
print(f"创建工具: {metadata.creator}")
print(f"生产工具: {metadata.producer}")
技巧三:PDF加密与解密
有些PDF可能设置了密码保护,我们可以用Python进行解密:
# 导入库
from PyPDF2 import PdfReader, PdfWriter
# 打开加密的PDF
reader = PdfReader("encrypted.pdf")
# 检查是否加密
if reader.is_encrypted:
# 尝试解密
reader.decrypt("password") # 替换为实际密码
# 创建一个新的PdfWriter对象
writer = PdfWriter()
# 添加所有页面到新PDF
for page in reader.pages:
writer.add_page(page)
# 保存解密后的PDF
with open("decrypted.pdf", "wb") as f:
writer.write(f)
print("PDF解密成功!")
else:
print("PDF没有加密")
如果你想给PDF加密保护,可以这样做:
# 导入库
from PyPDF2 import PdfReader, PdfWriter
# 打开PDF
reader = PdfReader("example.pdf")
writer = PdfWriter()
# 添加所有页面
for page in reader.pages:
writer.add_page(page)
# 添加密码保护
writer.encrypt("your_password")
# 保存加密后的PDF
with open("encrypted.pdf", "wb") as f:
writer.write(f)
print("PDF加密成功!")
技巧四:PDF页面的提取与合并
有时候,我们可能只需要PDF的某几页,或者想将多个PDF合并成一个:
# 导入库
from PyPDF2 import PdfReader, PdfWriter
# 提取指定页面
def extract_pages(input_path, output_path, pages):
reader = PdfReader(input_path)
writer = PdfWriter()
for page_num in pages:
# 页码从0开始,所以需要减1
if 0 <= page_num - 1 < len(reader.pages):
writer.add_page(reader.pages[page_num - 1])
with open(output_path, "wb") as f:
writer.write(f)
print(f"已提取{
len(pages)}页到{output_path}")
# 提取第1、3、5页
extract_pages("example.pdf", "extracted.pdf", [1, 3, 5])
合并多个PDF:
# 导入库
from PyPDF2 import PdfReader, PdfWriter
# 合并多个PDF
def merge_pdfs(input_paths, output_path):
writer = PdfWriter()
for path in input_paths:
reader = PdfReader(path)
for page in reader.pages:
writer.add_page(page)
with open(output_path, "wb") as f:
writer.write(f)
print(f"已合并{len(input_paths)}个PDF到{output_path}")
# 合并三个PDF
merge_pdfs(["file1.pdf", "file2.pdf", "file3.pdf"], "merged.pdf")
技巧五:PDF转Word
PDF转Word是最常见的需求之一,我们可以借助 PyPDF2
库来实现:
# 使用PyPDF2和python-docx的组合
from PyPDF2 import PdfReader
from docx import Document
import io
def pdf_to_word_alternative(pdf_path, docx_path):
# 读取PDF
reader = PdfReader(pdf_path)
# 创建Word文档
doc = Document()
# 提取每页文本并添加到Word文档
for page_num in range(len(reader.pages)):
page = reader.pages[page_num]
text = page.extract_text()
# 添加页码标题
doc.add_heading(f'Page {page_num + 1}', level=1)
# 添加文本
doc.add_paragraph(text)
# 添加分页符(除了最后一页)
if page_num < len(reader.pages) - 1:
doc.add_page_break()
# 保存Word文档
doc.save(docx_path)
print(f"已将{pdf_path}转换为{docx_path}")
# 使用示例
pdf_to_word_alternative("file_data/报告模板.pdf", "file_data/报告模板.docx")
技巧六:PDF转图片
有时候,我们可能需要将PDF转换为图片,以便在社交媒体上分享:
# 安装所需库
pip install fitz
# 导入库
import fitz # PyMuPDF
import os
def pdf_to_images(pdf_path,
output_folder, dpi=200):
# 确保输出文件夹存在
os.makedirs(output_folder, exist_ok=True)
# 打开PDF文件
pdf = fitz.open(pdf_path)
# 计算缩放因子 (dpi/72,因为PDF使用72dpi为基准)
zoom = dpi / 72
# 转换每一页
for i, page in enumerate(pdf):
# 获取页面的Matrix对象用于缩放
mat = fitz.Matrix(zoom, zoom)
# 渲染为Pixmap
pix = page.get_pixmap(matrix=mat)
# 保存为图像
image_path = os.path.join(output_folder, f"page_{i + 1}.jpg")
pix.save(image_path)
print(f"已将{pdf_path}转换为{pdf.page_count}张图片")
pdf.close
()
# 使用示例
pdf_to_images("file_data/报告模板.pdf", "file_data/output_images")
注意:Windows用户需要安装poppler并设置环境变量,或者直接指定poppler_path参数。
技巧七:PDF表格数据提取
处理PDF中的表格数据是一个常见难题,我们可以使用 tabula-py
库来解决:
# 安装tabula-py
pip install tabula-py
# 导入库
import tabula
import pandas as pd
import os
import shutil
# 打印当前工作目录,帮助调试
print("当前工作目录:", os.getcwd())
# 提取PDF中的表格
def extract_tables(pdf_path, output_excel):
# 检查文件是否存在
if not os.path.exists(pdf_path):
print(f"错误:文件 '{pdf_path}' 不存在!")
return
# 创建一个临时文件,使用英文名称
temp_pdf = "temp_file.pdf"
shutil.copy2(pdf_path, temp_pdf)
try:
# 读取PDF中的所有表格,使用subprocess模式
print(f"正在处理文件: {pdf_path}")
tables = tabula.read_pdf(
temp_pdf,
pages='all',
multiple_tables=True,
encoding='gbk', # 尝试使用GBK编码
java_options=['-Dfile.encoding=UTF8'] # 设置Java编码
)
# 检查是否成功提取表格
if not tables or len(tables) == 0:
print("未能提取任何表格,尝试其他选项...")
tables = tabula.read_pdf(
temp_pdf,
pages='all',
multiple_tables=True,
encoding='gbk',
guess=True, # 增加猜测参数
lattice=
True # 尝试格子模式
)
# 创建Excel写入器
with pd.ExcelWriter(output_excel) as writer:
# 将每个表格写入Excel的不同工作表
for i, table in enumerate(tables):
sheet_name = f"Table_{i + 1}"
table.to_excel(writer, sheet_name=sheet_name, index=False)
print(f"已从{pdf_path}提取{len(tables)}个表格到{output_excel}")
except Exception as e:
print(f"错误: {str(e)}")
finally:
# 清理临时文件
if os.path.exists(temp_pdf):
os.remove(temp_pdf)
# 使用示例 - 确保目录存在
pdf_path = "file_data/万投光伏站2025年02月01日结算单.pdf"
if os.path.
exists(pdf_path):
extract_tables(pdf_path, "tables.xlsx")
else:
print(f"文件路径不存在: {pdf_path}")
print("可用文件列表:")
if os.path.exists("file_data"):
print(os.listdir("file_data"))
else:
print("file_data目录不存在")
注意:tabula-py需要Java环境支持,请确保已安装Java。
技巧八:PDF文本搜索与替换
如果你需要在PDF中搜索特定内容,或者替换某些文本:
# 导入库
from PyPDF2 import PdfReader
import re
# 在PDF中搜索文本
def search_text(pdf_path, search_term):
reader = PdfReader(pdf_path)
results = []
for page_num, page in enumerate(reader.
pages):
text = page.extract_text()
matches = re.finditer(search_term, text, re.IGNORECASE)
for match in matches:
start = max(0, match.start() - 20)
end = min(len(text), match.end() + 20)
context = text[start:end]
results.append({
"page": page_num + 1,
"context": context
})
return results
# 使用示例
results = search_text("example.pdf", "Python")
for result in results:
print(f"第{result['page']}页: ...{result['context']}...")
技巧九:PDF添加水印
最后,我们来看一个实用的技巧:如何给PDF添加水印:
# 导入库
from PyPDF2 import PdfReader, PdfWriter
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
import io
import os
# 添加水印 (Add watermark)
def add_watermark(input_pdf, output_pdf, watermark_text, font_path=None):
# 创建水印 (Create watermark)
packet = io.BytesIO()
c = canvas.Canvas(packet, pagesize=letter)
width, height = letter
# 如果提供了字体路径,则注册该字体 (Register font if a path is provided)
if font_path and os.path.exists(font_path):
font_name = os.path.basename(font_path).split('.')[0]
pdfmetrics.registerFont(TTFont(font_name, font_path))
c.setFont(font_name, 50)
else:
# 使用内置的中文字体 (Use built-in Chinese font)
# 注册思源黑体 (Register Source Han Sans)
font_name = "SourceHanSans"
try:
pdfmetrics.registerFont(TTFont(font_name, "SourceHanSans-Regular.ttf"))
c.setFont(font_name, 50)
except:
# 如果找不到思源黑体,尝试使用其他常见中文字体
print("未找到思源黑体,尝试使用内置字体。请考虑安装并指定中文字体路径。")
# 使用默认字体,可能不支持中文
c.setFont("Helvetica", 50)
# 设置透明度 (Set transparency)
c.setFillAlpha(0.3)
# 旋转45度 (Rotate 45 degrees)
c.rotate(45)
# 放置水印文本 (Place watermark text)
c.drawString(height / 2, 0, watermark_text)
c.save()
# 移动到开始位置 (Move to the beginning position)
packet.seek(0)
watermark = PdfReader(packet)
# 获取输入PDF (Get input PDF)
reader = PdfReader(input_pdf)
writer = PdfWriter()
# 为每一页添加水印 (Add watermark to each page)
for page in reader.pages:
page.merge_page(watermark.pages[0])
writer.add_page(page)
# 保存输出PDF (Save output PDF)
with open(output_pdf, "wb") as f:
writer.write(f)
print(f"已为{input_pdf}添加水印并保存为{output_pdf}")
# 使用示例 (Usage example)
# 使用方法1:指定中文字体路径
add_watermark("file_data/报告模板.pdf", "file_data/watermarked.pdf", "水印", "C:/Windows/Fonts/simhei.ttf")
# 使用方法2:不指定字体路径,尝试使用内置字体
# add_watermark("file_data/报告模板.pdf", "file_data/watermarked.pdf", "水印")
# 中文常见字体路径示例
# Windows: C:/Windows/Fonts/simhei.ttf (黑体), C:/Windows/Fonts/simsun.ttc (宋体)
# Mac: /Library/Fonts/华文黑体.ttf, /System/Library/Fonts/PingFang.ttc
# Linux: /usr/share/fonts/truetype/arphic/uming.ttc
通过这10个技巧,你应该已经掌握了Python处理PDF的基本方法。从简单的文本提取到复杂的表单填写,从文件合并到水印添加,Python都能帮你轻松搞定。
当然,PDF处理的世界远不止这些,还有很多高级技巧等待你去探索。
希望这篇文章对你有所帮助!如果你有其他PDF处理的问题或者需求,欢迎在评论区留言,我们一起讨论。
如果你喜欢这篇文章,别忘了点赞、收藏、分享,你的支持是我继续创作的动力!
转发、收藏、在看,是对作者最大的鼓励!👏
对Python,AI,自动化办公提效,副业发展等感兴趣的伙伴们,扫码添加逍遥,限免交流群
备注【成长交流】