前提条件
- Windows10
- Python3
- openpyxlライブラリ
- PyMuPDFライブラリ
- Tkinterライブラリ
サンプルのPDFファイルは下記のウィキペディアトップページをPDFとしてローカルに保存したものを使用します。
https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8
openpyxlライブラリの公式ドキュメントは以下です。
https://openpyxl.readthedocs.io/en/stable/
PyMuPDFライブラリの公式ドキュメントは以下です。
https://pymupdf.readthedocs.io/en/latest/
Tkinterライブラリの公式ドキュメントは以下です。
https://docs.python.org/ja/3/library/tkinter.html
目的
PyMuPDFライブラリを利用して、ローカルにあるPDFからテキストを抽出する。抽出したテキストはPDFのページごとにExcelのシートとしてopenpyxlライブラリを利用して書き込み、Excelファイルとして保存する。
環境構築
pip install openpyxl pymupdf
サンプル
# -*- coding: utf-8 -*-
import fitz # pymupdfライブラリ
import openpyxl as px #openpyxlライブラリ
import os
from tkinter import filedialog #thinterライブラリ
typ = [('pdfファイル','*.pdf')]
dir = './'
pdf = filedialog.askopenfilename(filetypes = typ, initialdir = dir)
doc = fitz.open(pdf)
# PDFテキストを格納するリスト
item_list = []
# PDFから1ページずつテキストを取得
for page in range(len(doc)):
textblocks = doc[page].get_text('blocks')
for textblock in textblocks:
if textblock[4].isspace() == False:
tmp = textblock[4].encode('shift_jis','ignore')
text = tmp.decode('shift_jis')
item_list.append([page,text])
# PDFファイルを閉じる
doc.close()
# 新しいエクセルを作成
wb = px.Workbook()
# エクセルの1行目として使用
headers = ['No', 'ページ', '内容']
# シート作成用
i = 0
# シートごとの要素数
j = 0
# エクセルにPDFのテキストデータを出力
for y, row in enumerate(item_list):
# PDFのページごとにエクセルシートを作成
if item_list[y][0] == i:
ws = wb.create_sheet(title = str(i))
ws.column_dimensions['C'].width = 100
j = y
i = i + 1
for k, header in enumerate(headers):
ws.cell(row = 1, column = k+1, value = headers[k])
ws.cell(row = y-j+2, column = 1, value = y-j+1)
for x, cell in enumerate(row):
ws.cell(row = y-j+2, column = x+2, value = item_list[y][x])
# Sheet1の削除
wb.remove(wb.worksheets[0])
excel = os.path.splitext(pdf)[0] + '_page_excel.xlsx'
# エクセルファイルの保存
wb.save(excel)
# エクセルファイルを閉じる
wb.close()
参考資料
関連資料
きっかけ
ネットで探すと、Excelの1枚目のシートにPDFの内容を全て書き込む例は見つけたけれども、PDFのページとExcelのシートが1対1対応してる例が見つけられなかったので、このプログラムを書いてみた。
苦労したところはページごとの要素数を記録し、それを活用して2枚目以降のシートの2行目から抽出したデータを書き込むところでした。