Help us understand the problem. What is going on with this article?

【自動化】PDF内の表をPythonで抜き出す

PDFは扱いにくい

PDFファイルをPythonで扱うのは大変です。

表がPDFの中に埋め込まれているケースも割とあります。

例えば

平成30年 全衛連ストレスチェックサービス実施結果報告書の中にはたくさんの表データが埋め込まれています。

例えばファイルの40ページの【表14 業種別高ストレス者の割合】を抜き出したいと思ったとします。

この表を選択して、Excelにコピペしてみましょう。
pdf_table_copy.png

コピーして、Excelに貼り付けます。

pdf_copy2excel.png

おや?うまくいかないですね。
1つのセルの中に、全部のデータが羅列されてしまっています。

実はPythonを使ってこのPDF中の表を比較的簡単にcsvやExcelに変換することができます。

PythonでPDFの表をcsvに

PythonでPDF内の表(テーブル)をcsvやexcelに変換する手順は2ステップです。

ステップ1. PDFから表をpandasのDataFrameとして抜き出す
ステップ2. DataFrameをcsvやexcelとして書き込む

順に見ていきましょう。

ステップ1. PDFから表をpandasのDataFrameとして抜き出す

pdfの表をDataFrameとして抜き出すために、tabulaというモジュールを使います。

tabulaはインストールされていない方も多いと思いますので
pip install tabula-py
でインストールします。

さらにこのtabulaはJavaで動きますので、Javaのインストールも必要です。

tabulaの準備ができたところで、pandasとtabulaををimportしておきます。

python
import pandas as pd
import tabula

PDFから表を抜き出すには、
tabula.read_pdf("xxx.pdf", lattice=True, pages='xxxx')
という関数を使います。

  • "xxx.pdf"には、読み込みたいPDFファイルのパスを書きます。
  • lattice=Trueはテーブルの罫線でセルを判定するためのオプションです。 抜き出したい表が罫線で区切られているならlattice=Trueを指定しましょう。
  • pagesは読み込みたいページを指定します。

    • 40ページ目だけを読み込むならpages='40'のように指定します。
    • 40~45ページを読み込むならpages='40-45'のように指定します。
    • すべてのページを読み込むならpages='all'でOKです。
  • 関数の戻りとしてpandas.DataFrameのリストが返ります。複数の表があった場合には、このリストをfor文で順に取り出せばよいです。

では、先ほどの『平成30年 全衛連ストレスチェックサービス実施結果報告書』の40ページの表を読み込んでみましょう。

python
# lattice=Trueでテーブルの軸線でセルを判定
dfs = tabula.read_pdf("平成30年 全衛連ストレスチェックサービス実施結果報告書.pdf", lattice=True, pages = '40')

for df in dfs:
    display(df)

tabula_df.png

列名がセル内で改行されていたために\rが入ってしまっていて変ですが、表の中身はうまく取り出せていますね。

一応、列名もきちんと直しておきましょう。
df.rename(columns={'元の列名': '変更後の列名'})で列名を変更できます。
複数の列名を変更するときは'元の列名': '変更後の列名'をコンマで区切ってつなげていけばOKです。

python
df = df.rename(columns={'高ストレ\rス者数': '高ストレス者数', '高ストレス\r者の割合': '高ストレス者の割合'})

ステップ2. DataFrameをcsvやexcelとして書き込む

pandasには元々DataFrameをcsvやExcelとして書き込む機能がついています。

csvとして保存:df.to_csv("ファイル名.csv", index=None)
Excelとして保存:df.to_excel("ファイル名.xlsx", index=None)

index=NoneはDataFrameのindexを書き込まないようにするためのオプション

まとめ

最後に今回のコードをまとめて記載しておきます。

pyhon
import pandas as pd
import tabula

# lattice=Trueでテーブルの軸線でセルを判定
dfs = tabula.read_pdf("平成30年 全衛連ストレスチェックサービス実施結果報告書.pdf", lattice=True, pages = '40')

# PDFの表をちゃんと取得できているか確認
for df in dfs:
    display(df)

# csv/Excelとして保存(今回はdfs[0]のみ)
df = dfs[0].rename(columns={'高ストレ\rス者数': '高ストレス者数', '高ストレス\r者の割合': '高ストレス者の割合'})
df.to_csv("PDFの表.csv", index=None) # csv
df.to_excel("PDFの表.xlsx", index=None) # Excel

画像扱いのPDFファイルから表を抜き出すには

紙の文書や書籍をスキャンして電子化したPDFの場合、テキストがOCR化されておらず、PDFファイル内の表が画像扱いのままのものもあると思います。

その場合は、下記の記事で紹介した方法をお試しください。

画像ファイルの表をOneDrive&Pythonで抜き出す

参考

私の書いた他の自動化シリーズはこちらです。ご興味があればどうぞ!

【自動化】PythonでWordの文書を読み取る
https://qiita.com/konitech913/items/c30236bdf47775535e2f

【自動化】Pythonコードをexeファイル化する
https://qiita.com/konitech913/items/6259f13e057bc25ebc23

【自動化】PythonでOutlookメールを送信する
https://qiita.com/konitech913/items/51867dbe24a2a4272bb6

【自動化】PythonでOutlookのメールを読み込む
https://qiita.com/konitech913/items/8a285522b0c118d5f905

【自動化】Pythonでメール(msgファイル)を読み込む
https://qiita.com/konitech913/items/fa0cf66aad27d16258c0

【自動化】Pythonでクリップボードを操作してExcelに表を貼り付ける
https://qiita.com/konitech913/items/83975332e395a387eace

konitech913
自称【自動化番長】。「これ、人間がやる作業じゃなくない…?」という単調&イライラする作業から人類を解放すべくあらゆる自動化を研究中です。
http://ai-kotohajime.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした