巧用Python的camelot庫批量提取PDF發票資訊

Gandedong 發表於 2021-09-23
Python

巧用Python的camelot庫批量提取PDF發票資訊

PDF是一種文件格式,因為這種格式不受作業系統的限制,而且方便儲存和傳輸,所以相關的pdf軟體非常受歡迎。目前市場上有很多pdf軟體,大部分是閱讀類,也有支援對pdf的編輯、轉換成Word等功能,但這部分工具不少是收費的。

例如我就很喜歡某個PDF轉換軟體,買了個終身VIP會員,目的就是將電子發票轉換成Excel格式,並提取相關資料。

Python

現在很多增值稅普通發票都是電子發票,其格式都是以PDF格式進行儲存的,而且相信未來的增值稅電子專票也會以PFD格式儲存。那麼財務能不能將PFD格式的發票資訊批量讀取到Excel中呢?特別是不花錢的情況下。

例如我從京東中收到幾十份電子發票,能不能通過什麼辦法將其金額、稅額一次性的錄入到某個Excel檔案中呢?

可以的,但問題是python可以操作PDF檔案的庫有好幾個,如PyPDF2、pyPDF4、pikepdf、ReportLab、pdfplumber、PyMuPDF等,那麼我們應該選擇哪一個庫為我們工作呢?

因為不是所有PDF庫都能讀取所有版本的電子發票,有些庫只能讀取2018年之前的版本,有些庫對2019年的發票不能讀取中文等等。

例如用pdfplumber庫,我們讀取中石化的電子發票時,只能讀取數字。

Python

Python

用pdfplumber庫的話,雖然可以讀取中文,但不能解析表格:

Python

我們的電子發票上面,除了有文字、表格、圖片,我們需要讀取以上的這些資訊,還還需要有解析表格的功能。當然,其他的Python庫也可以讀取,但為了減少讀取時出現錯誤,我建議選擇用camelot庫來讀取發票。

Camelot譯文為卡美洛,是阿瑟王傳說中的城堡,但在python庫中,這是一個PDF表格讀取庫,而且比較冷門,不過非常適合用來提取發票。它能將每個PDF表格提取到Pandas DataFrame 中,對資料分析非常方便,更讓人滿意的是能比較準確的識別中文。

設計camelot庫是一位叫做維納亞克·梅塔的印度電腦工程師,是一位印度90後。從事資料分析的工作。如果對這個庫有什麼疑問的,可以在Github留言給它。老實說,這個庫的安裝比較麻煩,我也走了不少彎路,以下是我的安裝總結:

千萬不要用pip install camelot來安裝,因為即使安裝成功了也會報錯,正確的方法是在Anaconda中用conda install -c conda-forge camelot-py命令。

Python

不要用PIP安裝,不然的話會非常麻煩,安裝成功之後,你就等於安裝了一套python庫,包括PyPDF2庫、 camelot庫、ghostscript庫、opencv庫、 pdfminer.six-庫、 pdftopng庫、以及tabulate庫。

另外安裝後,需要到www.ghostscript.com/download/gsdnl...官網安裝Ghostscript軟體,不然的話會報錯,由於我是Win10的,選擇用64bit。安裝成功後記得重啟電腦。

Python

這個時候我們再用camelot去讀取發票,就會發現已經轉變成表格格式。

Python

現在,我先介紹一下這個庫的基本操作。

import camelot #匯入庫

tables = camelot.read_pdf('發票名稱.pdf')

tables[0].df ##用提取表格顯示

其中tables[0]表示第一張表格,如果是tables[1]表示第二張表格,.df表示用pandas方式顯示錶格。

預設情況下,Camelot庫只會對PDF 的第一頁來提取表格。如果要指定多個頁面,您可以使用pages關鍵字引數:

camelot.read_pdf(‘發票名稱.pdf’, pages=’1,2,3’)##提取1,2,3頁的表格,或者用

camelot.read_pdf(‘發票名稱.pdf’, pages=’1-3’)或者pages=’1-end’都可以。

匯入之後,如果我們發現有一些不需要的字元,如空格、點和換行符之類的,我們可以用strip_text引數去除。

tables = camelot.read_pdf(‘發票名稱.pdf’, strip_text=’ \n’)

tables[0].df

執行如下:

Python

但是我發現這種單元格不好看,好像有些單元格沒有拆分一樣,這時我們可以加上shift_text=[‘’]這個引數,讓各行列分組更緊密。

tables = camelot.read_pdf(‘044002007111_22865083.pdf’,shift_text=[‘’],strip_text=’\n’)

tables[0].df

Python

這個時候,基本上發票的資料可以出來了。

我們可以用tables[0].to_csv(‘發票.csv’)來儲存,或用to_excel()為Excel格式。

Python

如果是非常多的發票呢?這是一個非常有現實意義的問題,相信不少的出納會希望有一款軟體能批量讀取發票,然後將其轉化成Excel檔案。以下是我分享的程式碼,希望可以幫到大家。

##批量讀取發票,然後彙總成一個CSV檔案
import camelot
import pandas as pd 
import os
##定義資料夾位置
directoryPath = r'E:\py讀取pdf發票彙總'##如果改為=os.getcwd()表示當前資料夾
os.chdir(directoryPath)
print(os.listdir())##列取該資料夾下所有檔名稱
folderList = os.listdir(directoryPath)
for folders, sub_folders, file in os.walk(directoryPath):  ##所有檔案的路徑
    for name in file:  ##定義所需檔名
        if name.endswith(".pdf"):  ##如果檔名是以.pdf結束的話
            filename = os.path.join(folders,name) ##定義這條路徑
            print(filename)##輸出檔案路徑
            print(name)##輸出檔名
            tables = camelot.read_pdf(filename,shift_text=[''],strip_text='\n')##讀取pdf檔案,
            df01= tables[0].df##轉換為DF表格
            #df01.to_excel('{name}.xlsx',sheet_name=name)
            df01.to_csv('foo2.csv',mode="a",encoding="utf_8_sig")##儲存為CSV格式,以直接使引數mode='a’實現每個表追加資料。

除了能讀取發票之外,也可以讀取申報表。在電子稅務局,我們可以查詢以及下載已經申報的申報表,包括增值稅申報表、所得稅申報表以及綜合申報表等。這些報表不是Excel格式的,全部都是PDF格式的。如果只做一家公司的賬當然是沒有問題的,但如果是好幾家公司的賬,要核對每個月的申報表以及每家子公司的申報表時,這就麻煩了。

舊的方法是一張一張的列印下來,然後逐張分析。好一點的用商業化PDF轉化軟體,批量將PDF轉化成Excel檔案,然後再分類彙總,資料透視等等。不過如果安裝了Camelot之後,你就可以用這個庫直接在PDF資料夾抓取資料,直接用Pandas庫進行分析。而且更方便的是,可以設定好指令碼程式,解決重複分析的問題。

我用一個例子來說明一下:

import pandas as pd
import camelot
import os
directoryPath =os.getcwd()
folderList = os.listdir(directoryPath)
for name in folderList:
    if '增值稅'and".pdf" in name:
        filename = os.path.join(directoryPath,name)
        print(filename)##輸出檔案路徑
        print(name)##輸出檔名
        tables = camelot.read_pdf(name,pages='1')##讀取pdf檔案,
tables[0].df
df01=tables[0].df
df02=df01.iloc[[4,5,9]]
df02

執行後:

Python

特別要注意的是,你要保證你瀏覽器內的pdf版本為最新版,我見到有的同事用其他瀏覽器下載的申報表檔案,因為版本原因不能被Camelot讀取,而相同的申報表,我卻可以讀取。這顯然是儲存PDF檔案時出現問題。

本作品採用《CC 協議》,轉載必須註明作者和本文連結