自动化魔法:用Python和PyMuPDF实现PDF文件的智能注释

引言

        在数字化办公的浪潮中,处理和分析大量文档成为了我们日常工作的一部分。尤其是面对PDF文件,手动检索和标注信息不仅耗时耗力,还难免疏漏。为了提升效率并减少人为失误,我精心打造了这款Python脚本,它能够智能化地在PDF文档中定位并标注Excel表格所指定的关键文本。本文将深入探讨这一脚本的内在逻辑,并指导你如何轻松驾驭这一自动化工具。

        程序的核心功能在于,它能够识别Excel文件中B列的特定文本,一旦这些文本在PDF文档中被找到,脚本便会自动在这些文本周围绘制矩形框,并在相邻位置以注释的形式展示同一行A列的内容。这一过程不仅提高了PDF文档处理的速度,同时也确保了信息标注的准确性和一致性。接下来,我将逐步展开,详细解释这一自动化流程的每个关键步骤。

        值得注意的是,随着PyMuPDF库的不断更新迭代,PyMuPDF库的语法已经产生不小的变化和以及新功能的加入,使得现有网络上的许多教程和文档的语法已经在某些情况下不再适用于最新版本使用需求。基于这一现状,笔者投入了不少时间和精力进行研究和实践,以确保本脚本使用的是最新的、正确的语法和方法。

在这篇文章中,你将看到:

  • 最新版本的PyMuPDF的正确使用方式。
  • 如何利用PyMuPDF的强大功能来实现复杂的PDF处理任务。
  • 实用技巧和最佳实践,帮助你避免常见的陷阱和错误。

我希望通过分享这些经过验证的知识和经验,能够帮助你在自动化PDF和Excel文件处理的道路上少走弯路,直接掌握最前沿的技术。无论你是编程新手还是资深开发者,这篇文章都将为你提供宝贵的信息和指导。让我们一起探索自动化魔法的奥秘,释放你的工作效率吧!

环境准备

在开始之前,请确保你的Python环境中安装了以下库:

  • PyMuPDF:用于读取、修改PDF文件。
  • openpyxl:用于读取Excel文件。
  • Tkinter:用于创建图形用户界面(GUI)。

要安装这三个库,你可以使用Python的包管理器pip。以下是安装命令:

对于PyMuPDF:

pip install PyMuPDF

对于openpyxl:

pip install openpyxl

对于Tkinter(通常Python的安装已经包含了Tkinter,但如果没有,你可以使用以下命令安装):

pip install tk

请注意,如果你使用的是Python 3.x版本,通常pip命令已经内置在Python中,你可以直接使用它来安装这些库。如果你使用的是Python 2.x版本,可能需要使用pip2或pip3来指定正确的Python版本。

脚本功能概述

本脚本具有以下核心功能:

  1. 通过GUI让用户选择PDF和Excel文件。
  2. 读取Excel文件中B列数据以获取指定的文本,并在PDF中搜索这些文本。
  3. 在PDF中找到的文本位置添加矩形框和文本注释。
  4. 保存修改后的PDF文件,并提供选项让用户选择保存路径。
  5. 脚本运行结束后,提示用户按特定键退出程序。

脚本详解

1. 图形用户界面(GUI)

使用Tkinter库创建一个简洁的GUI,让用户能够方便地选择需要处理的文件。

# 创建Tk窗口对象并立即销毁,用于文件对话框
root = Tk()
root.withdraw()

# 使用tkinter.filedialog获取PDF文件路径
input_file_pdf = filedialog.askopenfilename(
    title="请选择PDF文件",  # 对话框标题
    filetypes=(("PDF files", "*.pdf"), ("All files", "*.*"))  # 文件类型过滤
)

# 如果用户取消了文件选择,就退出程序
if not input_file_pdf:
    print("未选择文件,程序将退出。")
    exit()

2. 打开和读取文件

使用PyMuPDF打开用户选择的PDF文件,使用openpyxl读取Excel文件,并获取活动工作表。

# 打开PDF文件
print("正在打开PDF文件,请稍候...")
doc = fitz.open(input_file_pdf)  # 使用PyMuPDF打开PDF文件
print("已打开PDF文件,请稍候...")

# 使用tkinter.filedialog获取Excel文件路径
input_file_excel = filedialog.askopenfilename(
    title="请选择Excel文件",  # 对话框标题
    filetypes=(("Excel files", "*.xlsx"), ("All files", "*.*"))  # 文件类型过滤
)

# 如果用户取消了文件选择,就退出程序
if not input_file_excel:
    print("未选择文件,程序将退出。")
    exit()

3. 搜索和注释

遍历Excel工作表的每一行,使用PyMuPDF的搜索功能在PDF中查找指定文本,并在找到的位置添加矩形框和文本注释。

# 遍历Excel的每一行,从第二行开始读取
for row in ws.iter_rows(min_row=1, values_only=True):
    text = str(row[0])  # 获取A列的值
    text_to_search = row[1]  # 获取B列的值

    print(f"正在处理Excel中的文本:'{text}' 和 '{text_to_search}'")

    # 用于跟踪是否在当前循环中找到文本的变量
    page_text_found = False

    # 遍历PDF的每一页
    for page_number in range(len(doc)):
        page = doc[page_number]  # 访问当前页
        areas = page.search_for(text_to_search)  # 在当前页搜索文本

        # 如果在页面上找到文本,添加扩大的矩形框和文本注释
        if areas:
            page_text_found = True

            for area in areas:
                x0, y0, x1, y1 = area
                print(f"在第 {page_number + 1} 页找到文本 '{text_to_search}'")

                # 扩大矩形框
                new_x0 = 27.7  # 根据需要调整
                new_y0 = y0 - down_size
                new_x1 = 524.6  # 根据需要调整
                new_y1 = y1 + up_size

                # 创建扩大后的矩形区域
                rect = fitz.Rect(new_x0, new_y0, new_x1, new_y1)
                # 添加矩形注释
                annot = page.add_rect_annot(rect)
                annot.set_border(width=2)
                annot.update(opacity=1)

                # 添加文本注释
                new_rect = fitz.Rect(5, new_y0 + 3, 10 + 50, new_y0 + 15)
                annot = page.add_freetext_annot(new_rect, text, fontsize=12, text_color=(1, 0, 0))

            # 由于找到文本后已添加注释,可以跳出内层循环
            break

    # 如果在当前Excel行的搜索中没有找到文本,则告知用户
    if not page_text_found:
        print(f"在整个PDF中没有找到文本 '{text_to_search}'。")

4. 保存和退出

用户选择保存路径后,脚本将保存修改后的PDF文件,并在所有操作完成后提示用户按特定键退出程序。

# 使用tkinter.filedialog获取保存PDF的文件路径
output_file_pdf = filedialog.asksaveasfilename(
    title="请输入要保存的PDF文件路径",
    filetypes=(("PDF files", "*.pdf"), ("All files", "*.*")),
    defaultextension=".pdf"  # 设置默认扩展名为PDF
)

# 如果用户取消了保存文件选择,就退出程序
if not output_file_pdf:
    print("未选择保存路径,程序将退出。")
    exit()

print("正在保存修改后的PDF文件,请稍候...")
doc.save(output_file_pdf)  # 保存修改后的PDF文件
print("修改后的PDF文件已保存。")

# 关闭文档
doc.close()  # 关闭PyMuPDF文档
print("搜索完成,PDF文件已关闭。")

代码示例文件与截图

Excel文件原内容

PDF文件原内容

程序运行后PDF文件内容

代码运行截图

完整代码

# 导入PyMuPDF库,用于处理PDF文件
import fitz
# 导入openpyxl库中的load_workbook函数,用于处理Excel文件
from openpyxl import load_workbook
# 导入Tk和filedialog,用于创建图形用户界面对话框
from tkinter import Tk, filedialog

# 创建Tk窗口对象并立即销毁,用于文件对话框
root = Tk()
root.withdraw()

# 使用tkinter.filedialog获取PDF文件路径
input_file_pdf = filedialog.askopenfilename(
    title="请选择PDF文件",  # 对话框标题
    filetypes=(("PDF files", "*.pdf"), ("All files", "*.*"))  # 文件类型过滤
)

# 如果用户取消了文件选择,就退出程序
if not input_file_pdf:
    print("未选择文件,程序将退出。")
    exit()

# 打开PDF文件
print("正在打开PDF文件,请稍候...")
doc = fitz.open(input_file_pdf)  # 使用PyMuPDF打开PDF文件
print("已打开PDF文件,请稍候...")

# 使用tkinter.filedialog获取Excel文件路径
input_file_excel = filedialog.askopenfilename(
    title="请选择Excel文件",  # 对话框标题
    filetypes=(("Excel files", "*.xlsx"), ("All files", "*.*"))  # 文件类型过滤
)

# 如果用户取消了文件选择,就退出程序
if not input_file_excel:
    print("未选择文件,程序将退出。")
    exit()

# 打开Excel文件
print("正在打开Excel文件,请稍候...")
wb = load_workbook(filename=input_file_excel)  # 加载Excel文件
ws = wb.active  # 获取活动工作表

# 矩形扩大的尺寸
up_size = 5  # 上边扩大的尺寸
down_size = 3  # 下边扩大的尺寸
left_size = 77.5  # 左边扩大的尺寸
right_size = 389.5  # 右边扩大的尺寸

# 遍历Excel的每一行,从第二行开始读取
for row in ws.iter_rows(min_row=1, values_only=True):
    text = str(row[0])  # 获取A列的值
    text_to_search = row[1]  # 获取B列的值

    print(f"正在处理Excel中的文本:'{text}' 和 '{text_to_search}'")

    # 用于跟踪是否在当前循环中找到文本的变量
    page_text_found = False

    # 遍历PDF的每一页
    for page_number in range(len(doc)):
        page = doc[page_number]  # 访问当前页
        areas = page.search_for(text_to_search)  # 在当前页搜索文本

        # 如果在页面上找到文本,添加扩大的矩形框和文本注释
        if areas:
            page_text_found = True

            for area in areas:
                x0, y0, x1, y1 = area
                print(f"在第 {page_number + 1} 页找到文本 '{text_to_search}'")

                # 扩大矩形框
                new_x0 = 27.7  # 根据需要调整
                new_y0 = y0 - down_size
                new_x1 = 524.6  # 根据需要调整
                new_y1 = y1 + up_size

                # 创建扩大后的矩形区域
                rect = fitz.Rect(new_x0, new_y0, new_x1, new_y1)
                # 添加矩形注释
                annot = page.add_rect_annot(rect)
                annot.set_border(width=2)
                annot.update(opacity=1)

                # 添加文本注释
                new_rect = fitz.Rect(5, new_y0 + 3, 10 + 50, new_y0 + 15)
                annot = page.add_freetext_annot(new_rect, text, fontsize=12, text_color=(1, 0, 0))

            # 由于找到文本后已添加注释,可以跳出内层循环
            break

    # 如果在当前Excel行的搜索中没有找到文本,则告知用户
    if not page_text_found:
        print(f"在整个PDF中没有找到文本 '{text_to_search}'。")

# 使用tkinter.filedialog获取保存PDF的文件路径
output_file_pdf = filedialog.asksaveasfilename(
    title="请输入要保存的PDF文件路径",
    filetypes=(("PDF files", "*.pdf"), ("All files", "*.*")),
    defaultextension=".pdf"  # 设置默认扩展名为PDF
)

# 如果用户取消了保存文件选择,就退出程序
if not output_file_pdf:
    print("未选择保存路径,程序将退出。")
    exit()

print("正在保存修改后的PDF文件,请稍候...")
doc.save(output_file_pdf)  # 保存修改后的PDF文件
print("修改后的PDF文件已保存。")

# 关闭文档
doc.close()  # 关闭PyMuPDF文档
print("搜索完成,PDF文件已关闭。")

# 提示用户按下q键退出程序,并检查输入
print("程序运行结束,按 'q' 键退出程序(不区分大小写)。")
while True:  # 创建一个无限循环
    key = input().strip().lower()  # 获取用户输入并转换为小写
    if key == 'q':  # 检查输入是否是 'q'
        break  # 如果是 'q',退出循环
    else:
        print("请输入 'q' 以退出程序。")

结语

这个Python脚本提供了一种高效、自动化的方式来处理PDF和Excel文件,尤其适用于需要在大量文档中搜索和标记特定信息的场景。通过使用这个脚本,你可以节省宝贵的时间,减少人为错误,提高工作效率。

如果你对这个脚本有任何疑问,或者想要获取更多类似的工具和技巧,请在评论区留下你的问题和建议。同时,如果你觉得这篇文章对你有帮助,请不要吝啬你的点赞和分享。


版权声明:本文首发于CSDN,作者保留所有权利。转载请保留原文链接和作者信息。

  • 20
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值