python實(shí)現(xiàn)pdf轉(zhuǎn)換為word

為了不在某個平臺開通會員,充錢歹袁,我借鑒了github某位大神的代碼https://github.com/python-fan/pdf2word屹篓,成功實(shí)現(xiàn)pdf轉(zhuǎn)換為word技肩,各位可以參考借鑒下俗孝。

1.在使用該代碼時酒甸,需要安裝對應(yīng)的第三方庫包,pdf轉(zhuǎn)換word(即提取pdf文字寫入到word中)需要兩個庫包:pdfminer3kpython-docx赋铝;需要提取pdf中的圖片插勤,需要?pymupdf該庫名進(jìn)行操作提取


pdfminer3k安裝圖


python-docx安裝圖
pymupdf安裝圖

2.實(shí)現(xiàn)代碼如下:

import os

from configparserimport ConfigParser

from ioimport StringIO

from ioimport open

from concurrent.futuresimport ProcessPoolExecutor

from pdfminer.pdfinterpimport PDFResourceManager

from pdfminer.pdfinterpimport process_pdf

from pdfminer.converterimport TextConverter

from pdfminer.layoutimport LAParams

from docximport Document

import fitz

import time

import re

#提取圖片函數(shù)

def pdf2pic(path, pic_path):

'''# 從pdf中提取圖片? ,param path: pdf的路徑 革骨,param pic_path: 圖片保存的路徑

'''

? ? # 使用正則表達(dá)式來查找圖片

? ? checkXO =r"/Type(?= */XObject)"

? ? checkIM =r"/Subtype(?= */Image)"

? ? # 打開pdf

? ? doc = fitz.open(path)

# 圖片計數(shù)

? ? imgcount =0

? ? lenXREF = doc.xrefLength()?#最新fitz庫是沒有doc._getXrefLength()

# 打印PDF的信息

? ? print("文件名:{}, 頁數(shù): {}, 對象: {}".format(path, len(doc), lenXREF -1))

# 遍歷每一個對象

? ? for iin range(1, lenXREF):

# 定義對象字符串

? ? ? ? text = doc.xrefObject(i)?#最新fitz庫是沒有g(shù)etObjectString()

isXObject = re.search(checkXO, text)

# 使用正則表達(dá)式查看是否是圖片

? ? ? ? isImage = re.search(checkIM, text)

# 如果不是對象也不是圖片农尖,則continue

? ? ? ? if not isXObjector not isImage:

continue

? ? ? ? imgcount +=1

? ? ? ? # 根據(jù)索引生成圖像

? ? ? ? pix = fitz.Pixmap(doc, i)

# 根據(jù)pdf的路徑生成圖片的名稱

? ? ? ? new_name = path.replace('\\', '_') +"_img{}.png".format(imgcount)

new_name = new_name.replace(':', '')

# 如果pix.n<5,可以直接存為PNG

? ? ? ? if pix.n <5:

pix.writePNG(os.path.join(pic_path, new_name))

# 否則先轉(zhuǎn)換CMYK

? ? ? ? else:

pix0 = fitz.Pixmap(fitz.csRGB, pix)

pix0.writePNG(os.path.join(pic_path, new_name))

pix0 =None

? ? ? ? # 釋放資源

? ? ? ? pix =None

? ? ? ? print("提取了{(lán)}張圖片".format(imgcount))

#讀取pdf文件函數(shù)

def read_from_pdf(file_path):

with open(file_path, 'rb')as file:

resource_manager = PDFResourceManager()

return_str = StringIO()

lap_params = LAParams()

device = TextConverter(

resource_manager, return_str, laparams=lap_params)

process_pdf(resource_manager, device, file)

device.close()

content = return_str.getvalue()

return_str.close()

return content

#保存word文件函數(shù)

def save_text_to_word(content, file_path):

doc = Document()

for linein content.split('\n'):#以換行符為分割

? ? ? ? paragraph = doc.add_paragraph()

paragraph.add_run(remove_control_characters(line))

doc.save(file_path)

#移除字符

def remove_control_characters(content):

mpa =dict.fromkeys(range(32))

return content.translate(mpa)

#直接調(diào)用read_from_pdf(pdf_file_path)函數(shù)和save_text_to_word(content, word_file_path)函數(shù)

def pdf_to_word(pdf_file_path, word_file_path):

content = read_from_pdf(pdf_file_path)

save_text_to_word(content, word_file_path)

#寫個主函數(shù),可以讀取配置文件信息和使用多進(jìn)程處理pdf文件

def main():

#讀取配置文件信息

? ? config_parser = ConfigParser()

config_parser.read('config.cfg')

config = config_parser['default']

#多進(jìn)程處理任務(wù)良哲,可以同時執(zhí)行多個pdf文件進(jìn)行轉(zhuǎn)換為word文件

? ? tasks = []

with ProcessPoolExecutor(max_workers=int(config['max_worker']))as executor:

for filein os.listdir(config['pdf_folder']):

extension_name = os.path.splitext(file)[1]

if extension_name !='.pdf':

continue

? ? ? ? ? ? file_name = os.path.splitext(file)[0]

pdf_file = config['pdf_folder'] +'/' + file

word_file = config['word_folder'] +'/' + file_name +'.docx'

? ? ? ? ? ? print('正在處理: ', file)

result = executor.submit(pdf_to_word, pdf_file, word_file)

tasks.append(result)

while True:

exit_flag =True

? ? ? ? for taskin tasks:

if not task.done():

exit_flag =False

? ? ? ? if exit_flag:

print('完成')

exit(0)

3.執(zhí)行代碼運(yùn)行

if __name__ =='__main__':

fpath=os.getcwd()

# pdf_to_word(fpath+'\\pdf\\test.pdf',fpath+'\\word\\test.docx')

? ? pdf2pic(fpath+'\\pdf\\test.pdf',fpath+'\\word')

4.運(yùn)行結(jié)果展示


讀取test.pdf文件


pdf轉(zhuǎn)換word的test.docx
提取pdf中的圖片到word目錄中
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盛卡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子臂外,更是在濱河造成了極大的恐慌,老刑警劉巖喇颁,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漏健,死亡現(xiàn)場離奇詭異,居然都是意外死亡橘霎,警方通過查閱死者的電腦和手機(jī)蔫浆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來姐叁,“玉大人瓦盛,你說我怎么就攤上這事⊥馇保” “怎么了原环?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長处窥。 經(jīng)常有香客問我嘱吗,道長,這世上最難降的妖魔是什么滔驾? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任谒麦,我火速辦了婚禮俄讹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘绕德。我一直安慰自己患膛,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布耻蛇。 她就那樣靜靜地躺著踪蹬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪城丧。 梳的紋絲不亂的頭發(fā)上延曙,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機(jī)與錄音亡哄,去河邊找鬼枝缔。 笑死,一個胖子當(dāng)著我的面吹牛蚊惯,可吹牛的內(nèi)容都是我干的愿卸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼截型,長吁一口氣:“原來是場噩夢啊……” “哼趴荸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起宦焦,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤发钝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后波闹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酝豪,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年精堕,在試婚紗的時候發(fā)現(xiàn)自己被綠了孵淘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡歹篓,死狀恐怖瘫证,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情庄撮,我是刑警寧澤背捌,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站洞斯,受9級特大地震影響载萌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一扭仁、第九天 我趴在偏房一處隱蔽的房頂上張望垮衷。 院中可真熱鬧,春花似錦乖坠、人聲如沸搀突。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽仰迁。三九已至,卻和暖如春顽分,著一層夾襖步出監(jiān)牢的瞬間徐许,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工卒蘸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留雌隅,地道東北人。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓缸沃,卻偏偏與公主長得像恰起,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子趾牧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容