プログラムは「こんな風に役に立つ」
pythonでpdfを分割して送信するとき5メガ未満ごと最後のファイル名を表示する
中国の子会社から法人税申告書が届きました。PDFでファイルサイズが19.1MB。お客様のメールサーバーは受信サイズが6MBなので、このファイルサイズでは送信しても届きません。
シェルコマンド「pdfseparete」で分割してみる。全46ページだったらしく、1ページずつ46個のファイルが出来上がりました。
このあと、Python製でコマンドラインから使えるファイラー「ranger」で分割されたファイルがあるディレクトリに移動して、1つ目のファイルに移動後、「V」を押す。これでファイル選択状態が始まる。「j」を押すごとに選択されるファイルが増えていく。右手人差し指で「j」を押しながら、横目で右下の角を見る。ファイルを選択してる「ranger」はこの部分にファイルサイズ/ファイル個数が表示されます。「4.68MB/8 Mrk」、1から8個目のファイルで4.68MBならメールが送信できます。「uv」と押すと選択が解除されます。
次は、9個目のファイルから同じようにキー操作をしてファイルを選択して行く。これを46個のファイルを5MB未満に分けてまとめる。4つに分けることができました。
1つのまとまりのファイルをメールに添付して、4個のメールを送信する。
エラーはなく、お客様にメールが届けられました。
この法人税申告書以外には、監査報告書もPDFで受け取っているので、こちらも分割して、5MB未満になるようにファイルを分けて、メールを送信する。数社あるので、数社分これを繰り返す。
この繰り返しは、わりと時間がかかります。
こんなときに役に立ってくれるのがプログラムです。
わたしは、Python3を使って繰り返し作業をプログラムにします。
コマンドラインで使えるようにします。多少長くはなりますが、コマンド履歴でいつでも呼び出せるようにコメント機能を使って名前をつけます。
これをわたしは「スケルトンライナー」と呼んでいます。
シェルコマンドでは、1行プログラムを「ワンライナー」と呼んでいますが、コマンドの中身が透けて見えていて、変数に値が変わったり、ファイルの名前など多少修正するだけで、変幻自在に使えますので、「スケルトンライナー」と呼んでます。
1度スケルトンライナーを書いて実行しておけば、次回からは、5MB未満になるようにファイルの個数を数える操作は必要ありません。コマンド履歴から呼び出して、ちょっと修正して、エンターを押すとすぐにメールを送ることができます。ほんの一瞬の作業になります。
プログラム、プログラミングと言われると、ゲームだったり、ダッシュボードやアプリという出来合いの難しそうなものを作ることを思い浮かべると思います。でも、こんな風に自分の作業時間を短縮する使い方もプログラミングなんです。すこしは身近に感じていただけるとうれしいです。そして、どんどん小さなスケルトンライナーを作りながら、自分のために役立てていただくと、使っているうちに自然とプログラムの考え方も身につくので一石二鳥です。
今回のスケルトンライナー
$ pdfseparate '2024年度所得汇缴报告.pdf' '2024年度所得汇缴报告''_%d.pdf' #pdf分割
$ python3 -c "$imt;exec(\"tsv_=io.StringIO('\\\\n'.join([''.join(x)+'\\t'+str(pathlib.Path(''.join(x)).stat().st_size) for x in sorted([re.split('(_|\\.pdf)',x.name)[:-1] for x in pathlib.Path().cwd().glob('**/2024*.pdf') if not re.search('报告.pdf',x.name)],key=lambda x:x[2].zfill(2))]));df=pl.read_csv(tsv_,separator='\\t',has_header=False);tsv_.close();i=0\nwhile i<len(df):i+=len(df[i:,:].with_columns(col_3=pl.cum_sum('column_2'),col_4=pl.cum_sum('column_2')/(1024*1024)).filter(pl.col('col_4')<=5));pr(''.join([x for x in df[:i,:].select(pl.col('column_1')).iter_rows()][-1]),i)\")" #pdfを分割して送信するとき5メガ未満ごと最後のファイル名を表示する