まえがき
Python初心者です。
オライリージャパン「退屈なことはPythonにやらせよう」
を参考にして組んだプログラムです。
###実現したいこと
両面印刷された、多数の枚数で構成された文書があるとします。
しかし、いちいちスキャンして裏返してスキャンして、次の紙をセットしてスキャンして裏返してスキャンして次の紙...など、面倒でやってられません。
そこで、この文書を、フィーダーを使って表側をすべて連続スキャンし、表文書の表側(1,3,5,...ページ)がスキャンされたPDFを出力します。
次に、同様に裏側(2,4,6,...ページ)がスキャンされたPDFを出力します。
最後の仕上げとして、Pythonを用いて2つのPDFを、ページが1,2,3,...ページと正しく繋がった1つのPDFにマージする、という手法を思いついたと言う次第です。
これなら、両面同時コピーの機能はないがフィーダーがあって、片面を比較的高速に連続コピーやスキャンできるような家庭用の複合機で、大量の紙で構成される文書を素早くスキャンし、素早くPDFにマージできます。
と、いうわけで早速プログラムで組んだのですが、問題が発生しました。
発生している問題・エラーメッセージ
ソースコードを書き終わり、デバッグを進めていくうちに、私の力だけでは解読不可能なエラーが発生しました。
内容は、次の通りです。
Traceback (most recent call last): File "pdf_even_odd_merger.py", line 45, in <module> odd_pdf = PyPDF2.PdfFileReader(odd_object) File "C:\Users\whpc0\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\PyPDF2\pdf.py", line 1084, in __init__ self.read(stream) File "C:\Users\whpc0\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\PyPDF2\pdf.py", line 1689, in read stream.seek(-1, 2) OSError: [Errno 22] Invalid argument
どうも、Invalid argumentのエラーは、open関数やraw文字列に関連するエラーで、ファイルが見つからないなどのエラーであることは調べて分かりました。
とりあえず何か分かるかなと思って、エラーメッセージに書いてあるPyPDFの中にあるpdf.pyも読んでみましたが、何が何なのやらさっぱり...。
該当のソースコード
ちなみにですが、"even"はeven number:偶数、"odd"はodd number:奇数として書いてあります。
Python
1#! Python3 2# -*- coding: utf-8 -*- 3#pdf_even_odd_merger.py 4 5import PyPDF2, os, sys 6 7pdflist = [] 8evencounter = 0 9oddcounter = 0 10for filename in os.listdir(os.getcwd()): 11 #このファイルが置かれているディレクトリ内のファイルやフォルダを走査 12 13 if filename.endswith(r".pdf"): 14 #ファイルネーム末尾が".pdf"で終わるファイルは、ファイルネームをpdflistに追加する。 15 pdflist.append(filename) 16 17 if filename.lower().startswith(r"even_"): 18 #ファイル名が"even.pdf"で終わる場合(偶数ページのみがスキャンされているファイルの場合)、evencounterを足していく。 19 #大文字の拡張子の可能性も考慮し、lowerメソッドを組んでいる。 20 evencounter += 1 21 22 if filename.lower().startswith(r"odd_"): 23 #ファイル名が"odd.pdf"で終わる場合(奇数ページのみがスキャンされているファイルの場合)、oddcounterを足していく。 24 #大文字の拡張子の可能性も考慮し、lowerメソッドを組んでいる。 25 oddcounter += 1 26 27if evencounter != 1 or oddcounter != 1: 28 print("エラーが発生しました。") 29 print(r"このファイルに置かれているPDFファイルは、'even_~~.pdf'あるいは'odd_~~.pdf'の2つのファイルのみでなくてはなりません。") 30 print("プログラムを終了します。") 31 sys.exit() 32 33pdflist.reverse() 34#pdflistに格納されているファイルが["even_~~.pdf","odd_~~.pdf"]のみであったとして、リスト内をeven,oddからodd,evenの順番にするためにソートする。 35#key=str.lowerで、大文字小文字を区別しないようにしている。 36 37pdfwriter = PyPDF2.PdfFileWriter() 38#結合したPDFファイルを保持するために、オブジェクトを作成しておく。 39 40#奇数ページファイルの読み込みオブジェクト 41odd_file_name = os.getcwd() + "\" + pdflist[0] 42print(odd_file_name) 43odd_object = open(odd_file_name,"rb") #pdflist[0]には、oddのファイルがある。 44odd_pdf = PyPDF2.PdfFileReader(odd_object) 45 46#偶数ページファイルの読み込みオブジェクト 47even_file_name = os.getcwd() + "\" + pdflist[1] 48print(even_file_name) 49even_object = open(even_file_name,"rb") #pdflist[1]には、evenのファイルがある。 50even_pdf = PyPDF2.PdfFileReader(even_object) 51 52#evenとoddが同じ枚数の紙からスキャンしたオブジェクトなら、ページ数が揃うはず。その検証を行う。 53#evenのページ数を取得する。 54odd_num_page = odd_pdf.numPages 55even_num_page = even_pdf.numPages 56superchecker = 0 57#57行目のような状況に遭遇した場合の排他処理そするための識別コード:デフォルトは1で、if文に引っかかった場合に1とする。 58if odd_num_page != even_num_page: 59 print("異なる文書からスキャンた奇数ページファイル、偶数ページファイルを誤って組み合わせないようにするための、安全用プログラムが作動しました。") 60 print("同じ文書からスキャンして得られた偶数ページファイルと奇数ページファイルは、同じページ数になるはずです。") 61 print("しかし、同じ文書からスキャンした文書で、最後のページが真っ白だった場合にそのページをスキャンしなかった場合も考えられます。") 62 print("あなたは、上記の状況に該当しますか。する場合は、1を入力してください。") 63 checknum = int(input()) 64 if chenknum == 1: 65 superchecker = 1 66 #57行目の状況に該当するので、1にしておく。 67 else: 68 print("プログラムを終了します。") 69 sys.exit() 70 71#57行目にある状況を想定して、2つのファイルのページ数で、大きい方を格納する。 72if even_num_page > odd_num_page or even_num_page == odd_num_page: 73 maxpagenum = even_num_page 74else: 75 maxpagenum = odd_num_page 76 77#PDFを、いよいよマージする。 78if superchecker == 0: 79 #まずは、57行目のような状態でない場合(supercheckerが0の場合) 80 for pagenum in range(0,maxpagenum): 81 oddpageobject = odd_pdf.getPage(pagenum) 82 pdfwriter = addPage(oddpageobject) 83 evenpageobject = even_pdf.getPage(pagenum) 84 pdfwriter = addPage(evenpageobject) 85 86 #マージングが終了したので、最後に書き出す 87 pdfoutput = open(r"merged.pdf","wb") #"meiged.pdf"という名前のPDFを作成する 88 pdfwriter.write(pdfoutput) #書き出す 89 pdfoutput.close() #書き込みの終了 90 print("すべての処理が正常に完了しました。") 91 print(r'merged.pdfという名前のファイルが保存されているはずです。') 92 print("プログラムを終了します。") 93 94else: 95 #次は、57行目のような状態である場合(superchecker1の場合) 96 for pagenum in range(0,maxpagenum-1): 97 oddpageobject = odd_pdf.getPage(pagenum) 98 pdfwriter = addPage(oddpageobject) 99 evenpageobject = even_pdf.getPage(pagenum) 100 pdfwriter = addPage(evenpageobject) 101 if pagenum == maxpagenum-2: 102 lastpage = maxpagenum-1 103 lastpageobject = even_pdf.getPage(lastpage) 104 pdfwriter = addPage(lastpageobject) 105 106 #マージングが終了したので、最後に書き出す 107 pdfoutput = open(r"merged.pdf","wb") #"meiged.pdf"という名前のPDFを作成する 108 pdfwriter.write(pdfoutput) #書き出す 109 pdfoutput.close() #書き込みの終了 110 print("すべての処理が正常に完了しました。") 111 print(r"merged.pdfという名前のファイルが保存されているはずです。") 112 print("プログラムを終了します。") 113
試したこと
1.エスケープ文字関連で怪しいところは、すべてraw文字列記述にした
2.相対パスではなく、os.getcwd()を用いて絶対パスを入手する方法へ変更した。
補足情報(FW/ツールのバージョンなど)
Python 3.8
importしたもの:
os
sys
PyPDF2 (バージョンは1.26.0)
以上です。皆様のご回答、お待ちしております。
回答1件
あなたの回答
tips
プレビュー