Python提取PDF發(fā)票信息保存Excel文件并制作EXE程序的全過程
前言
通過本篇文章可學習pdf
發(fā)票信息的提取,內(nèi)容保存至Excel
,了解命令圖像工具Gooey
,以及如何將python文件打包為exe
程序
背景
現(xiàn)在電子發(fā)票越來越普遍,各公司開票形式已基本無紙化。目前所在公司的情況是,每個人自己報賬,需要將發(fā)票信息(發(fā)票號/金額)填如K3系統(tǒng)進行流程申請,另外將電子發(fā)票打印為紙質并貼票后找領導簽字及審批K3的流程;之后在將紙質單據(jù)送至財務審批。如果財務發(fā)現(xiàn)數(shù)據(jù)填寫不正確,就會將流程和單據(jù)打回來,又要重新找領導簽字審批,相當麻煩。
分析
為了減少報賬被打回來的情況,我們先分析,整個報賬過程中,存在的問題
下載回來的發(fā)票文件命名不規(guī)范不容易識別
如:04500160011131347550.pdf
填K3時需要復制發(fā)票號和金額,還要選擇發(fā)票類型
每次要打開pdf發(fā)票復制發(fā)票號和金額
發(fā)票可能存在錯誤情況:如公司名稱或納稅人識別號不正確
每次還要檢查一下
優(yōu)化
一開始的想法是,做一個程序,識別發(fā)票信息并提供復制按鈕,方便復制到k3。自動檢查發(fā)票信息是否完整正確,公司名稱和納稅人識別號是否正確,如不正確則提示錯誤,另外自動將文件重名稱,及一鍵打印功能。
不過由于對Python的GUI還不大熟悉,就改了方式:將發(fā)票信息提取至Excel,在自己到Excel上復制信息和檢查發(fā)票是否完整,另外將文件重命名為開票公司+金額的形式
最終效果
實現(xiàn)
讀取pdf發(fā)票
使用pdfplumber,安裝命令pip install pdfplumber
,
import pdfplumber import re import os def re_text(bt, text): m1 = re.search(bt, text) if m1 is not None: return re_block(m1[0]) def re_block(text): return text.replace(' ', '').replace(' ', '').replace(')', '').replace(')', '').replace(':', ':') def get_pdf(dir_path): pdf_file = [] for root, sub_dirs, file_names in os.walk(dir_path): for name in file_names: if name.endswith('.pdf'): filepath = os.path.join(root, name) pdf_file.append(filepath) return pdf_file def read(): filenames = get_pdf('C:\Users\Administrator\Desktop\a') # 修改為自己的文件目錄 for filename in filenames: print(filename) with pdfplumber.open(filename) as pdf: first_page = pdf.pages[0] pdf_text = first_page.extract_text() if '發(fā)票' not in pdf_text: continue # print(pdf_text) print('--------------------------------------------------------') print(re_text(re.compile(r'[\u4e00-\u9fa5]+電子普通發(fā)票.*?'), pdf_text)) t2 = re_text(re.compile(r'[\u4e00-\u9fa5]+專用發(fā)票.*?'), pdf_text) if t2: print(t2) # print(re_text(re.compile(r'發(fā)票代碼(.*\d+)'), pdf_text)) print(re_text(re.compile(r'發(fā)票號碼(.*\d+)'), pdf_text)) print(re_text(re.compile(r'開票日期(.*)'), pdf_text)) print(re_text(re.compile(r'名\s*稱\s*[::]\s*([\u4e00-\u9fa5]+)'), pdf_text)) print(re_text(re.compile(r'納稅人識別號\s*[::]\s*([a-zA-Z0-9]+)'), pdf_text)) price = re_text(re.compile(r'小寫.*(.*[0-9.]+)'), pdf_text) print(price) company = re.findall(re.compile(r'名.*稱\s*[::]\s*([\u4e00-\u9fa5]+)'), pdf_text) if company: print(re_block(company[len(company)-1])) print('--------------------------------------------------------') read()
通過上述代碼可以實現(xiàn)對pdf發(fā)票的內(nèi)容識別和輸出功能,完整的功能請通過學習本文后續(xù)的內(nèi)容自主實現(xiàn)。
寫入Excel
使用xlwt寫Excel文件,安裝命令pip install xlwt
,一個簡單的例子如下
import xlwt # 創(chuàng)建工作簿 wb = xlwt.Workbook() # 創(chuàng)建表單 sh = wb.add_sheet('sheet 1') # 寫入數(shù)據(jù) sh.write(0, 1, '姓名') # 保存 wb.save('test.xls')
創(chuàng)建圖像界面
使用Gooey創(chuàng)建GUI圖像界面,安裝命令pip install Gooey
官網(wǎng)地址:https://github.com/chriskiehl/Gooey 目前是:15.4k stars
這里對Gooey的適用情況做一個說明,Gooey適用于命令行的圖形工具,也就是只做輸入(有各種輸入/選擇框)和輸出的情況,不適用于做界面展示,無法添加自定義按鈕,如button等。使用print就能將輸出內(nèi)容顯示到GUI圖形界面上
一個簡單的例子
from gooey import Gooey, GooeyParser @Gooey(program_name="簡單的實例") def main(): parser = GooeyParser(description="第一個示例!") parser.add_argument('文件路徑', widget="FileChooser") # 文件選擇框 parser.add_argument('日期', widget="DateChooser") # 日期選擇框 args = parser.parse_args() # 接收界面?zhèn)鬟f的參數(shù) print(args) if__name__ == '__main__': main()
打包為exe文件
使用pyinstaller將代碼打包為exe文件
安裝命令pip install pyinstaller
打包命令pyinstaller -F xxxxx.py -w
(xxxxx.py改為具體的.py文件名)
等待打包完成,在代碼目錄的會生成dist
文件夾,打開后可以看到exe程序
注意:程序有中文輸出的請查看該文章,避免打包后程序無法正常運行,參考如下
附:解決Gooey在打包成exe文件后打印中文報UnicodeDecodeError: 'utf-8' codec can't decode
問題
在使用Gooey這個工具生成GUI的時候,沒有打包前測試是好的,但是當打包成exe文件后,雙擊exe運行填入所需選項執(zhí)行報UnicodeDecodeError: 'utf-8' codec can't decode的錯誤。
PS C:\Users\faces\Desktop\gooey demo\dist> .\auto.exe
Exception in thread Thread-1:
Traceback (most recent call last):
File "threading.py", line 926, in _bootstrap_inner
File "threading.py", line 870, in run
File "site-packages\gooey\gui\processor.py", line 71, in _forward_stdout
File "site-packages\gooey\gui\processor.py", line 84, in _extract_progress
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb5 in position 13: invalid start byte
通過查找github中提交的issue發(fā)現(xiàn)是打包后環(huán)境的encoding與打包時的encoding不一致導致的問題。
解決方案
在Gooey裝飾器中加入關鍵字參數(shù)encoding='cp936'
from gooey import Gooey, GooeyParser @Gooey(encoding='cp936') def main(): parser = GooeyParser(description="Export music lite") parser.add_argument('exe文件', widget="FileChooser") parser.add_argument('flac文件夾', widget="DirChooser") parser.add_argument('MP3導出文件夾', widget="DirChooser") args = parser.parse_args() print(args) if __name__ == "__main__": main()
問題
接下來我想更改Gooey生成的GUI頁面為中文,那么代碼改為
from gooey import Gooey, GooeyParser @Gooey(encoding='cp936', language='chinese') def main(): parser = GooeyParser(description="Export music lite") ...
這時候執(zhí)行會報如下錯誤
PS C:\Users\faces\Desktop\gooey demo\dist> .\auto.exe
Traceback (most recent call last):
File "auto.py", line 17, in <module>
File "site-packages\gooey-1.0.3-py3.7.egg\gooey\python_bindings\gooey_decorator.py", line 87, in inner2
File "auto.py", line 12, in main
File "site-packages\gooey-1.0.3-py3.7.egg\gooey\python_bindings\gooey_parser.py", line 114, in parse_args
File "site-packages\gooey-1.0.3-py3.7.egg\gooey\python_bindings\gooey_decorator.py", line 82, in run_gooey
File "site-packages\gooey-1.0.3-py3.7.egg\gooey\gui\application.py", line 21, in run
File "site-packages\gooey-1.0.3-py3.7.egg\gooey\gui\application.py", line 28, in build_app
File "site-packages\gooey-1.0.3-py3.7.egg\gooey\gui\lang\i18n.py", line 24, in load
File "json\__init__.py", line 293, in load
UnicodeDecodeError: 'gbk' codec can't decode byte 0xa7 in position 20: illegal multibyte sequence
解決方案
從報錯信息中可以看到是因為load代碼的時候使用encoding='cp936'去加載文件導致的錯誤,那么簡單粗暴的方法是編輯site-packages\gooey-1.0.3-py3.7.egg\gooey\gui\lang\i18n.py這個文件
找到
with io.open(os.path.join(language_dir, json_file), 'r', encoding=encoding) as f: _DICTIONARY = json.load(f)
修改為
with io.open(os.path.join(language_dir, json_file), 'r', encoding='utf-8') as f: _DICTIONARY = json.load(f)
總結
到此這篇關于Python提取PDF發(fā)票信息保存Excel文件并制作EXE程序的文章就介紹到這了,更多相關Python提取PDF發(fā)票信息保存Excel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
在pytorch中如何查看模型model參數(shù)parameters
這篇文章主要介紹了在pytorch中如何查看模型model參數(shù)parameters,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11python 刪除系統(tǒng)中的文件(按時間,大小,擴展名)
這篇文章主要介紹了python 如何刪除系統(tǒng)中的文件,分別按時間,大小,擴展名刪除,滿足不同需求,感興趣的朋友可以了解下2020-11-11將pymysql獲取到的數(shù)據(jù)類型是tuple轉化為pandas方式
這篇文章主要介紹了將pymysql獲取到的數(shù)據(jù)類型是tuple轉化為pandas方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-05-05Python 聊聊socket中的listen()參數(shù)(數(shù)字)到底代表什么
本篇文章對Python 聊聊socket中的listen()參數(shù)(數(shù)字)到底代表什么,進行了很好的講解,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04django如何連接已存在數(shù)據(jù)的數(shù)據(jù)庫
這篇文章主要給大家介紹了關于django如何連接已存在數(shù)據(jù)的數(shù)據(jù)庫的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用django具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2018-08-08python 實現(xiàn)長數(shù)據(jù)完整打印方案
這篇文章主要介紹了python 實現(xiàn)長數(shù)據(jù)完整打印方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03