使用Python批量将PDF转Word

news2024/12/28 18:16:12

简述

        以下全部代码无法完美对图片、表格等非文字形式的内容转化。要较好的效果需要使用光学字符分析等方法进行转化

        我懒,不想将代码模块拆分出来写注释

        除代码1中有详细注释外,剩下的代码仅在关键部分进行注释

代码1:小规模文件的转换

代码简介

        不使用线程,挨个文件转换格式。

        适用于小规模的PDF文件批量转换。

        需要自己选择PDF文件(可以全选文件,自动筛选PDF格式)

代码内容

import os, sys  # 导入操作系统接口和系统相关的参数和函数
from pdf2docx import Converter  # 导入pdf2docx库中的Converter类,用于将PDF文件转换为docx格式

import tkinter as tk  # 导入Tkinter库,用于创建图形用户界面
from tkinter import filedialog  # 导入Tkinter库中的filedialog模块,用于打开文件对话框

# 定义一个函数,用于将PDF文件转换为docx格式
def convert_pdf_to_docx(file_path):
    if os.path.splitext(file_path)[1] == '.pdf':  # 检查文件的扩展名是否为.pdf
        pdf_filename = os.path.basename(file_path)  # 从file_path中提取出文件名(不含路径)
        word_name = os.path.splitext(pdf_filename)[0] + ".docx"  # 创建新的文件名,将.docx作为扩展名

        cv = Converter(pdf_filename)  # 创建一个Converter对象,用于转换文件
        cv.convert(word_name)  # 调用convert方法,将PDF文件转换为docx格式,并将转换后的文件保存为word_name
        cv.close()  # 关闭转换器对象

        print(f"**{pdf_filename}**处理完成")  # 打印转换完成的信息

# 创建一个Tkinter窗口,但不显示它
root = tk.Tk()
root.withdraw()

# 使用filedialog模块打开一个文件选择对话框,允许用户选择多个文件
file_paths = filedialog.askopenfilenames(title="选择需要处理的文件")
if len(file_paths) == 0:  # 如果没有选择文件,退出程序
    sys.exit()
else:
    print("待处理文件:")  # 打印提示信息
    for file_path in file_paths:  # 遍历所有选择的文件路径
        print("  ", file_path)  # 打印每个文件的路径


# 遍历所有选择的文件路径,并调用convert_pdf_to_docx函数进行转换
for file_path in file_paths:
    convert_pdf_to_docx(file_path)

print("全部PDF转换完成")  # 打印所有PDF文件转换完成的信息

功能的执行

选择需要转换的文件

选择你需要转换的文件,可以直接全选

一次只能转换一个文件夹中的全部文件,无法进入到该文件夹的次级文件夹中

选择需要转换的PDF文件

开始转换文件

请注意终端信息窗口,会提示转换进度

开始转换

转换完成

转换完成

转换效果:

代码2:较大规模文件的转换

更新功能

1.使用多线程模式,一个文件一条线程的转换文件

2.增加时间计算,统计转换文件需要多少时间,方便后继继续优化提高转换速度

详细代码

import os
import sys
from pdf2docx import Converter
import tkinter as tk
from tkinter import filedialog
import threading
import time

# 定义一个函数,用于将PDF文件转换为docx格式
def convert_pdf_to_docx(file_path):
    try:
        if os.path.splitext(file_path)[1] == '.pdf':
            #pdf_filename = os.path.basename(file_path)
            #word_name = os.path.splitext(pdf_filename)[0] + ".docx"
            cv = Converter(file_path)
            cv.convert(os.path.splitext(os.path.basename(file_path))[0] + ".docx")
            cv.close()
    except Exception as e:
        print(f"转换 {os.path.basename(file_path)} 时发生错误: {e}")

# 创建一个Tkinter窗口,但不显示它
root = tk.Tk()
root.withdraw()

# 使用filedialog模块打开一个文件选择对话框,允许用户选择多个文件
file_paths = filedialog.askopenfilenames(title="选择需要处理的文件")
if not file_paths:
    sys.exit("没有选择文件,操作取消。")


# 打印待处理的文件
print("待处理文件:")
for file_path in file_paths:
    print("  ", file_path)

# 创建一个线程列表用于存储所有的转换线程
threads = []

# 遍历所有选择的文件路径,并创建转换线程
for file_path in file_paths:
    thread = threading.Thread(target=convert_pdf_to_docx, args=(file_path,))
    threads.append(thread)

# 记录开始时间
start_time = time.time()

# 启动所有的转换线程
for thread in threads:
    thread.start()

# 等待所有的转换线程完成
for thread in threads:
    time.sleep(0.1)# 暂停程序1毫秒
    thread.join()

# 记录结束时间
end_time = time.time()

# 计算并打印转换完成所需的总时间
total_time = end_time - start_time
print(f"所有文件转换完成,总共耗时: {total_time:.2f} 秒。")

代码3:超大规模文件的转换

功能的更新

1.引入线程池,控制程序消耗的系统资源

详细代码

import os
import logging
from tkinter import Tk, filedialog
from concurrent.futures import ThreadPoolExecutor, as_completed
from pdf2docx import Converter

# 配置日志格式和级别
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')

# 定义一个函数来处理单个PDF文件的转换
def process_pdf_file(pdf_path):
    try:
        pdf_dir = os.path.dirname(pdf_path)
        file_name = os.path.splitext(os.path.basename(pdf_path))[0]
        docx_path = os.path.join(pdf_dir, f"{file_name}.docx")
        
        # 转换PDF到Word
        cv = Converter(pdf_path)
        cv.convert(docx_path, start=0, end=None)
        cv.close()
        
        # 记录文件保存的信息
        logging.info(f"Converted file saved to {docx_path}")
    except Exception as e:
        # 如果发生错误,记录错误信息而不是转换成功信息
        logging.error(f"Error processing file {pdf_path}: {e}")

# 创建主窗口
root = Tk()
root.withdraw()  # 隐藏主界面

# 选择PDF文件
pdf_paths = filedialog.askopenfilenames(title="选择PDF文件", filetypes=[("PDF files", "*.pdf")])

if pdf_paths:
    # 创建一个线程池,限制线程数量为CPU核心数
    with ThreadPoolExecutor(max_workers=os.cpu_count()*2) as executor:
        # 将任务提交到线程池
        futures = [executor.submit(process_pdf_file, pdf_path) for pdf_path in pdf_paths]
        
        # 使用as_completed迭代器等待所有任务完成
        for future in as_completed(futures):
            future.result()
            if future.exception() is not None:
                logging.error(f"An error occurred: {future.exception()}")
            else:
                logging.info(f"File processed successfully: {future.result()}")

    # 所有文件处理完成后,关闭窗口并退出程序
    root.destroy()
else:
    logging.info("没有选择PDF文件。")

代码4:超快速PDF文件转换

功能更新

只转换文字,对任何图片表格会出现问题

详细代码

import os
import logging
from tkinter import Tk, filedialog
from concurrent.futures import ThreadPoolExecutor, as_completed
import fitz  # PyMuPDF

# 配置日志格式和级别
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')

# 定义一个函数来处理单个PDF文件的转换
def process_pdf_file(pdf_path):
    try:
        pdf_dir = os.path.dirname(pdf_path)
        file_name = os.path.splitext(os.path.basename(pdf_path))[0]
        docx_path = os.path.join(pdf_dir, f"{file_name}.docx")
        
        # 使用PyMuPDF读取PDF内容
        pdf = fitz.open(pdf_path)
        text = ""
        for page in pdf:
            text += page.get_text()
        
        pdf.close()
        
        # 将文本写入Word文档(这里需要一个将文本转换为docx格式的函数)
        with open(docx_path, 'w', encoding='utf-8') as f:
            f.write(text)
        
        # 记录文件保存的信息
        logging.info(f"Converted file saved to {docx_path}")
    except Exception as e:
        # 如果发生错误,记录错误信息而不是转换成功信息
        logging.error(f"Error processing file {pdf_path}: {e}")

# 创建主窗口
root = Tk()
root.withdraw()  # 隐藏主窗口

# 选择PDF文件
pdf_paths = filedialog.askopenfilenames(title="选择PDF文件", filetypes=[("PDF files", "*.pdf")])

if pdf_paths:
    # 创建一个线程池
    with ThreadPoolExecutor(max_workers=min(len(pdf_paths), os.cpu_count())) as executor:
        # 将任务提交到线程池
        futures = [executor.submit(process_pdf_file, pdf_path) for pdf_path in pdf_paths]
        
        # 等待所有任务完成
        for future in as_completed(futures):
            future.result()

    # 所有文件处理完成后,关闭窗口并退出程序
    root.destroy()
else:
    logging.info("没有选择PDF文件。")

批量删除文件夹内的全部word:使用Python批量删除文件夹内的Word-CSDN博客

程序打包方式见我的这个文章:在Vscode中将python打包为exe,超级简单,还能自定义exe的logo_怎么将vscode编写的代码打包成exe-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1589949.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++设计模式|创建型 1.单例模式

1.什么是单例模式? 单例模式的的核⼼思想在创建类对象的时候保证⼀个类只有⼀个实例,并提供⼀个全局访问点来访问这个实例。 只有⼀个实例的意思是,在整个应⽤程序中,只存在该类的⼀个实例对象,⽽不是创建多个相同类…

spring boot整合Redis监听数据变化

一、前言 Redis提供了数据变化的通知事件,可以实时监测key和value的变化,客户端可以通过订阅相关的channel来接收这些通知事件,然后做相应的自定义处理,详细的介绍可以参考官方文档Redis keyspace notifications | Docs 使用Red…

NLP问答系统:使用 Deepset SQUAD 和 SQuAD v2 度量评估

目录 一、说明 二、Deepset SQUAD是个啥? 三、问答系统(QA系统),QA系统在各行业的应用及基本原理 3.1 医疗 3.2 金融 3.3 顾客服务 3.4 教育 3.5 制造业 3.6 法律 3.7 媒体 3.8 政府 四、在不同行业使用QA系统的基本原理 五、关于…

uniapp uview里面的u-navbar结合u-sticky组件的使用

导航栏自定义加需要吸顶产生的问题 如上图直接使用并不能出现tab栏吸顶效果&#xff0c;那是由于u-sticky组件吸顶时与顶部的距离默认为0 那么做如下处理 <u-sticky :offset-top"navbarHeight()"><u-tabs :list"helpTabList" active-color"…

Excel/WPS超级处理器,提取汉字/字母/数字

在职场工作中&#xff0c;经常会遇到单元格中有汉字&#xff0c;数字&#xff0c;字母三者的自由组合&#xff0c;但往往只需要其中的一者&#xff0c;如何快速提取呢&#xff0c;超级处理器&#xff0c;提供了4个功能可选。 超级处理器下载与安装 1&#xff09;分离字符 将…

【MySQL】事务篇

SueWakeup 个人主页&#xff1a;SueWakeup 系列专栏&#xff1a;学习技术栈 个性签名&#xff1a;保留赤子之心也许是种幸运吧 目录 本系列专栏 1. 什么是事务 2. 事务的特征 原子性&#xff08;Atomicity&#xff09; 一致性&#xff08;Consistency&#xff09; 隔离性&…

【MYSQL】索引机制概述

由于MySQL是作为存储层部署在业务系统的最后端&#xff0c;所有的业务数据最终都要入库落盘&#xff0c;但随着一个项目在线上运行的时间越来越久&#xff0c;数据库中的数据量自然会越来越多&#xff0c;而数据体积出现增长后&#xff0c;当需要从表查询一些数据时&#xff0c…

Argus DBM 一款开源的数据库监控工具,无需部署Agent

开箱即用 无需部署Agent&#xff0c;开箱即用。我们使用JDBC直连您的数据库&#xff0c;输入IP端口账户密码即可。 全平台支持 Argus目前支持对Mysql, PostgreSQL, Oracle等数据库类型的监控&#xff0c;我们也会尽快适配其它数据库&#xff0c;致力于监控所有数据库。我们提…

数仓维度建模

维度建模 数仓建模方法1. 范式建模法&#xff08;Third Normal Form&#xff0c;3NF&#xff09;2. 维度建模法&#xff08;Dimensional Modeling&#xff09;3. 实体建模法&#xff08;Entity Modeling&#xff09; 维度建模1. 事实表事实表种类事务事实表周期快照事实表累计快…

淘宝扭蛋机小程序:扭出惊喜,乐享购物新体验

在快节奏的现代生活中&#xff0c;人们总是在寻找新鲜、有趣的娱乐方式。淘宝扭蛋机小程序应运而生&#xff0c;为您带来前所未有的购物与娱乐结合新体验。在这里&#xff0c;每一次的扭动都充满惊喜&#xff0c;每一次的点击都带来乐趣&#xff0c;让您在购物的同时&#xff0…

VRRP(虚拟路由冗余协议)详解

VRRP-------虚拟路由冗余协议 在一个网络中&#xff0c;要做为一个合格的网络首先就要具备几种冗余&#xff0c;增加网络的可靠性。 这几种冗余分别为&#xff1a;线路冗余&#xff0c;设备冗余&#xff0c;网关冗余&#xff0c;UPS冗余 VRRP该协议就是解决网关冗余的。在二层…

总分410+专业130+国防科技大学831信号与系统考研经验国防科大电子信息与通信工程,真题,大纲,参考书。

好几个学弟催着&#xff0c;总结一下我自己的复习经历&#xff0c;希望大家复习少走弯路&#xff0c;投入的复习正比换回分数。我专业课831信号与系统130&#xff08;感觉比估分要低&#xff0c;后面找Jenny老师讨论了自己拿不准的地方也没有错误&#xff0c;心里最近也这经常回…

基于kintex UltraScale XCKU060的双路QSFP+光纤PCIe 卡

基于kintex UltraScale XCKU060的双路QSFP光纤PCIe 卡 一、板卡概述 本板卡系我司自主研发&#xff0c;基于Xilinx UltraScale Kintex系列FPGA XCKU060-FFVA1156-2-I架构&#xff0c;支持PCIE Gen3 x8模式的高速信号处理板卡&#xff0c;搭配两路40G QSFP接口&#xff…

分类算法——sklearn转换器和估计器(一)

转换器&#xff08;特征工程的父类&#xff09; 实例化&#xff08;实例化的是一个转换器类&#xff08;Transformer&#xff09;&#xff09;调用fit_transform&#xff08;对于文档建立分类词频矩阵&#xff0c;不能同时调用&#xff09; 把特征工程的接口称之为转换器&…

采集某新闻网资讯网站保存PDF

网址&#xff1a;融资总额近3亿美元、药明康德押注&#xff0c;这家抗衰老明星公司有何过人之处-36氪 想要抓取文章内容&#xff0c;但是找不到啊&#xff0c;可能是文字格式的问题&#xff0c;也可能文章内容进行了加密。 在元素中查看&#xff0c;window.initialState返回的就…

算法修炼之路之双指针含多道leetcode 经典题目

目录 前言 一&#xff1a;普通双指针 1.经典题目一 283移动0问题 分析 代码实现 2.经典题目二 1089复写0 分析 代码实现 二&#xff1a;解决成环类问题-快慢指针 经典例题一 202快乐数 分析 代码实现 三&#xff1a;左右相遇指针 经典例题一 11 盛最多水的容…

杂货铺 | Linux虚拟机Ubuntu操作系统下设置共享文件夹(以及找不到hgfs文件夹怎么办)

文章目录 &#x1f4da;步骤一&#xff1a;配置共享文件夹&#x1f4da;步骤二&#xff1a;配置挂载环境&#x1f4da;步骤三&#xff1a;解决权限问题&#x1f4da;步骤四&#xff1a;解决重启失效问题 &#x1f4da;步骤一&#xff1a;配置共享文件夹 建立本地共享文件夹&…

TripoSR: Fast 3D Object Reconstruction from a Single Image 论文阅读

1 Abstract TripoSR的核心是一个基于变换器的架构&#xff0c;专为单图像3D重建设计。它接受单张RGB图像作为输入&#xff0c;并输出图像中物体的3D表示。TripoSR的核心包括&#xff1a;图像编码器、图像到三平面解码器和基于三平面的神经辐射场&#xff08;NeRF&#xff09;。…

程序员做副业,AI+公众号爆文,开启赚钱新模式!

给大家介绍一个程序员可做的副业&#xff0c;AI公众号爆文项目。 公众号已经成为了一个巨大的流量池&#xff0c;许多优秀的公众号作者通过发布爆款文章&#xff0c;获得了丰厚的收益。 而作为程序员的你&#xff0c;是否也想过要利用自己的技术优势&#xff0c;在这个领域分…

React Router 5 vs 6:使用上的主要差异与升级指南

React Router 5 的一些API 在 React Router 6 上有时可能找不到&#xff0c;可能会看到如下画面&#xff1a;export ‘useHistory’ was not found in ‘react-router-dom’ … React Router目前有两个大的版本&#xff0c;即React Router 5、6。React Router 6 在设计上更加简…