回答編集履歴

4

表現を修正

2020/09/12 16:41

投稿

Daregada
Daregada

スコア11990

test CHANGED
@@ -92,7 +92,7 @@
92
92
 
93
93
  追加分:
94
94
 
95
- - PDFファイルの内容により、`PyPDF2.PdfFileReader()`で読み込むさいに「OSError: [Errno 22] Invalid argument」になるものがある。公式のGitHubの以下のページで議論されている(未解決)。
95
+ - PDFファイルの内容により、`PyPDF2.PdfFileReader()`で読み込むさいに「OSError: [Errno 22] Invalid argument」になるものがある。PyPDF2公式のGitHubの以下のページで議論されている(未解決)。
96
96
 
97
97
 
98
98
 

3

PDFファイル自体に問題があるという補足を追加

2020/09/12 16:41

投稿

Daregada
Daregada

スコア11990

test CHANGED
@@ -89,3 +89,61 @@
89
89
  print("すべての処理が正常に完了しました。")
90
90
 
91
91
  ```
92
+
93
+ 追加分:
94
+
95
+ - PDFファイルの内容により、`PyPDF2.PdfFileReader()`で読み込むさいに「OSError: [Errno 22] Invalid argument」になるものがある。公式のGitHubの以下のページで議論されている(未解決)。
96
+
97
+
98
+
99
+ [A certain PDF File triggers OSError: [Errno 22] Invalid argument · Issue #530 · mstamy2/PyPDF2](https://github.com/mstamy2/PyPDF2/issues/530)
100
+
101
+
102
+
103
+ 先頭の発言の「This file」のリンクからダウンロードした`NTB - LOI.pdf`(印刷された書類をスキャンしたっぽい内容)を`PyPDF2.PdfFileReader()`で読み込むと、確かに「OSError(以下略)」が発生する。質問者がスキャンで作成したPDFファイルも、これと同じ問題が起きている可能性が高い。なお、こちらで検証に使っていたPDFファイルは、印刷した文書をスキャンしたものではなく、Wordで作成した文書を直接PC上でPDF化したものだった。
104
+
105
+
106
+
107
+ とりあえずの対策として、上記のスレッドでは、GhostScript(gs)を使ってPDFファイルを書き換えるためのコマンドラインが提案されている。
108
+
109
+
110
+
111
+ > gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/printer -dNOPAUSE -dQUIET -dBATCH -sOutputFile="出力ファイル名" "入力ファイル名"
112
+
113
+
114
+
115
+ あいにくWindowsにGhostScriptを入れていなかったので、仮想Linuxマシンで上記のコマンドラインで変換を行なったところ、
116
+
117
+ ```terminal
118
+
119
+ $ gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/printer -dNOPAUSE -dQUIET -dBATCH -sOutputFile="output.pdf" "input.pdf"
120
+
121
+ **** Error: An error occurred while reading an XREF table.
122
+
123
+ **** The file has been damaged. This may have been caused
124
+
125
+ **** by a problem while converting or transfering the file.
126
+
127
+ **** Ghostscript will attempt to recover the data.
128
+
129
+ **** However, the output may be incorrect.
130
+
131
+ ```
132
+
133
+ とエラーを吐いたものの、変換後のPDFファイルは問題なく`PyPDF2.PdfFileReader()`で読み込むことができた。なお、PDFビューアーアプリでは、どちらのPDFファイルも表示できている。
134
+
135
+
136
+
137
+ ということで、
138
+
139
+
140
+
141
+ 0. 現在使っているPDFファイルではなく、Wordなどの文書を直接PDF化したものを用意して、コードの動作確認を行なう。
142
+
143
+ 0. 最終目的であるスキャンされたPDFファイルのマージを行なうために、GhostScriptのダウンロードとインストールを行なう。
144
+
145
+ 0. gsコマンドが利用可能になったら、上記のコマンドラインで変換を試み、生成されたPDFファイルを使って(動作確認済みの)コードでマージを行なう。
146
+
147
+
148
+
149
+ という手順が必要でしょう。

2

余分なPDFファイルがあっても動作するよう修正

2020/09/12 16:40

投稿

Daregada
Daregada

スコア11990

test CHANGED
@@ -8,39 +8,41 @@
8
8
 
9
9
 
10
10
 
11
- 残った問題点は、
11
+ ~~残った問題点は、~~
12
12
 
13
- - カレントディレクトリに存在するPDFファイルが2個以外のときの処理。たとえば、1個だけある場合や、3個以上ある場合にどうするか。現在は`ps.listdir()`の末尾2個だけが処理される。
13
+ - ~~カレントディレクトリに存在するPDFファイルが2個以外のときの処理。たとえば、1個だけある場合や、3個以上ある場合にどうするか。現在は`os.listdir()`の末尾2個だけが処理される。~~
14
+
15
+
16
+
17
+ globを使って「even_*.pdf」と「odd_*.pdf」をそれぞれ別個にリストに読み込み、それぞれのリストの要素が1のときだけ続く処理を行なうように変更した。これで、他のPDFファイル(以前作成したmerged.pdfなど)が存在しても動作する。
14
18
 
15
19
 
16
20
 
17
21
  ```Python
18
22
 
23
+ import glob
24
+
25
+ import sys
26
+
19
27
  import PyPDF2
20
-
21
- import os
22
28
 
23
29
 
24
30
 
25
- pdflist = []
31
+ even_list = glob.glob("even_*.pdf")
26
32
 
27
- for filename in os.listdir(os.getcwd()):
33
+ odd_list = glob.glob("odd_*.pdf")
28
34
 
29
- if filename.endswith(r".pdf"):
35
+ if len(even_list) != 1 or len(odd_list) != 1:
30
36
 
37
+ print("1組のPDFファイル(even_*.pdf, odd_*pdf)になっていません")
38
+
31
- pdflist.append(filename)
39
+ sys.exit(1)
32
40
 
33
41
 
34
42
 
35
- pdflist.reverse()
43
+ odd_file_name = odd_list[0]
36
44
 
37
- print(pdflist)
38
-
39
-
40
-
41
- odd_file_name = os.getcwd() + "\" + pdflist[0]
42
-
43
- print(odd_file_name)
45
+ print("odd file: " + odd_file_name)
44
46
 
45
47
  odd_object = open(odd_file_name, "rb")
46
48
 
@@ -48,9 +50,9 @@
48
50
 
49
51
 
50
52
 
51
- even_file_name = os.getcwd() + "\" + pdflist[1]
53
+ even_file_name = even_list[0]
52
54
 
53
- print(even_file_name)
55
+ print("even file: " + even_file_name)
54
56
 
55
57
  even_object = open(even_file_name, "rb")
56
58
 
@@ -80,6 +82,10 @@
80
82
 
81
83
  pdfoutput.close()
82
84
 
85
+ odd_object.close()
86
+
87
+ even_object.close()
88
+
83
89
  print("すべての処理が正常に完了しました。")
84
90
 
85
91
  ```

1

補足を追加

2020/09/12 15:29

投稿

Daregada
Daregada

スコア11990

test CHANGED
@@ -1,3 +1,19 @@
1
+ - 質問へのコメントでも指摘されているように、`odd_object`と`even_object`のモードは`"rb"にしないと読み込めません。
2
+
3
+ - forループで`maxpagenum`という変数が突然出てくる。(偶数ページと奇数ページを比較して、より長くなる可能性がある)`odd_pdf.numPages`に代える。
4
+
5
+ - `pdfwriter`に書き込みを行なう`addPage()`は代入ではなくメソッド呼び出しなので、それに見合う形にする。
6
+
7
+ - 偶数ページのページ数は、奇数ページのページ数と同じか、1ページ少なくなるか(1,3,5ページと2,4ページなど)のどちらかである。1ページ少なくなる場合、`getPage()`しないように`even_pdf.numPages`を使ったif文で処理する。
8
+
9
+
10
+
11
+ 残った問題点は、
12
+
13
+ - カレントディレクトリに存在するPDFファイルが2個以外のときの処理。たとえば、1個だけある場合や、3個以上ある場合にどうするか。現在は`ps.listdir()`の末尾2個だけが処理される。
14
+
15
+
16
+
1
17
  ```Python
2
18
 
3
19
  import PyPDF2