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、專案需要匯入的庫
1 2 3 4 | pip insatll pymupdf (使用fitz需要安裝) pip insatll pyside2 (使用pyside2需要安裝) pip install python-docx (使用docx需要安裝) pip install pywin32 (使用win32com需要安裝) |
1 2 3 4 5 6 7 8 | 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檔案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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功能和訊號
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # 設定單行文字框唯讀 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檔案主功能函式)
1 2 3 4 5 6 7 8 9 10 | 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檔案主功能函式)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 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(取得單個檔案路徑)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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(取得多個檔案路徑)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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檔案互轉)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 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檔案互轉)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 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中取得的圖像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | 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:UsersAdministratorDesktop2個白嫖檔案", # 起始目錄 "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:UsersAdministratorDesktop2個白嫖檔案", # 起始目錄 "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:UsersAdministratorDesktop2個白嫖檔案", "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:UsersAdministratorDesktop2個白嫖檔案", # 起始目錄 "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、目前還沒進去大批量的測試,如果需要可以進行多執行緒來實現