見出し画像

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()

で、実行すると、

pypdfで作成した目次

ちゃんと、出力されました👍

#python #pypdf #pdf #自炊 #スキャン

仕事で香港赴任しています。 こちらの珍しい食材のレポートと、日本人の日本人の舌による自分のための料理にチャレンジ!