首页 > 编程语言 >全面解析:使用Python实现Docx转Pdf及PDF OCR处理的自动化流程(附完整代码)

全面解析:使用Python实现Docx转Pdf及PDF OCR处理的自动化流程(附完整代码)

时间:2024-12-04 22:57:17浏览次数:7  
标签:Docx Python docx 文档 file path pdf OCR dir

在数字化办公环境中,文档格式转换与内容提取是日常工作中经常遇到的需求。本文将详细介绍如何使用Python构建一个自动化流程,实现从.docx文件转换为.pdf,然后对.pdf文件进行OCR(光学字符识别)处理,最终将识别结果保存为Word文档。整个流程涵盖了文件转换、图像处理、OCR识别和结果整理等多个步骤,适用于需要批量处理文档的场景。

项目概述

本项目旨在自动化处理文档转换与内容提取的流程,具体步骤如下:

  1. Docx转Pdf:使用LibreOffice将.docx文件转换为.pdf格式。
  2. Pdf转图片:将转换后的.pdf文件的每一页渲染为高质量的PNG图片。
  3. OCR识别:利用PaddleOCR对每一页的PNG图片进行文字识别。
  4. 结果整理:将OCR识别的文字内容汇总并保存为新的Word文档。
  5. 文件管理:自动移动和清理中间生成的文件,保持工作目录整洁。

环境准备

在开始之前,需要确保系统中安装了以下工具和库:

必要工具

  • Python 3.6+
  • LibreOffice:用于文档格式转换。

安装LibreOffice

根据操作系统的不同,可以通过以下方式安装LibreOffice:

  • Ubuntu/Debian:
    sudo apt-get update
    sudo apt-get install libreoffice
    
  • MacOS:
    brew install --cask libreoffice
    
  • Windows: 下载并安装LibreOffice:LibreOffice下载

安装Python库

使用pip安装所需的Python库:

pip install PyMuPDF tqdm paddleocr python-docx

注意:PaddleOCR可能需要更多的依赖,建议参考PaddleOCR官方文档进行详细安装。

代码结构解析

本项目包含两个主要的Python脚本:

  1. doc_to_pdf.py:负责将.docx文件转换为.pdf
  2. pdf.py:负责处理.pdf文件,包括转换为图片、OCR识别和结果保存。

1. Docx转Pdf (doc_to_pdf.py)

# doc_to_pdf.py
import subprocess
import os

def docx_to_pdf(docx_path, output_dir):
    """
    使用 LibreOffice 将 .docx 文件转换为 .pdf

    :param docx_path: .docx 文件的路径
    :param output_dir: 输出 .pdf 文件的目录
    """
    # 确保输出目录存在
    os.makedirs(output_dir, exist_ok=True)
    
    # 调用 LibreOffice 命令行进行转换
    command = [
        'libreoffice', '--headless', '--convert-to', 'pdf', docx_path, '--outdir', output_dir
    ]
    subprocess.run(command, check=True)
    print(f"已将 {docx_path} 转换为 PDF 并保存至 {output_dir}")

2. PDF处理与OCR (pdf.py)

import fitz
from tqdm import tqdm
import os
from paddleocr import PaddleOCR
from docx import Document  # 用于创建 Word 文档
from docx.shared import Pt  # 设置字体大小
from doc_to_pdf import docx_to_pdf
import shutil

def pdf_to_png(pdf_path, img_path):
    # 确保图片输出目录存在
    os.makedirs(img_path, exist_ok=True)

    # 打开 PDF 文件
    pdf_doc = fitz.open(pdf_path)
    
    # 遍历每一页
    for pg in tqdm(range(pdf_doc.page_count), total=pdf_doc.page_count, desc='PDF分割处理'):
        page = pdf_doc[pg]
        rotate = 0  # 不旋转页面
        zoom_x = 2  # 横向缩放系数
        zoom_y = 2  # 纵向缩放系数
        mat = fitz.Matrix(zoom_x, zoom_y)  # 缩放矩阵
        
        # 渲染为像素图
        pix = page.get_pixmap(matrix=mat, alpha=False)
        
        # 保存为 PNG 图片
        one_img_path = os.path.join(img_path, f"img_{pg}.png")
        pix.save(one_img_path)

def traversal_file(pdf_name,img_path, out_path):
    # 初始化 OCR 模型,避免在循环中重复加载
    det = r"/home/ialover/document/PaddleOCR-release-2.6.1/model/ch_PP-OCRv4_det_infer"
    rec = r"/home/ialover/document/PaddleOCR-release-2.6.1/model/ch_PP-OCRv4_rec_infer"
    ocr = PaddleOCR(use_angle_cls=True, rec_model_dir=rec, det_model_dir=det,lang = 'ch')
    
    # 创建一个新的 Word 文档
    document = Document()

    # 设置中文字体(如果需要)
    from docx.oxml.ns import qn
    style = document.styles['Normal']
    font = style.font
    font.name = 'SimSun'  # 宋体
    font.size = Pt(12)
    font.element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')

    # 遍历所有图片文件并进行 OCR 识别
    image_files = sorted(os.listdir(img_path), key=lambda x: int(x.split('_')[1].split('.')[0]))
    for fp in tqdm(image_files, desc='OCR识别处理中'):
        file_path = os.path.join(img_path, fp)
        ocr_result = ocr.ocr(file_path, cls=True)
        # 将识别结果写入 Word 文档
        for one_content in ocr_result[0]:  # 访问第一页内容
            # print(one_content)
            text, confidence = one_content[1]  # 提取文字内容和置信度
            document.add_paragraph(text)  # 仅写入文字内容
    
    # 保存 Word 文档
    output_docx = os.path.join(out_path, f'{pdf_name}.docx')
    document.save(output_docx)
    print(f'OCR 结果已保存到 {output_docx}')

def remove_dir(input_path):
    for fg in os.listdir(input_path):
        file_path = os.path.join(input_path, fg)
        if os.path.isfile(file_path):
            os.remove(file_path)

def doctopdf(pdf_input_dir,pdf_book_dir):
    for fp in os.listdir(pdf_input_dir):
        file_pdf = os.path.join(pdf_input_dir,fp)
        target_pdf_file = os.path.join(pdf_book_dir,fp)
        if file_pdf.endswith('.pdf'):
            shutil.move(file_pdf,target_pdf_file)
        else:
            docx_to_pdf(file_pdf,pdf_book_dir)
            
def deal_with_pdf_dir(pdf_book_dir,img_path,pdf_output_dir):
    for fp in os.listdir(pdf_book_dir):
        file_path = os.path.join(pdf_book_dir,fp)
        pdf_to_png(file_path,img_path)
        file_name_with_ext = os.path.basename(file_path)
        pdf_name = os.path.splitext(file_name_with_ext)[0]
        traversal_file(pdf_name=pdf_name,img_path=img_path,out_path=pdf_output_dir)



if __name__ == "__main__":
    img_path = "./pdf_img_dir/"  
    pdf_input_dir = './pdf_input_dir'
    pdf_book_dir = './pdf_book_dir/'
    out_path = './pdf_output_dir'
    os.makedirs(out_path,exist_ok=True)
    doctopdf(pdf_input_dir=pdf_input_dir,pdf_book_dir=pdf_book_dir)
    deal_with_pdf_dir(pdf_book_dir=pdf_book_dir,img_path=img_path,pdf_output_dir=out_path)
    remove_dir(img_path)
    remove_dir(pdf_input_dir)
    remove_dir(pdf_book_dir)

详细功能讲解

Docx转Pdf

doc_to_pdf.py中,docx_to_pdf函数利用LibreOffice的命令行工具将.docx文件转换为.pdf。该函数接收两个参数:

  • docx_path:待转换的.docx文件路径。
  • output_dir:转换后.pdf文件的输出目录。

通过subprocess.run调用LibreOffice的命令,实现无界面的文档转换,并在转换完成后输出提示信息。

from doc_to_pdf import docx_to_pdf

docx_path = 'path/to/document.docx'
output_dir = 'path/to/output_pdf'
docx_to_pdf(docx_path, output_dir)

Pdf转图片

pdf.py中,pdf_to_png函数使用PyMuPDF库将.pdf文件的每一页渲染为高分辨率的PNG图片。函数参数包括:

  • pdf_path:待处理的.pdf文件路径。
  • img_path:保存生成图片的目录。

通过遍历PDF的每一页,设置缩放系数以提高图片质量,并将每页保存为单独的PNG文件。

pdf_path = 'path/to/document.pdf'
img_path = 'path/to/output_images'
pdf_to_png(pdf_path, img_path)

OCR识别与结果保存

traversal_file函数负责对生成的PNG图片进行OCR识别,并将识别结果汇总到一个新的Word文档中。主要步骤包括:

  1. 初始化OCR模型:指定检测(det)和识别(rec)模型的路径,初始化PaddleOCR实例。
  2. 创建Word文档:使用python-docx创建一个新的Word文档,并设置中文字体以确保识别文本的正确显示。
  3. 遍历图片文件:按顺序读取生成的PNG图片,对每张图片进行OCR识别。
  4. 保存识别结果:将识别的文本逐段添加到Word文档中,最终保存为指定路径的.docx文件。
pdf_name = 'document_name'
img_path = 'path/to/output_images'
out_path = 'path/to/output_docx'
traversal_file(pdf_name, img_path, out_path)

文件管理与清理

为了保持工作目录的整洁,脚本还包含了文件管理和清理的功能:

  • doctopdf函数:遍历输入目录中的文件,若是.pdf文件则移动到目标目录,否则调用docx_to_pdf进行转换。
  • remove_dir函数:删除指定目录中的所有文件,用于清理中间生成的图片和转换后的文件。
def doctopdf(pdf_input_dir, pdf_book_dir):
    for fp in os.listdir(pdf_input_dir):
        file_pdf = os.path.join(pdf_input_dir, fp)
        target_pdf_file = os.path.join(pdf_book_dir, fp)
        if file_pdf.endswith('.pdf'):
            shutil.move(file_pdf, target_pdf_file)
        else:
            docx_to_pdf(file_pdf, pdf_book_dir)

运行流程

1. 准备输入文件

将需要处理的.docx.pdf文件放入./pdf_input_dir目录。

2. 执行脚本

运行pdf.py脚本:

python pdf.py
流程执行:
  1. 转换与移动文件
    • 脚本首先调用doctopdf函数,将./pdf_input_dir中的.docx文件转换为.pdf并移动到./pdf_book_dir/
  2. 处理PDF文件
    • 接着,deal_with_pdf_dir函数处理./pdf_book_dir/中的所有.pdf文件,转换为PNG图片并进行OCR识别,最终将结果保存到./pdf_output_dir
  3. 清理中间文件
    • 最后,脚本清理中间生成的图片和转换后的文件,保持目录整洁。

3. 查看结果

./pdf_output_dir目录下,可以找到包含OCR识别文本的.docx文件。

总结与扩展

本文介绍了如何使用Python构建一个自动化的文档处理流程,包括文档格式转换、PDF处理、OCR识别和结果整理。通过结合使用LibreOffice、PyMuPDF、PaddleOCR和python-docx等工具,实现了高效的批量文档处理。

优势

  • 自动化:无需手动转换和复制粘贴,节省时间。
  • 批量处理:一次性处理多个文件,适合大规模文档管理。
  • 高精度 OCR:利用PaddleOCR提供高质量的文本识别,支持多语言。
  • 灵活性:可根据需求调整转换和识别的参数,适应不同的文档格式和内容。

可能的扩展方向

  1. 多语言支持:调整PaddleOCR的语言参数,支持更多语言的OCR识别。
  2. 错误处理与日志记录:增加异常处理机制和日志记录,提升脚本的健壮性和可维护性。
  3. 图形界面:为脚本添加图形用户界面(GUI),提高用户体验。
  4. 并行处理:利用多线程或多进程技术,加快大规模文档处理的速度。
  5. 云端集成:将脚本部署到云端,实现远程文档处理服务。

通过不断优化和扩展,可以将此自动化流程应用到更广泛的场景中,提高工作效率,节省人力资源。

参考资料

反馈与交流

如果您在实现过程中遇到任何问题或有更好的建议,欢迎在下方留言与我们交流。


版权声明:本文原创,转载请注明出处。

结语:感谢您的阅读,祝您在自动化文档处理的道路上取得更多的成果!


图片示例


结语

通过本文的介绍,希望您能够掌握如何利用Python及其强大的库,构建适合自己需求的文档处理工具。如果有更多需求,可以根据具体场景进行相应的调整和优化。自动化文档处理不仅能提高工作效率,还能减少人为错误,是现代办公环境中不可或缺的一部分。

标签:Docx,Python,docx,文档,file,path,pdf,OCR,dir
From: https://blog.csdn.net/yaoyihe/article/details/144252013

相关文章

  • 学习Python的笔记14--迭代器和生成器
    1.迭代器(Iterator)概念:迭代意味着重复多次,就像循环一样。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。1.iter():返回迭代器自身。2.next():返回容器的下一个元素,如果没有元素了,抛St......
  • 学习Python的笔记10--函数进阶
    1、变量作用域定义:变量生效的范围,主要分为两类:局部变量和全局变量。1、局部变量定义:函数体内部的变量,只在函数体内部生效。deftestA():a=100print(a)testA()#100print(a)#报错:name'a'isnotdefined变量a是定义在testA函数内部的变量,在函数外部访问则立即报......
  • 学习Python的笔记11--函数加强
    1、 lambda表达式1、语法:lambda参数列表:表达式注意:1、lambda表达式的参数可有可无,函数的参数在lambda表达式中完全适用。2、lambda表达式能接收任何数量的参数但只能返回一个表达式的值。3、直接打印lambda表达式,输出的是此lambda的内存地址#需求:函数返回值100#1.函......
  • 煮波的絮絮叨叨之Python篇
    晚上好啊贝贝们,今天聊点什么好呢既然每天都要学习新知识或者复习旧知识,那么就聊聊笔记好了。笔记对学习是很重要的,一个清晰明了的笔记不仅可以让你的心情变得愉悦,而且能让复习更加事半功倍。无偿推荐语雀 记笔记的软件,里面可以构建知识库,可以将你的各个内容分好类。今日......
  • python 数据类型和操作
    &转义要写成amp;<转义成<input默认转化为字符串是个文本,当需要计算时要转化为数字eg.x=input()​x=int或者更简单的x=int(input(""))布尔值,TRUEORFLASE​机器学习大任务:​回归是预测一个数​分类是给一个准确具体的数print(type(type(42......
  • task05&&01拓展:Python 条件判断和代码风格随笔
    在Python编程中,遵循良好的代码规范至关重要。一、空格使用规范•采用空格表示缩进,切勿使用制表符(Tab)。•语法相关的每一层缩进用4个空格表示。•每行字符数最好不超过79个。若表达式过长需多行显示,除首行外,其余行应在正常缩进基础上再增加4个空格。•函数和类定......
  • 物体检测(YOLO)示例:使用 Rust 调用 Python 进行物体检测
    在本示例中,我们将展示如何使用Rust调用Python脚本来完成YOLO物体检测任务。我们将通过Rust的std::process::Command调用Python脚本,并传递输入图像以进行检测。环境准备首先,您需要安装以下工具:更多内容访问ttocr.com或联系1436423940Rust语言:从Rust官网安装R......
  • 大数据学习记录,Python基础(5)
    模块类与对象模块内置模块time,random,os,json第三方模块requests,pandas,numpy,....自定义模块xxx.py常见的内置模块hashlib模块该模块主要是进行数据加密的作用。常见的加密方式:sha256()【可逆】md5()【不可逆】importhashlibinfo='12345......
  • python学习-condition
    条件判断1.三个关键词:ifelseelif(即为elseif)(1)if语句执行有个特点,它是从上往下判断,如果在某个判断上是True,把该判断对应的语句执行后,就忽略掉剩下的elif和else(2)当if后面的条件语句不满足时,与之相对应的else中的代码块将被执行。ifa==1:print('right')else:print('wro......
  • 大数据学习记录,Python基础(5)
    模块类与对象模块内置模块time,random,os,json第三方模块requests,pandas,numpy,…自定义模块xxx.py常见的内置模块hashlib模块该模块主要是进行数据加密的作用。常见的加密方式:sha256()【可逆】md5()【不可逆】importhashlibinfo='123456'#......