PDF转换成word

# -*- coding: utf-8 -*-  # 指定文件编码格式,支持中文

# 导入需要的标准库
import os  # 操作系统接口模块,用于文件路径处理
import threading  # 多线程支持模块
from queue import Queue  # 线程安全队列,用于任务管理
from tkinter import Tk  # GUI基础库
from tkinter.filedialog import askopenfilenames  # 文件选择对话框
from pdf2docx import Converter  # PDF转Word核心库
from concurrent.futures import ThreadPoolExecutor  # 线程池执行器

class PDFConverter:
    def __init__(self):
        """ 初始化转换器实例 """
        self.task_queue = Queue()  # 创建任务队列(先进先出)
        self.results = []  # 存储转换结果列表
        self.lock = threading.Lock()  # 创建线程锁(保证结果记录的线程安全)
        self.executor = ThreadPoolExecutor(max_workers=4)  # 创建包含4个工作线程的线程池

    def add_task(self, pdf_path):
        """ 添加转换任务到队列 """
        # 生成Word文件路径:将.pdf替换为.docx
        word_path = os.path.splitext(pdf_path)[0] + ".docx"
        # 将任务元组(PDF路径,Word路径)放入队列
        self.task_queue.put((pdf_path, word_path))

    def _convert_task(self, pdf_path, word_path):
        """ 实际执行转换的内部方法(仅供线程调用) """
        try:
            # 创建PDF转换器对象(需要try块因为可能打开文件失败)
            cv = Converter(pdf_path)
            # 执行转换操作(核心功能)
            cv.convert(word_path)
            # 关闭转换器释放资源
            cv.close()
            
            # 使用线程锁保证结果列表的线程安全
            with self.lock:
                # 记录成功结果(文件路径,成功标志,提示信息)
                self.results.append((pdf_path, True, "转换成功"))
        except Exception as e:
            # 捕获所有异常(包括文件不存在、转换错误等)
            with self.lock:
                # 记录失败结果(文件路径,失败标志,错误信息)
                self.results.append((pdf_path, False, str(e)))
        finally:
            # 确保无论是否异常都关闭转换器
            if 'cv' in locals():  # 检查cv变量是否存在
                cv.close()

    def start_convert(self):
        """ 启动转换任务(从队列中取出任务分配给线程池) """
        # 循环直到任务队列为空
        while not self.task_queue.empty():
            # 从队列获取一个任务(自动遵循先进先出顺序)
            pdf_path, word_path = self.task_queue.get()
            # 将任务提交给线程池执行(自动分配空闲线程)
            self.executor.submit(self._convert_task, pdf_path, word_path)
            # 打印当前任务启动信息
            print(f"开始转换: {os.path.basename(pdf_path)}")
        # 关闭线程池并等待所有任务完成
        self.executor.shutdown(wait=True)

    def show_results(self):
        """ 显示最终转换结果 """
        print("\n转换结果汇总:")
        # 遍历所有结果记录
        for result in self.results:
            # 解包结果元组
            file_path, success, msg = result
            # 根据成功标志生成状态文本
            status = "成功" if success else "失败"
            # 打印文件名、状态和详细信息
            print(f"{os.path.basename(file_path)}: {status} | 详细信息: {msg}")

def main():
    """ 主程序入口函数 """
    # 创建Tk根窗口后立即隐藏(不显示空白窗口)
    Tk().withdraw()
    
    # 打开文件选择对话框(多选模式)
    pdf_files = askopenfilenames(
        title="选择PDF文件(可多选)",  # 对话框标题
        filetypes=[("PDF文件", "*.pdf"), ("所有文件", "*.*")]  # 文件过滤器
    )

    # 如果没有选择文件则退出
    if not pdf_files:
        print("未选择文件,程序退出。")
        return

    # 创建PDF转换器实例
    converter = PDFConverter()
    
    # 将选中的文件逐个添加到任务队列
    for file in pdf_files:
        converter.add_task(file)

    # 显示开始提示信息
    print(f"开始批量转换 {len(pdf_files)} 个文件...")
    # 启动转换流程
    converter.start_convert()
    # 显示汇总结果
    converter.show_results()
    # 等待用户回车退出(防止控制台窗口立即关闭)
    input("按回车键退出...")

# Python程序标准入口(当直接运行本文件时执行)
if __name__ == "__main__":
    main()

关键代码结构说明:

  1. 类结构设计:class PDFConverter:
        def __init__(self): ...    # 初始化组件
        def add_task(self): ...    # 添加任务
        def _convert_task(self): ...  # 实际转换方法(带下划线表示内部方法)
        def start_convert(self): ...  # 启动转换
        def show_results(self): ...  # 显示结果

2.多线程工作流程: 主线程:main()
        ↓
创建转换器实例 → 添加任务到队列
        ↓
启动start_convert()
        ↓
线程池中的工作线程:执行_convert_task()
        ↓
所有线程完成后 → 显示结果

  1. 重要技术点

    • ThreadPoolExecutor:Python标准库的线程池实现

    • Queue:保证多线程环境下的任务安全存取

    • threading.Lock():防止多个线程同时修改结果列表

    • with语句:自动管理资源(如文件关闭)

 

你可能感兴趣的:(pdf,word,python,c语言,c++,php,java)