社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python玩转PDF:10个实用技巧让你告别繁琐操作

A逍遥之路 • 3 月前 • 135 次点击  

📚 你是否曾经被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 PdfReaderPdfWriter

# 打开加密的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 PdfReaderPdfWriter

# 打开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 PdfReaderPdfWriter

# 提取指定页面
def extract_pages(input_pathoutput_pathpages):
    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", [135])

合并多个PDF:

# 导入库
from PyPDF2 import PdfReaderPdfWriter

# 合并多个PDF
def merge_pdfs(input_pathsoutput_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_pathdocx_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_folderdpi=200):
    # 确保输出文件夹存在
    os.makedirs(output_folderexist_ok=True)

    # 打开PDF文件
    pdf = fitz.open(pdf_path)

    # 计算缩放因子 (dpi/72,因为PDF使用72dpi为基准)
    zoom = dpi / 72

    # 转换每一页
    for ipage in enumerate(pdf):
        # 获取页面的Matrix对象用于缩放
        mat = fitz.Matrix(zoomzoom)

        # 渲染为Pixmap
        pix = page.get_pixmap(matrix=mat)

        # 保存为图像
        image_path = os.path.join(output_folderf"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_pathoutput_excel):
    # 检查文件是否存在
    if not os.path.exists(pdf_path):
        print(f"错误:文件 '{pdf_path}' 不存在!")
        return

    # 创建一个临时文件,使用英文名称
    temp_pdf = "temp_file.pdf"
    shutil.copy2(pdf_pathtemp_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_excelas writer:
            # 将每个表格写入Excel的不同工作表
            for itable in enumerate(tables):
                sheet_name = f"Table_{i + 1}"
                table.to_excel(writersheet_name=sheet_nameindex=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_pathsearch_term):
    reader = PdfReader(pdf_path)
    results = []
    
    for page_numpage in enumerate(reader. pages):
        text = page.extract_text()
        matches = re.finditer(search_termtextre.IGNORECASE)
        
        for match in matches:
            start = max(0match.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 PdfReaderPdfWriter
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_pdfoutput_pdfwatermark_textfont_path=None):
    # 创建水印 (Create watermark)
    packet = io.BytesIO()
    c = canvas.Canvas(packetpagesize=letter)
    widthheight = 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_namefont_path))
        c.setFont(font_name50)
    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_name50)
        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 / 20watermark_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知识日日补!






           对Python,AI,自动化办公提效,副业发展等感兴趣的伙伴们,扫码添加逍遥,限免交流群

备注【成长交流】

图片

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/180168
 
135 次点击