1. 程式人生 > 實用技巧 >PDFtoWORD_V1.1版本支援PDF文件中的文字和圖片一起轉化到word文件中了~

PDFtoWORD_V1.1版本支援PDF文件中的文字和圖片一起轉化到word文件中了~

​昨天菜鳥小白做了一個小軟體——PDFtoWORD,作用就是將pdf檔案中的文字提取出來自動轉化為可編輯的word型別。但是這個軟體目前也只能將檔案PDF中的文字提取出來,還無法提取圖片。為了進一步完善這個小工具,菜鳥小白一下班就看有沒有什麼方法能夠將pdf中的圖片提取出來。
功夫不負有心人,還真讓菜鳥小白找到了方法。使用fitz庫能夠很好的提取出圖片,然後通過python-docx庫將提取出來的圖片拷貝到word中去。整體的過程如下:

PDF檔案中提取文字

接下來我們就來看看程式碼,通過pdfminer處理PDF檔案還是昨天的程式碼,有不理解的地方可以直接參考昨天的分享。

PDF檔案中提取圖片

我們先看看如何將PDF中的圖片從PDF中提取出來存放到資源池中。

# -*- coding:utf-8 -*-#author:菜鳥小白的學習分享import fitzimport timeimport reimport osdef pdf2pic(path, pic_path):    t0 = time.clock()  # 生成圖片初始時間    checkXO = r"/Type(?= */XObject)"  # 使用正則表示式來查詢圖片    checkIM = r"/Subtype(?= */Image)"    doc = fitz.open(path)  # 開啟pdf檔案
imgcount = 0 # 圖片計數 lenXREF = doc._getXrefLength() # 獲取物件數量長度 # 列印PDF的資訊 print("檔名:{}, 頁數: {}, 物件: {}".format(path, len(doc), lenXREF - 1)) # 遍歷每一個物件 for i in range(1, lenXREF): text = doc._getXrefString(i) # 定義物件字串 isXObject = re.search(checkXO, text) # 使用正則表示式檢視是否是物件
isImage = re.search(checkIM, text) # 使用正則表示式檢視是否是圖片 if not isXObject or not isImage: # 如果不是物件也不是圖片,則continue continue imgcount += 1 pix = fitz.Pixmap(doc, i) # 生成影象物件 new_name = "圖片{}.png".format(imgcount) # 生成圖片的名稱 if pix.n < 5: # 如果pix.n<5,可以直接存為PNG pix.writePNG(os.path.join(pic_path, new_name)) else: # 否則先轉換CMYK pix0 = fitz.Pixmap(fitz.csRGB, pix) pix0.writePNG(os.path.join(pic_path, new_name)) pix0 = None pix = None # 釋放資源 t1 = time.clock() # 圖片完成時間 print("執行時間:{}s".format(t1 - t0)) print("提取了{}張圖片".format(imgcount))if__name__=='__main__': pic_path = r'.\圖片' path = "oracle資料庫安裝.pdf" # 建立儲存圖片的資料夾 if os.path.exists(pic_path): print("資料夾已存在,不必重新建立!") pass else: os.mkdir(pic_path) pdf2pic(path, pic_path)

這個是一個可以獨立執行的程式,作用就是將pdf中的圖片存放在圖片資料夾下面。在執行之前我們首先要使用pip install pymupdf庫,庫中包含了我們需要使用的fitz庫。

將圖片寫入word文件

為了大致保證圖片貼上的位置和PDF中的位置一致,我們需要在昨天程式的基礎上修改一下對每一頁PDF檔案的處理,對每一頁的物件進行判斷,若是文字則直接拷貝到word中,若是圖片則按照pdf中的順序依次拷貝到word中。程式碼如下:

        # 迴圈遍歷列表,每次處理一個page內容        # doc.get_pages()獲取page列表        for page in doc.get_pages():            interpreter.process_page(page)            # 接收該頁面的LTPage物件            layout = device.get_result()            # 這裡的layout是一個LTPage物件 裡面存放著page解析出來的各種物件            # 一般包括LTTextBox,LTFigure,LTImage,LTTextBoxHorizontal等等一些對像            # 想要獲取文字就得獲取物件的text屬性            for x in layout:                try:                    if (isinstance(x, LTTextBoxHorizontal)):                        # with open('%s' % (save_path), 'a') as f:                        #     result = x.get_text()                        #     print(result)                        #     f.write(result + "\n")                        result = x.get_text()                        print(result)                        doc_object.add_paragraph(result)                    elif (isinstance(x, LTFigure)):                        cont +=1                        images =  r".\圖片\圖片{}.png".format(cont)                        print(images)                            # doc.add_paragraph(string)  # 新增文字                        doc_object.add_picture(images, width=Inches(7))  # 新增圖, 設定寬度                except:print("Failed")

最後我們再將主函式修改一下,進行呼叫

if __name__ == '__main__':    # 解析本地PDF文字,儲存到本地TXT    file_name = input("請輸入需要轉化的檔名:")    doc_name = input("請輸入轉化後的檔名(支援TXT、doc、HTML格式):")    pic_path = r'.\圖片'    flag = False    # 建立儲存圖片的資料夾    if os.path.exists(pic_path):        print("資料夾已存在,不必重新建立!")        pass    else:        os.mkdir(pic_path)        flag = True    PNGfromPDF.pdf2pic(file_name,pic_path)    doc = Document()  # doc物件    # with open(r'菜鳥小白.pdf', 'rb') as pdf_html:    #     parse(pdf_html, r'菜鳥小白的學習分享.doc')    with open(file_name, 'rb') as pdf_html:        parse(pdf_html, doc_name,doc)    doc.save(doc_name)  # 儲存路徑

最終實現效果

原始PDF檔案

轉化後的word

細心的小夥伴一定發現了一些問題,就是圖片並沒有完全按照PDF的順序進行放置。這個我後來查閱資料和除錯程式發現:pdfminer程式在處理每一頁PDF時會將物件進行分類,返回的結果也是按照不同型別的物件分塊的,這樣就造成了我們還原的word中每一頁都是所有的文字在前,圖片在後的情況。

這個遺留就當做軟體的一個bug遺留吧,版本先行釋出,有需要獲取最新轉化工具的關注“菜鳥小白的學習分享”公眾號,回覆"PDFtoWORD_V1.1"獲取吧。


好了,今天的分享就到這裡,如果你也喜歡菜鳥小白的分享,就給菜鳥小白點選一個關注、在看、點贊+雞腿吧。

晚安~