pypdfを使った目次(しおり)作成
Macのプレビューの使い勝手が良いのですが、唯一の難点が目次(Acrobatでいうところのしおり)が作成できないこと。
目次を作成するソフトウェアは色々ありますが、自炊スキャンファイル用に他の編集機能(縁取り、回転、結合)も含めて、Pythonで簡単なアプリを作ってみようと思い立ちました。
使用したpypdfライブラリの目次作成のサンプルが、英語サイトでも見当たらなかったのですが、試行錯誤しようやくうまく動いたので、メモとして記します。
Pythonで目次を作るライブラリとして、ざっと調べると下記のものがありました。
PyMuPDF
ReportLab (+ pdfrw)
pypdf (PyPDF4, PyPDF2の後釜というか、一番最初のライブラリ名に戻っている)
pdftk
PyMuPDFがとても高性能かつ実行速度も速そうだったのですが、ライセンスやら使い勝手を考え、pypdfを選択しました。サンプルコードはこんな感じ。
import sys
from pypdf import PdfReader, PdfWriter
# 使用するpdfファイル。pythonファイルと同じフォルダにあるとする。
input_file_name = 'test.pdf'
# 目次のリスト。各要素は[タイトル, ページ番号, 親のタイトル]とする。
outline_list = [['Chapter 1', 1, None],
['Section 1.1', 2, 'Chapter 1'],
['Section 1.2', 3, 'Chapter 1'],
['Chapter 2', 4, None],
['Section 2.1', 5, 'Chapter 2']
]
# PDFファイルを読み込む
pdf_reader = PdfReader(input_file_path)
pdf_writer = PdfWriter(clone_from=input_file_path)
# PDFファイルを開き、各ページを追加
for page_number in range(pdf_reader.get_num_pages()):
page = pdf_reader.get_page(page_number)
pdf_writer.add_page(page)
# アウトライン項目を作成し、それらを適切な親に関連付ける
outline_dict = {}
for outline in outline_list:
title, page_number, parent_title = outline
parent = outline_dict.get(parent_title) # 親のアウトライン項目を取得
outline_item = pdf_writer.add_outline_item(title=title, page_number=page_number-1, parent=parent)
outline_dict[title] = outline_item # 作成したアウトライン項目を保存
# 出力PDFファイルに書き出し
pdf_writer.write(input_file_name.rsplit('.',1)[0] + '_outlined.pdf')
pdf_writer.close()
で、実行すると、
仕事で香港赴任しています。 こちらの珍しい食材のレポートと、日本人の日本人の舌による自分のための料理にチャレンジ!