実現したいこと
pythonでPDFをエクセルに変換するプログラムを作成したい
発生している問題・分からないこと
70行目で整数除算のエラーが発生してしまいます
エラーメッセージ
error
1Traceback (most recent call last): 2 File "c:\Users\USER\OneDrive\デスクトップ\python\PDF_Excel.py", line 70, in <module> 3 y = df_s_x.iloc[i,5] // (math.ceil(h_min*10)/10) + 1 4 ~~~~~~~~~~~~~~~~~^^~~~~~~~~~~~~~~~~~~~~~~~~~ 5TypeError: unsupported operand type(s) for //: 'str' and 'float'
該当のソースコード
python
1from pdfminer3.pdfinterp import PDFResourceManager, PDFPageInterpreter 2from pdfminer3.converter import PDFPageAggregator 3from pdfminer3.pdfpage import PDFPage 4from pdfminer3.layout import LAParams, LTTextContainer 5import pandas as pd 6import openpyxl 7import math 8from tkinter import filedialog 9import os 10 11def pdfminer_config(line_overlap, word_margin, char_margin,line_margin, detect_vertical): 12 laparams = LAParams(line_overlap=line_overlap, 13 word_margin=word_margin, 14 char_margin=char_margin, 15 line_margin=line_margin, 16 detect_vertical=detect_vertical) 17 resource_manager = PDFResourceManager() 18 device = PDFPageAggregator(resource_manager, laparams=laparams) 19 interpreter = PDFPageInterpreter(resource_manager, device) 20 return (interpreter, device) 21 22typ = [('pdfファイル','*.pdf')] 23dir = './' 24pdf_file_name = filedialog.askopenfilename(filetypes = typ, initialdir = dir) 25work_file = os.path.splitext(pdf_file_name)[0] + '_work.xlsx' 26excel_file_name = os.path.splitext(pdf_file_name)[0] + '.xlsx' 27 28list1 = ['','','','','','','',''] 29df_x = pd.DataFrame([list1]) 30df_x.columns = ['page', 'word', 'x1','x2','y1','y2','width','hight'] 31int_page = 0 32ii_index = 0 33 34with open(pdf_file_name, 'rb') as fp: 35 interpreter, device = pdfminer_config(line_overlap=0.1, word_margin=0.1, 36 char_margin=0.1, line_margin=0.1, detect_vertical=False) 37 for page in PDFPage.get_pages(fp): 38 int_page = int_page + 1 39 interpreter.process_page(page) 40 layout = device.get_result() 41 for lt in layout: 42 # LTTextContainerの場合だけ標準出力 43 if isinstance(lt, LTTextContainer): 44 df_x.loc[ii_index] = [int_page,'{}'.format(lt.get_text().strip()), lt.x0 , lt.x1 ,\ 45 841 - lt.y0 + (int_page - 1) * 841,841 - lt.y1 + (int_page - 1) * 841,lt.width ,lt.height ] 46 ii_index = ii_index + 1 47 48device.close() 49 50# x1でソート 51df_s_x = df_x.sort_values(['x1','y2'], ascending=[True,True]) 52# 縦のピッチを計算 53h_min = 100 54for i in range(len(df_s_x)): 55 if i > 0: 56 if df_s_x.iloc[i-1,2] == df_s_x.iloc[i,2]: 57 h_sa = df_s_x.iloc[i,5] - df_s_x.iloc[i-1,5] 58 if h_sa > 1.0 and h_min > h_sa: 59 h_min = h_sa 60 61# workファイルを書き出し 62with pd.ExcelWriter(work_file) as writer: 63 df_s_x.to_excel(writer, sheet_name='sheet1', index=False) 64wb = openpyxl.Workbook() 65ws = wb.worksheets[0] 66 67j = 1 68width_x = 0 69for i in range(len(df_s_x)): 70 y = df_s_x.iloc[i,5] // (math.ceil(h_min*10)/10) + 1 71 c1 = ws.cell(row=int(y), column=j) 72 if c1.value == None: 73 c1.value = df_s_x.iloc[i,1] 74 else: 75 #列幅調整 76 ws.column_dimensions[ws.cell(row=1, column=j).column_letter].width = (df_s_x.iloc[i,2]/5.98- width_x ) 77 width_x = df_s_x.iloc[i,2]/5.98 78 j = j + 1 79 c1 = ws.cell(row=int(y), column=j) 80 c1.value = df_s_x.iloc[i,1] 81 82wb.save(excel_file_name) 83
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
AIに質問した際に文字列を浮動小数点数に変換するためにfloat()使用すると改善すると回答がでました
補足
特になし
> df_s_x.iloc[i,5] // (math.ceil(h_min*10)/10) + 1
上記は何をしたくて書いたコードですか?
1列目から値をセットしつつ、既に文字が入っていれば列の幅を調整したうえで次の列へ値をセットしています
df_s_x.iloc[i,5] には数値が入っているはずということでしょうか?
そうなると思っています。
> そうなると思っています。
確かめましたか?
「TypeError: unsupported operand type(s) for //: 'str' and 'float'」が発生するということは何か間違いがあったのではないでしょうか?
色々なPDFで試した結果、A1セルから縦に順番に文字が入っているようなファイルでは上手く作動する事は
確認が取れています。
ですが発注書や納品書みたいな不規則な文字の配列がしているファイルではエラーが出てしまいます。
df_s_x.iloc[i,5] には数値が入っていることを確認されましたか?という意味でコメントしました。つまりデバッグしましたか?ということです。
意味を理解できておらず申し訳ございません。
規則性のあるPDFなら数値が入っている事を確認とれています。
df_s_x.iloc[i,5]は['page', 'word', 'x1','x2','y1','y2','width','hight']の内の y2 を指しているってことですよね?そこに値を入れる処理で文字列が混入してしまっているのではないでしょうか?(df_x.loc[ii_index] = ・・・ のところでしょうか?)
やりたかった事はスキャンしたPDFをエクセルに変換したかったのですが
このコードでは実現不可能だと知りました。
今までたくさんのコメントを頂きましたがご迷惑をおかけしました。
回答1件
あなたの回答
tips
プレビュー