0
0

PythonでPDFファイルの読み書きマージやパスワード解除したりする。

Last updated at Posted at 2024-09-21

はじめに

PythonのPDF処理ライブラリpypdfについてまとめる。

目次

pypdfライブラリ取得

pypdfのライブラリは下記で取得。パスワードがかかっているファイルを復号化する場合はpypdf[crypto]も必要。

$ pip install pypdf
$ pip install pypdf[crypto]

戻る

PDF読み込みとテキスト出力

PDFファイルはpypdf.PdfReader()で読み出す。テキスト出力はページを指定して.extract_text()でできる。スライスを使えないので複数ページ出力したい場合は、for等で出力する必要がある。

コマンド 内容
pdf = pypdf.PdfReader('ファイル名') ファイルを読み出しpdfへ出力
len(pdf.pages) ページ数
pdf.pages[0].extract_text() 1ページ目をテキスト出力
import pypdf

# pdf読み出し
in_file = input('PDFファイル名:')
pdf = pypdf.PdfReader(in_file)

# ページ数読み出し
print(f'# {len(pdf.pages)=}')

# 1ページ目読み出し
print(pdf.pages[0].extract_text())

# 全ぺージ読み出し
for i in pdf.pages:
	print(i.extract_text())

戻る

PDF図の出力

PDFの図の出力は.imagesで取り出せる。

下記は、./figフォルダに図を保存する例。図名は、ページごとに被る可能性があるのでcntをファイル名に付けて保存している。

import pypdf
import os

# pdf読み出し
in_file = input('PDFファイル名:')
pdf = pypdf.PdfReader(in_file)


# 図の格納フォルダ作成
if not os.path.isdir('fig'):
	os.mkdir('fig')
cnt=0
for page in pdf.pages:
	#各ページ内の図を取り出し、ファイルとして保存する。
	for image in page.images:
		print(f'{cnt:04d}_{image.name},{image}')
		
		with open(f'fig/{cnt:04d}_{image.name}', 'wb') as f:
			f.write(image.data)
		cnt=cnt+1

# print(f'{cnt:04d}_{image.name},{image}')
# 0000_Im0.jpg,ImageFile(name=Im0.jpg, data: 28.5 kB)

戻る

PDF書き込み

コマンド 内容
pdf = pypdf.PdfWriter() PDF生成
pdf.clone_reader_document_root() 特定のPDFを先頭からコピーしてクローンを作る
pdf.add_page() pdfを1ページ追加
pdf.write('出力ファイル名.pdf') ファイルとして書き出し
ファイルをクローン
import pypdf

# PDF生成
new_pdf = pypdf.PdfWriter()

# あるPDF読み出し
in_file = input('PDFファイル名:')
pdf = pypdf.PdfReader(in_file)

# クローン生成
new_pdf.clone_reader_document_root(pdf)

#ファイル出力
new_pdf.write('出力ファイル名.pdf')
new_pdf.close()
特定のページをコピー
import pypdf

# PDF生成
new_pdf = pypdf.PdfWriter()

# あるPDF読み出し
in_file = input('PDFファイル名:')
pdf = pypdf.PdfReader(in_file)

#6ページ目(0オリジン)~最後のページまで抜き出し
for i in pdf.pages[5:]:
	pdf_div.add_page(i)
new_pdf.write('出力ファイル名.pdf')
new_pdf.close()

戻る

PDFマージ

.append().merge()を使えば、PDFファイル全てをマージしたり、特定のページをマージしたりすることができる。

コマンド 内容
mpdf = pypdf.PdfWriter() マージ用PDF作成(書き込みと同じ)
mpdf.append('マージファイル名') ファイルをすべてマージ
mpdf.merge(page, file ,pages=pypdf.PageRange('start:stop:step')) fileの特定のpageから start/stop/stepで指定したページを挿入する
PDFマージ
import pypdf

mpdf = pypdf.PdfWriter()
mpdf.append('A.pdf')	#A.pdf全て
mpdf.append('B.pdf')	#B.pdf全て
mpdf.write('AB.pdf')
mpdf.close()
PDFをページ指定してマージ
import pypdf

mpdf = pypdf.PdfWriter()
mpdf.append('A.pdf')	#A.pdf全て
mpdf.merge(10,'B.pdf',pages=pypdf.PageRange('0:5'))	#B.pdfの1~5ページを 10ページ目に挿入する
mpdf.write('AB.pdf')
mpdf.close()

戻る

PDF分割

.append()を使えば、PDFを分割することもできる。

コマンド 内容
divpdf = pypdf.PdfWriter() 分割用PDF作成(書き込みと同じ)
divpdf.append(file,pages=pypdf.PageRange('start:stop:step')) fileをstart/stop/stepで指定したページ抜き出す
PDF分割
import pypdf

div1_pdf = pypdf.PdfWriter()
div2_pdf = pypdf.PdfWriter()
div1_pdf.append('A.pdf',pages=pypdf.PageRange(':5'))	#5ページ目まで
div2_pdf.append('A.pdf',pages=pypdf.PageRange('5:'))	#5ページ以降
div1_pdf.write('A1.pdf')
div2_pdf.write('A2.pdf')

戻る

PDFパスワード解除

pdf.is_encryptedでpdfの暗号化状態を確認できる。Trueであれば、パスワードがかかっている。パスワード解除はpdf.decrypt('パスワード')でできる。このライブラリでパスワード解読できるわけではないので、パスワードはわかっている必要はある。
下記例は、パスワード解除して、解除したファイルを新たに作成する関数。def pdf_unlock(in_file, password, out_file):

import pypdf

# PDFファイル読み込み
in_file = input('PDFファイル名:')
pdf = pypdf.PdfReader(in_file)
# 暗号状態確認
print(f'# {pdf.is_encrypted=}')

# pdf.is_encrypted=True

#-------------------------------------------
# PDF解除処理
#-------------------------------------------
def pdf_unlock(in_file, password, out_file):
	#PDF読み込み
	pdf = pypdf.PdfReader(in_file)

	#PDFパスワード解除
	pdf.decrypt(password)

	#新PDFファイルを準備
	pdf_unlock = pypdf.PdfWriter()

	#新PDFにコピー
	pdf_unlock.clone_reader_document_root(pdf)

	#パスワード解除された状態でPDF保存
	pdf_unlock.write(out_file)
    pdf_unlock.close()


# PDFファイル読み込み
password = input('PDFのパスワード:')
out_file = 'unlock'+in_file

# PDF解除処理
pdf_unlock(in_file, password, out_file)

戻る

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0