はじめに
ある日、巨大なPDFファイルを作成したところ、先方からクラウドストレージが使えないのでメールで送ってくれと言われました。7zipで圧縮して分割して送ったらセキュリティポリシー違反で届きませんでした。
そんな時に30分くらいで作ったコードです。どんぴしゃのものが見つからなかったのでやり方をメモしておきます。いろいろ雑なのはご愛敬。
コード
実行環境:
- ubuntu 20.04 on WSL1
- Python 3.8.2
- PyPDF2 1.26.0
- pathlib 1.0.1
split_pdf.py}
import PyPDF2
from pathlib import Path
import os
def split_file(pfin):
# 目標サイズに応じて変更
MAX_SIZE = 9000000
if os.path.getsize(pfin) > MAX_SIZE:
# PDF読み込み
r = PyPDF2.PdfFileReader(str(pfin), strict=False)
lastpage = r.numPages
# 1ページに達したら終了
if lastpage == 1: return
# 真ん中で分割するためのページ
split = lastpage // 2
# ファイル名生成 suffixはお好みで
f1 = Path(f'{pfin.stem}_1.pdf')
f2 = Path(f'{pfin.stem}_2.pdf')
w = PyPDF2.PdfFileWriter()
# 1ページづつwriterに追加
for i in range(lastpage):
w.addPage(r.getPage(i))
# splitに達したらファイル名f1として保存
if i == split:
with open(f1, 'wb') as f:
w.write(f)
del w
w = PyPDF2.PdfFileWriter()
# 最後まで追加したらファイル名f2として保存
with open(f2, 'wb') as f:
w.write(f)
del w
# f1が目標ファイルサイズを超えていたら再帰的に渡す
if os.path.getsize(f1) > MAX_SIZE:
split_file(f1)
# f2が目標ファイルサイズを超えていたら再帰的に渡す
if os.path.getsize(f2) > MAX_SIZE:
split_file(f2)
# 処理が終わったら元ファイルを削除(残したかったらコメントアウト)
pfin.unlink()
if __name__ == "__main__":
# 例としてhoge.pdfを分割したいとする
split_file(Path('hoge.pdf'))
補足
- このプログラムを実行すると
input:
hoge.pdf
output:
hoge_1_1.pdf
hoge_1_2.pdf
hoge_2.pdf
のように出力されます。最後にお好みでリネームしてください。
- 巨大すぎるファイルを細かく分割するとファイル名が長くなります。ほどほどの深さになるように適切にパラメータを設定してください
- あくまで
MAX_SIZE
を超えない程度に分割したいという思想で作ったプログラムです。MAX_SIZE
ギリギリに作りたいときは別のやり方をお勧めします - このやり方は1ページのサイズが
MAX_SIZE
を超えた場合はMAX_SIZE
以下にできません
最後に
最初に受け渡し方法を相談しておきましょう