PDFファイルの操作をPythonで自動化する方法を紹介します。
こちらの記事の続きで、引き続きPyMuPDFの基本的な使い方を紹介します。今回は主にPyMuPDFを使ったPDFファイルの編集について紹介します。
具体的には、PDFファイルの上書き保存、新規保存、ページのコピー・削除、PDFファイルの結合について紹介したいと思います。
PDF操作を自動化したいシーンは少ないよ・・・って思う方もいらっしゃるかと思いますが、PDFリーダでPDFファイルの編集って意外と面倒だと思いますので、PDFリーダを使わずにサクッと作業できる点は非常に魅力的でないかな!?と思います。
いつか役に立つかもしれませんので、ぜひPyMuPDFの使い方を学んでください。
PDFファイルを編集して上書き保存/名前をつけて保存する
上書き保存と名前をつけて保存
名前をつけて保存は以下のようにsave()の引数にファイル名を入れるだけです。
Documentオブジェクト.save(新規ファイル名)
上書き保存は、DocumentオブジェクトのsaveIncr()を使います。
Documentオブジェクト.saveIncr()
ページを削除する
特定のページを削除したい場合は、Documentオブジェクトのdelete_page()を使います。
Documentオブジェクト.delete_page(ページ番号)
邪魔なページを削除して見やすくしたいって場合は便利かもしれないです。なお、ページ番号は0始まりなので注意してください。
import fitz
filename = "test.pdf"
pdf = fitz.open(filename)
#特定のページを消す(2ページ目を消す)
pdf.delete_page(1)
複数ページを一気に削除したい場合もあります。ループを使ってdelete_page()をしてもいいですが、複数ページを削除したい場合は、Documentオジェクトのdelete_pages()を使います。
Documentオブジェクト.delete_pages(from=開始ページ番号、to=終了ページ番号) または Documentオブジェクト.delete_pages(開始ページ番号、終了ページ番号)
その他、delete_pagesの引数には、rangeオブジェクトやリスト、タプル渡すこともできます。また、以下のサンプルコードに書いたように、色々な方法がありますので、使いやすい方法を使ってください。
import fitz
filename = "test.pdf"
pdf = fitz.open(filename)
#delete_pages()を使って複数のページを消す
#2〜9ページ目を削除
pdf.delete_pages(range(2,10))
pdf.delete_pages(2, 9)
pdf.delete_pages(from_page = 2, to_page = 9)
#delを使って複数ページを削除する
del doc[2:10]
del doc[range(2, 10)]
del doc[(2, 3, 4, ... , 9)]
ページをコピーする
ページのコピーを作りたい場合は、Documentオブジェクトのfullcopy_page()を使います。
Documentオブジェクト.fullcopy_page(コピーしたいページ、to=コピーする場所)
または、copy_page()を使います。
Documentオブジェクト.copy_page(コピーしたいページ、to=コピーする場所)
fullcopy_pageとcopy_pageの挙動は一見同じように見えますが、コピーもとのページに変更した場合に違いが現れます。
fullcopy_page()は新しいページオブジェクトを作るのに対して、copy_page()はコピー元への参照を作るだけです。つまり、copy_page()を使った場合、コピー元のページに変更を加えると、コピーしたページにも同じ変更が反映されます。とりあえず、fullcopy_page()を使ったほうが無難そうです。
import fitz
filename = "test.pdf"
pdf = fitz.open(filename)
#fullcopy_pageを使って、6ページ目のコピーを1ページに置く
pdf.fullcopy_page(
5,
to = 0
)
#fullcopy_pageを使って、6ページ目のコピーを1ページに置く
pdf.fullcopy_page(
5,
to = 0
)
#copy_pageを使って、10ページ目のコピーを2ページに置く
pdf.copy_page(
9,
to = 1
)
#copy_pageの挙動を確認。10ページにアノテーションを加えると2ページ目にも変更が反映される
page = pdf[9]
page.add_polyline_annot([Point(50,15), Point(100, 50), Point(150, 15)])
#上書き保存する
pdf.saveIncr()
2つのPDFファイルを結合する
2つのPDFファイルを結合するには、Documentオブジェクトのinsert_pdf()を使います。書式は以下のとおりです。
#pdfファイル1のDocumentオブジェクト = Documentオブジェクト1
#pdfファイル1のDocumentオブジェクト = Documentオブジェクト2
Documentオブジェクト1.insert_pdf(
Documentオブジェクト2,
from_page = コピーしたいページの開始ページ番号,
to_page = コピーしたいページの終了ページ番号,
start_at = コピーを挿入する場所
)
完璧な個人的な意見ですが、複数のPDFを開くのが面倒なので、結合して1つのファイルにしたい・・・というシーンが結構多いのではないでしょうか?
import fitz
filename1 = "test1.pdf"
filename2 = "test2.pdf"
pdf1 = fitz.open(filename1)
pdf2 = fitz.open(filename2)
#filename2の1ページ〜10ページをfilename1の5ページ目に挿入する
pdf1.insert_pdf(
pdf2,
from_page = 0,
to_page = 10,
start_at = 4,)
pdf1.save("concated.pdf")
pdf1.close()
pdf2.close()