admin管理员组

文章数量:1605197

Python通过PySide2、fitz完成word/pdf文档互转

  • 通过pyside2库完成window设置
    • 一、在QT设计师中完成.ui文件
    • 二、具体操作步骤
      • 1、项目需要导入的库
      • 2、加载ui文件
      • 3、设置qt窗口中widget功能和信号
      • 4、主功能函数1(word文档转化pdf文档主功能函数)
      • 4、主功能函数2(pdf文档转化word文档主功能函数)
      • 5、获取文件path函数1(获取单个文件路径)
      • 5、获取文件path函数2(获取多个文件路径)
      • 6、处理转化函数1(执行单个word文档和pdf文档互转)
      • 6、处理转化函数2(执行多个word文档和pdf文档互转)
      • 7、实现打开从pdf中获取的图片
    • 完整代码
    • 总结

通过pyside2库完成window设置

第一次写博客!非专业程序员,只是对编程感兴趣,自学的python的,主要为了方便日常工作。以及记录所学知识点。欢迎各位大佬指导!!!

一、在QT设计师中完成.ui文件

二、具体操作步骤

1、项目需要导入的库

pip install pymupdf  (使用fitz需要安装)
pip install pyside2  (使用pyside2需要安装)
pip install  python-docx  (使用docx需要安装)
pip install  pywin32  (使用win32com需要安装)
from PySide2.QtWidgets import QApplication, QFileDialog, QMessageBox
from PySide2.QtUiTools import QUiLoader
from PySide2.QtCore import QFile
from win32com.client import constants, gencache
import fitz
from docx import Document
from docx.shared import Pt
import os

2、加载ui文件

class WordTransform:

    def __init__(self):
        """
        加载ui文件,初始化按钮等触发事件响应对接执行函数
        """
        file = QFile('./word_ppt.ui')
        file.open(QFile.ReadOnly)
        file.close()
        self.window = QUiLoader().load(file)
        
if __name__ == '__main__':
    app = QApplication([])
    new_word = WordTransform()
    new_word.window.show()
    app.exec_()

3、设置qt窗口中widget功能和信号

		# 设置单行文本框只读
        self.window.lineEdit.setReadOnly(True)
        # 设置多行文本框只读
        self.window.plainTextEdit.setReadOnly(True)
        # 当按钮“打开文件”被点击触发事件,执行对应函数
        self.window.pushButton1.clicked.connect(self.get_filepath)
        # 当按钮“单个转化”被点击触发事件,执行对应函数
        self.window.pushButton2.clicked.connect(self.create_pdf_word)
        # 当按钮“打开文件”被点击触发事件,执行对应函数
        self.window.pushButton3.clicked.connect(self.get_filepaths)
        # 当按钮“批量转化”被点击触发事件,执行对应函数
        self.window.pushButton4.clicked.connect(self.create_pdfs_words)
        # 当按钮“打开pdf中图片”被点击触发事件,执行对应函数
        self.window.pushButton5.clicked.connect(self.open_pdf_image)

4、主功能函数1(word文档转化pdf文档主功能函数)

    def word_to_pdf(self, path):
        """
        word文档转化pdf文档主功能函数
        """
        pdf_path = path.split('.')[0] + '.pdf'
        word = gencache.EnsureDispatch('Word.Application')
        doc = word.Documents.Open(path, ReadOnly=1)
        # 转化方法
        doc.ExportAsFixedFormat(pdf_path, constants.wdExportFormatPDF)
        word.Quit()

4、主功能函数2(pdf文档转化word文档主功能函数)

    def pdf_to_word(self, path):
        """
        pdf文档转化word文档主功能函数
        注:该函数木器中能识别pdf中的纯文本和图片信息,表格等其他识别不出
        """
        pic_path = './pdf_word_images'  # 获取pdf文档中图片保存路径
        if not os.path.exists(pic_path):
            os.mkdir(pic_path)
        else:
            pass
        document = Document()
        word_path = path.split('.')[0] + '.docx'
        doc = fitz.open(path)
        for n in range(doc.page_count):
            page = doc.load_page(n)
            # 获取pdf中的文本信息,并写入word
            document.add_paragraph(page.getText('text'))
        self.window.progressBar.setValue(1)
        for i in range(doc.page_count):
            for image in doc.get_page_images(i):
                xref = image[0]
                pix = fitz.Pixmap(doc, xref)
                if pix.n < 5:
                    pix.writePNG(os.path.join(pic_path, 'page%s-%s.png' % (i, xref)))  # 保存图片
                    document.add_picture(os.path.join(pic_path, 'page%s-%s.png' % (i, xref)), Pt(400), Pt(200))  # 获取pdf中的图片信息,并写入word文档
                # 否则先转换CMYK
                else:
                    pix0 = fitz.Pixmap(fitz.csRGB, pix)
                    pix0.writePNG(os.path.join(pic_path, 'page%s-%s.png' % (i, xref)))
                    document.add_picture(os.path.join(pic_path, 'page%s-%s.png' % (i, xref)), Pt(400), Pt(200))
                    pix0 = None
                    # 释放资源
                    pix = None
        document.save(word_path)  # 保存word文档

5、获取文件path函数1(获取单个文件路径)

 def get_filepath(self):
        """
        弹出文件路径选择框,获取所选择的单个文件路径并写入到单行文本框中
        """
        try:
            mode = self.window.buttonGroup.checkedButton().text()
            if mode == 'word 转 pdf':
                filepath, _ = QFileDialog.getOpenFileName(
                    self.window,  # 父窗口对象
                    "选择上传文件",  # 窗口的标题
                    r"C:",  # 起始目录
                    "word文档类型 (*.docx *.doc )"  # 选择类型过滤项,过滤内容在括号中
                )
                self.window.lineEdit.setReadOnly(False)
                self.window.lineEdit.setText(filepath)
                self.window.lineEdit.setReadOnly(True)
            elif mode == 'pdf 转 word':
                filepath, _ = QFileDialog.getOpenFileName(
                    self.window,  # 父窗口对象
                    "选择上传文件",  # 窗口的标题
                    r"C:",  # 起始目录
                    "word文档类型 (*.pdf)"  # 选择类型过滤项,过滤内容在括号中
                )
                self.window.lineEdit.setReadOnly(False)
                self.window.lineEdit.setText(filepath)
                self.window.lineEdit.setReadOnly(True)
        except:
            QMessageBox.critical(self.window, '错误提示', '请选择转换模式!!!')

5、获取文件path函数2(获取多个文件路径)

    def get_filepaths(self):
        """
        弹出文件路径选择框,获取所选择的多个文件路径并写入到多行文本框中
        """
        try:
            self.list_path = []
            mode = self.window.buttonGroup.checkedButton().text()
            if mode == 'word 转 pdf':
                filepaths, _ = QFileDialog.getOpenFileNames(
                    self.window,
                    "选择你要上传的多个图片",
                    r"C:",
                    "word文档类型 (*.docx *.doc )"
                )
                self.window.plainTextEdit.setReadOnly(False)
                self.window.plainTextEdit.clear()
                for word_path in filepaths:
                    self.window.plainTextEdit.appendPlainText(word_path)
                    self.list_path.append(word_path)
                self.window.plainTextEdit.setReadOnly(True)
            elif mode == 'pdf 转 word':
                filepaths, _ = QFileDialog.getOpenFileNames(
                        self.window,  # 父窗口对象
                        "选择你要上传的多个图片",  # 窗口的标题
                        r"C:",  # 起始目录
                        "word文档类型 (*.pdf)"  # 选择类型过滤项,过滤内容在括号中
                )
                self.window.plainTextEdit.setReadOnly(False)
                self.window.plainTextEdit.clear()
                for word_path in filepaths:
                    self.window.plainTextEdit.appendPlainText(word_path)
                    self.list_path.append(word_path)
                self.window.plainTextEdit.setReadOnly(True)
        except:
            QMessageBox.critical(self.window, '错误提示', '请选择转换模式!!!')

6、处理转化函数1(执行单个word文档和pdf文档互转)

    def create_pdf_word(self):
        """
        执行单个word文档和pdf文档互转
        """
        path = self.window.lineEdit.text()
        if path:
            try:
                mode = self.window.buttonGroup.checkedButton().text()
                if path and (mode == 'word 转 pdf'):
                    self.window.progressBar.setRange(0, 2)
                    # 设置进度条显示进度信息(0-2)对应不同的进度信息
                    self.window.progressBar.setValue(1)
                    self.word_to_pdf(path)
                    # 设置进度条显示进度信息(0-2)对应不同的进度信息
                    self.window.progressBar.setValue(2)
                    # 将进度条倒退到开头
                    self.window.progressBar.reset()
                    self.window.lineEdit.clear()
                elif path and (mode == 'pdf 转 word'):
                    self.window.progressBar.setRange(0, 2)
                    # 设置进度条显示进度信息(0-2)对应不同的进度信息
                    self.window.progressBar.setValue(1)
                    self.pdf_to_word(path)
                    # 设置进度条显示进度信息(0-2)对应不同的进度信息
                    self.window.progressBar.setValue(2)
                    # 将进度条倒退到开头
                    self.window.progressBar.reset()
                    self.window.lineEdit.clear()
            except:
                QMessageBox.critical(self.window, '错误提示', '请选择转换模式!!!')
        else:
            QMessageBox.critical(self.window, '错误提示', '文件路径不能为空!!!')

6、处理转化函数2(执行多个word文档和pdf文档互转)

    def create_pdfs_wrods(self):
        """
        执行多个word文档和pdf文档互转
        """
        text = self.window.plainTextEdit.toPlainText()
        if text:
            try:
                self.window.progressBar.setRange(0, len(self.list_path))
                mode = self.window.buttonGroup.checkedButton().text()
                if mode == 'word 转 pdf':
                    i = 1
                    for path in self.list_path:
                        self.word_to_pdf(path)
                        # 设置进度条显示进度信息(0-3)对应不同的进度信息
                        self.window.progressBar.setValue(i)
                        i += 1
                    # 将进度条倒退到开头
                    self.window.progressBar.reset()
                    self.window.plainTextEdit.clear()
                elif mode == 'pdf 转 word':
                    i = 1
                    for path in self.list_path:
                        self.pdf_to_word(path)
                        # 设置进度条显示进度信息(0-3)对应不同的进度信息
                        self.window.progressBar.setValue(i)
                        i += 1
                    # 将进度条倒退到开头
                    self.window.progressBar.reset()
                    self.window.plainTextEdit.clear()
            except:
                QMessageBox.critical(self.window, '错误提示', '请选择转换模式!!!')
        else:
            QMessageBox.critical(self.window, '错误提示', '文件路径不能为空!!!')

7、实现打开从pdf中获取的图片

    def open_pdf_image(self):
        """
        打开已获取的pdf中的图片
        """
        filepath, _ = QFileDialog.getOpenFileName(
            self.window,  # 父窗口对象
            "选择上传文件",  # 窗口的标题
            r"./pdf_word_images",  # 起始目录
            "word文档类型 (*.png *.jpg)"  # 选择类型过滤项,过滤内容在括号中
        )
        if filepath:
            os.system(f'start {filepath}')
        else:
            pass

完整代码

ui文件下载地址:自提码(py66)

from PySide2.QtWidgets import QApplication, QFileDialog, QMessageBox
from PySide2.QtUiTools import QUiLoader
from PySide2.QtCore import QFile
from win32com.client import constants, gencache
import fitz
from docx import Document
from docx.shared import Pt
import os


class WordTransform:

    def __init__(self):
        """
        加载ui文件,初始化按钮等触发事件响应对接执行函数
        """
        file = QFile('./word_ppt.ui')
        file.open(QFile.ReadOnly)
        file.close()
        self.window = QUiLoader().load(file)
        # 设置单行文本框只读
        self.window.lineEdit.setReadOnly(True)
        # 设置多行文本框只读
        self.window.plainTextEdit.setReadOnly(True)
        # 当按钮“打开文件”被点击触发事件,执行对应函数
        self.window.pushButton1.clicked.connect(self.get_filepath)
        # 当按钮“单个转化”被点击触发事件,执行对应函数
        self.window.pushButton2.clicked.connect(self.create_pdf_word)
        # 当按钮“打开文件”被点击触发事件,执行对应函数
        self.window.pushButton3.clicked.connect(self.get_filepaths)
        # 当按钮“批量转化”被点击触发事件,执行对应函数
        self.window.pushButton4.clicked.connect(self.create_pdfs_wrods)
        # 当按钮“打开pdf中图片”被点击触发事件,执行对应函数
        self.window.pushButton5.clicked.connect(self.open_pdf_image)

    def word_to_pdf(self, path):
        """
        word文档转化pdf文档主功能函数
        """
        pdf_path = path.split('.')[0] + '.pdf'
        word = gencache.EnsureDispatch('Word.Application')
        doc = word.Documents.Open(path, ReadOnly=1)
        # 转化方法
        doc.ExportAsFixedFormat(pdf_path, constants.wdExportFormatPDF)
        word.Quit()

    def pdf_to_word(self, path):
        """
        pdf文档转化word文档主功能函数
        注:该函数木器中能识别pdf中的纯文本和图片信息,表格等其他识别不出
        """
        pic_path = './pdf_word_images'
        if not os.path.exists(pic_path):
            os.mkdir(pic_path)
        else:
            pass
        document = Document()
        word_path = path.split('.')[0] + '.docx'
        doc = fitz.open(path)
        for n in range(doc.page_count):
            page = doc.load_page(n)
            document.add_paragraph(page.getText('text'))
        self.window.progressBar.setValue(1)
        for i in range(doc.page_count):
            for image in doc.get_page_images(i):
                xref = image[0]
                pix = fitz.Pixmap(doc, xref)
                if pix.n < 5:
                    pix.writePNG(os.path.join(pic_path, 'page%s-%s.png' % (i, xref)))
                    document.add_picture(os.path.join(pic_path, 'page%s-%s.png' % (i, xref)), Pt(400), Pt(200))
                # 否则先转换CMYK
                else:
                    pix0 = fitz.Pixmap(fitz.csRGB, pix)
                    pix0.writePNG(os.path.join(pic_path, 'page%s-%s.png' % (i, xref)))
                    document.add_picture(os.path.join(pic_path, 'page%s-%s.png' % (i, xref)), Pt(400), Pt(200))
                    pix0 = None
                    # 释放资源
                    pix = None
        document.save(word_path)

    def get_filepath(self):
        """
        弹出文件路径选择框,获取所选择的单个文件路径并写入到单行文本框中
        """
        try:
            mode = self.window.buttonGroup.checkedButton().text()
            if mode == 'word 转 pdf':
                filepath, _ = QFileDialog.getOpenFileName(
                    self.window,  # 父窗口对象
                    "选择上传文件",  # 窗口的标题
                    r"C:\Users\Administrator\Desktop\2个白嫖\文件",  # 起始目录
                    "word文档类型 (*.docx *.doc )"  # 选择类型过滤项,过滤内容在括号中
                )
                self.window.lineEdit.setReadOnly(False)
                self.window.lineEdit.setText(filepath)
                self.window.lineEdit.setReadOnly(True)
            elif mode == 'pdf 转 word':
                filepath, _ = QFileDialog.getOpenFileName(
                    self.window,  # 父窗口对象
                    "选择上传文件",  # 窗口的标题
                    r"C:\Users\Administrator\Desktop\2个白嫖\文件",  # 起始目录
                    "word文档类型 (*.pdf)"  # 选择类型过滤项,过滤内容在括号中
                )
                self.window.lineEdit.setReadOnly(False)
                self.window.lineEdit.setText(filepath)
                self.window.lineEdit.setReadOnly(True)
        except:
            QMessageBox.critical(self.window, '错误提示', '请选择转换模式!!!')

    def get_filepaths(self):
        """
        弹出文件路径选择框,获取所选择的多个文件路径并写入到多行文本框中
        """
        try:
            self.list_path = []
            mode = self.window.buttonGroup.checkedButton().text()
            if mode == 'word 转 pdf':
                filepaths, _ = QFileDialog.getOpenFileNames(
                    self.window,
                    "选择你要上传的多个图片",
                    r"C:\Users\Administrator\Desktop\2个白嫖\文件",
                    "word文档类型 (*.docx *.doc )"
                )
                self.window.plainTextEdit.setReadOnly(False)
                self.window.plainTextEdit.clear()
                for word_path in filepaths:
                    self.window.plainTextEdit.appendPlainText(word_path)
                    self.list_path.append(word_path)
                self.window.plainTextEdit.setReadOnly(True)
            elif mode == 'pdf 转 word':
                filepaths, _ = QFileDialog.getOpenFileNames(
                        self.window,  # 父窗口对象
                        "选择你要上传的多个图片",  # 窗口的标题
                        r"C:\Users\Administrator\Desktop\2个白嫖\文件",  # 起始目录
                        "word文档类型 (*.pdf)"  # 选择类型过滤项,过滤内容在括号中
                )
                self.window.plainTextEdit.setReadOnly(False)
                self.window.plainTextEdit.clear()
                for word_path in filepaths:
                    self.window.plainTextEdit.appendPlainText(word_path)
                    self.list_path.append(word_path)
                self.window.plainTextEdit.setReadOnly(True)
        except:
            QMessageBox.critical(self.window, '错误提示', '请选择转换模式!!!')

    def create_pdf_word(self):
        """
        执行单个word文档和pdf文档互转
        """
        path = self.window.lineEdit.text()
        if path:
            try:
                mode = self.window.buttonGroup.checkedButton().text()
                if path and (mode == 'word 转 pdf'):
                    self.window.progressBar.setRange(0, 2)
                    # 设置进度条显示进度信息(0-2)对应不同的进度信息
                    self.window.progressBar.setValue(1)
                    self.word_to_pdf(path)
                    # 设置进度条显示进度信息(0-2)对应不同的进度信息
                    self.window.progressBar.setValue(2)
                    # 将进度条倒退到开头
                    self.window.progressBar.reset()
                    self.window.lineEdit.clear()
                elif path and (mode == 'pdf 转 word'):
                    self.window.progressBar.setRange(0, 2)
                    # 设置进度条显示进度信息(0-2)对应不同的进度信息
                    self.window.progressBar.setValue(1)
                    self.pdf_to_word(path)
                    # 设置进度条显示进度信息(0-2)对应不同的进度信息
                    self.window.progressBar.setValue(2)
                    # 将进度条倒退到开头
                    self.window.progressBar.reset()
                    self.window.lineEdit.clear()
            except:
                QMessageBox.critical(self.window, '错误提示', '请选择转换模式!!!')
        else:
            QMessageBox.critical(self.window, '错误提示', '文件路径不能为空!!!')

    def create_pdfs_wrods(self):
        """
        执行多个word文档和pdf文档互转
        """
        text = self.window.plainTextEdit.toPlainText()
        if text:
            try:
                self.window.progressBar.setRange(0, len(self.list_path))
                mode = self.window.buttonGroup.checkedButton().text()
                if mode == 'word 转 pdf':
                    i = 1
                    for path in self.list_path:
                        self.word_to_pdf(path)
                        # 设置进度条显示进度信息(0-3)对应不同的进度信息
                        self.window.progressBar.setValue(i)
                        i += 1
                    # 将进度条倒退到开头
                    self.window.progressBar.reset()
                    self.window.plainTextEdit.clear()
                elif mode == 'pdf 转 word':
                    i = 1
                    for path in self.list_path:
                        self.pdf_to_word(path)
                        # 设置进度条显示进度信息(0-3)对应不同的进度信息
                        self.window.progressBar.setValue(i)
                        i += 1
                    # 将进度条倒退到开头
                    self.window.progressBar.reset()
                    self.window.plainTextEdit.clear()
            except:
                QMessageBox.critical(self.window, '错误提示', '请选择转换模式!!!')
        else:
            QMessageBox.critical(self.window, '错误提示', '文件路径不能为空!!!')

    def open_pdf_image(self):
        """
        打开已获取的pdf中的图片
        """
        filepath, _ = QFileDialog.getOpenFileName(
            self.window,  # 父窗口对象
            "选择上传文件",  # 窗口的标题
            r"./pdf_word_images",  # 起始目录
            "word文档类型 (*.png *.jpg)"  # 选择类型过滤项,过滤内容在括号中
        )
        if filepath:
            os.system(f'start {filepath}')
        else:
            pass


if __name__ == '__main__':
    app = QApplication([])
    new_word = WordTransform()
    new_word.window.show()
    app.exec_()


总结

1、word 转pdf 还是可以的,可以单个转,也可以批量转,还是挺方便的
2、pdf 转word 目前还不知道怎么识别pdf中的表格,只能识别文本和图片,希望有大佬可以指点下,谢谢!
3、目前还没进去大批量的测试,如果需要可以进行多线程来实现

本文标签: 文档wordPDF