PDFの表からデータを取得したい
PDFの表からデータを取得したかったので、PyMuPDFを使ってデータを取得してみました。
ドキュメント
pip install
pip install PyMuPDF
コード
ドキュメントのコードです。
ChatGPTにコメントを日本語にしてもらいました。
import fitz
from pprint import pprint
# ドキュメントを開く
doc = fitz.open("test.pdf")
# ページを取得する
page = doc[0]
# ページ上にあるテーブルを検出する
tabs = page.find_tables()
# 検出されたテーブルの数を表示する
print(f"{len(tabs.tables)}個のテーブルが{page}上に見つかりました")
# 少なくとも1つのテーブルが見つかった場合
if tabs.tables:
# 最初のテーブルの内容を表示する
pprint(tabs[0].extract())
表からデータを取得する
1ページのPDFに1つの表があるとき
このようなPDFがあります。
表(テーブル)のデータを取得します。
PDFのファイルは同一ディレクトリに保存します。
from pprint import pprint
import fitz
# ドキュメントを開く
doc = fitz.open("recipe.pdf")
# ページを取得する
page = doc[0]
# ページ上にあるテーブルを検出する
tabs = page.find_tables()
# 検出されたテーブルの数を表示する
print(f"{len(tabs.tables)}個のテーブルが{page}上に見つかりました")
# 少なくとも1つのテーブルが見つかった場合
if tabs.tables:
# 最初のテーブルの内容を表示する
pprint(tabs[0].extract())
【出力結果】
リストとして出力されます。
1個のテーブルがpage 0 of recipe.pdf上に見つかりました
[['材料', '数量'],
['アボカド', '1個'],
['トマト', '適当(アボカドにあうくらい)'],
['大豆水煮缶', '1缶'],
['豆腐', '適当'],
['しらす', '適当'],
['ごま', '適当']]
1ページのPDFに複数の表があるとき
このPDFには、1ページのPDFに2つの表があります。
for文で複数の表のデータを取得します。
from pprint import pprint
import fitz
# ドキュメントを開く
doc = fitz.open("recipe.pdf")
# ページを取得する
page = doc[0]
# ページ上にあるテーブルを検出する
tabs = page.find_tables()
# 検出されたテーブルの数を表示する
print(f"{len(tabs.tables)}個のテーブルが{page}上に見つかりました")
# 少なくとも1つのテーブルが見つかった場合
if tabs.tables:
# すべてのテーブルを抽出する
for table in tabs:
# テーブルのデータを抽出する
pprint(table.extract())
print()
【出力結果】
リストが2つ出力されました。
2個のテーブルがpage 0 of recipe.pdf上に見つかりました
[['材料', '数量'],
['アボカド', '1個'],
['トマト', '適当(アボカドにあうくらい)'],
['大豆水煮缶', '1缶'],
['豆腐', '適当'],
['しらす', '適当'],
['ごま', '適当']]
[['順番', '内容'],
['1', 'アボカドとトマトを切る'],
['2', '1と大豆の水煮缶をまぜて、ビタミン C を入れる'],
['3', 'お皿に豆腐を入れて2をのせる'],
['4', '3にしらす・ごま・亜麻仁油をかける']]
PDFが複数ページあるとき
PDFが複数ページあるときはpage = doc[0]
でページ番号を指定します。
page = doc[0]
は1ページ目です。
財務省の貿易統計から「令和5年7月分貿易統計(速報)の概要」をダウンロードしました。
1ページ目の最初の表を取得します。
1ページ目の1つ目の表のデータを取得します。
page = doc[0]
は1ページ目、tabs[0]
は1つ目の表です。
from pprint import pprint
import fitz
doc = fitz.open("gaiyo2023_07.pdf")
page = doc[0]
tabs = page.find_tables()
if tabs.tables:
pprint(tabs[0].extract())
【出力結果】
[['輸 出', '金 額', '8兆 7,250億円', '▲ 0.3%', '29ヵ月ぶりの減少'],
[None, '数量指数', '100.3', '▲ 3.2%', '10ヵ月連続の減少'],
['輸 入', '金 額', '8兆 8,037億円', '▲13.5%', '4ヵ月連続の減少'],
[None, '数量指数', '96.9', '▲ 4.3%', '9ヵ月連続の減少'],
['差 引', '金 額', '▲787億円', '▲94.5%', '2ヵ月ぶりの赤字']]
1ページ目の2つ目の表のデータを取得します。
page = doc[0]
は1ページ目、tabs[1]
は2つ目の表です。
from pprint import pprint
import fitz
doc = fitz.open("gaiyo2023_07.pdf")
page = doc[0]
tabs = page.find_tables()
if tabs.tables:
pprint(tabs[1].extract())
【出力結果】
[['輸 出', '1兆 7,912億円', '+13.5%', '22ヵ月連続の増加'],
['輸 入', '9,453億円', '▲11.2%', '2ヵ月連続の減少'],
['差 引', '8,459億円', '+65.0%', '6ヵ月連続の増加']]
PDFの表をExcelに出力する
pandasのデータフレームを作成して、Excelに出力します。
pip install pandas
pip install openpyxl
pandasのデータフレームを作成してExcelに出力します。
import fitz
import pandas as pd
doc = fitz.open("gaiyo2023_07.pdf")
page = doc[3]
tabs = page.find_tables()
if tabs.tables:
table_data = tabs[0].extract()
# 列名を取得
columns = table_data[0]
# データ行を取得
data_rows = table_data[1:]
# Pandasデータフレームを作成
df = pd.DataFrame(data_rows, columns=columns)
# データフレームをExcelファイルに保存
df.to_excel("output.xlsx", index=False) # index=Falseを設定して行番号を含めない
print("Excelファイルに保存しました: output.excel")
おまけ
ちょっと遊んでみました🎊
Python日記vol.20🐍PDFの表からデータを取得して叙勲受章者の表を作りたい