実現したいこと
tkinterでエクセルをPDF化するアプリの作成を考えています。
文字数が多かったので不要なコードは一部削除してます。
python
1 2# pdf_converter_standalone.py 3 4import os 5import win32com.client as win32 6import zipfile 7 8folder = r"ローカルのフォルダーを指定" # ← 必要に応じて変数化 9files = [f for f in os.listdir(folder) if f.endswith(".xlsx") and not f.startswith("~$")] 10 11 12for file in files: 13 try: 14 excel = win32.gencache.EnsureDispatch("Excel.Application") 15 wb = excel.Workbooks.Open(os.path.join(folder, file)) 16 if wb is None: 17 print(f"⚠ 開けない: {file}") 18 excel.Quit() 19 continue 20 21 ws = wb.Sheets(1) 22 ws.PageSetup.PrintArea = "B1:Y63" 23 wb.ExportAsFixedFormat(0, os.path.join(folder, file.replace(".xlsx", ".pdf"))) 24 wb.Close(False) 25 26 with zipfile.ZipFile(os.path.join(folder, file.replace(".xlsx", ".zip")), "w") as zipf: 27 zipf.write(os.path.join(folder, file.replace(".xlsx", ".pdf")), arcname=file.replace(".xlsx", ".pdf")) 28 29 excel.Quit() 30 print(f"✅ 完了: {file}") 31 32 except Exception as e: 33 print(f"❌ {file}: {e}") 34 try: excel.Quit() 35 except: pass 36 37
発生している問題・分からないこと
pyファイルで直接実行するれば問題ないのですが、tkinterでアプリ化して、アプリから実行するとエラーになります。
エラーメッセージ
error
1(-2147417851, 'サーバーによって例外が返されました。', None, None)
該当のソースコード
Python
1import tkinter as tk 2from tkinter import filedialog, messagebox 3import json 4import os 5from excel_splitter_logic import run_excel_processing, convert_to_pdf_and_zip 6 7CONFIG_FILE = "folder_config.json" 8 9class ExcelSplitterApp: 10 def __init__(self, master): 11 self.master = master 12 master.title("Excel 分割アプリ") 13 master.geometry("600x350") 14 15 self.config = self.load_config() 16 17 # Excelファイルパス入力 18 tk.Label(master, text="Excelファイルのパス:").grid(row=0, column=0, sticky=tk.W) 19 self.excel_path = tk.Entry(master, width=50) 20 self.excel_path.grid(row=0, column=1) 21 tk.Button(master, text="参照", command=self.browse_excel).grid(row=0, column=2) 22 23 # ロゴ画像パス入力 24 tk.Label(master, text="ロゴ画像パス:").grid(row=1, column=0, sticky=tk.W) 25 self.image_path = tk.Entry(master, width=50) 26 self.image_path.grid(row=1, column=1) 27 tk.Button(master, text="参照", command=self.browse_image).grid(row=1, column=2) 28 29 # 記号ごとの出力フォルダ入力 30 self.symbol_entries = {} 31 self.symbols = ['#', '$', '%', '&', 'Other'] 32 for i, symbol in enumerate(self.symbols): 33 label = "マーク無し" if symbol == "Other" else symbol 34 tk.Label(master, text=f"{label} 用フォルダ:").grid(row=2+i, column=0, sticky=tk.W) 35 entry = tk.Entry(master, width=50) 36 entry.grid(row=2+i, column=1) 37 tk.Button(master, text="参照", command=lambda s=symbol: self.browse_symbol_folder(s)).grid(row=2+i, column=2) 38 self.symbol_entries[symbol] = entry 39 40 # 設定ファイルに保存されたパスがあれば反映 41 if symbol in self.config: 42 entry.insert(0, self.config[symbol]) 43 44 # 処理ボタン 45 tk.Button(master, text="処理開始", command=self.start_processing).grid(row=7, column=1, pady=10) 46 tk.Button(master, text="PDF & ZIP化実行", command=self.run_pdf_converter).grid(row=8, column=1, pady=5) 47 48 def browse_excel(self): 49 path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx;*.xlsm")]) 50 if path: 51 self.excel_path.delete(0, tk.END) 52 self.excel_path.insert(0, path) 53 54 def browse_image(self): 55 path = filedialog.askopenfilename(filetypes=[("Image files", "*.png;*.jpg;*.jpeg")]) 56 if path: 57 self.image_path.delete(0, tk.END) 58 self.image_path.insert(0, path) 59 60 def browse_symbol_folder(self, symbol): 61 path = filedialog.askdirectory() 62 if path: 63 self.symbol_entries[symbol].delete(0, tk.END) 64 self.symbol_entries[symbol].insert(0, path) 65 self.config[symbol] = path 66 self.save_config() 67 68 def start_processing(self): 69 try: 70 source_file = self.excel_path.get() 71 image_path = self.image_path.get() 72 symbol_paths = {symbol: self.symbol_entries[symbol].get() for symbol in self.symbols} 73 run_excel_processing(source_file, symbol_paths, image_path) 74 messagebox.showinfo("完了", "Excelの分割保存が完了しました。") 75 except Exception as e: 76 messagebox.showerror("エラー", f"処理中にエラーが発生しました:\n{str(e)}") 77 78 def run_pdf_converter(self): 79 try: 80 sharp_folder = self.symbol_entries["#"].get() 81 if not os.path.exists(sharp_folder): 82 messagebox.showerror("エラー", "「#」記号用のフォルダが設定されていません。") 83 return 84 convert_to_pdf_and_zip(sharp_folder) 85 messagebox.showinfo("完了", "PDF変換とZIP化が完了しました。") 86 except Exception as e: 87 messagebox.showerror("エラー", f"PDF/ZIP処理中にエラーが発生しました:\n{str(e)}") 88 89 def load_config(self): 90 if os.path.exists(CONFIG_FILE): 91 with open(CONFIG_FILE, "r", encoding="utf-8") as f: 92 return json.load(f) 93 return {} 94 95 def save_config(self): 96 with open(CONFIG_FILE, "w", encoding="utf-8") as f: 97 json.dump(self.config, f, ensure_ascii=False, indent=2) 98 99# アプリ実行 100if __name__ == '__main__': 101 root = tk.Tk() 102 app = ExcelSplitterApp(root) 103 root.mainloop() 104
Python
1import os 2import re 3import zipfile 4import unicodedata 5from openpyxl import load_workbook, Workbook 6from openpyxl.utils import get_column_letter 7from openpyxl.worksheet.cell_range import CellRange 8from openpyxl.drawing.image import Image as XLImage 9from openpyxl.styles import Font, Border, Side 10from PIL import Image as PILImage 11from copy import copy 12import win32com.client as win32 13 14# ---------------------------- 15# ファイル名を安全に整形(記号除去、全角→半角、スペース除去) 16# ---------------------------- 17def sanitize_filename(name: str) -> str: 18 name = unicodedata.normalize("NFKC", name) # 全角 → 半角 19 name = re.sub(r'[\\/:*?"<>|]', '', name) # 禁止記号除去 20 name = name.replace('\u3000', '') # 全角スペース除去 21 return name.strip() 22 23# ---------------------------- 24# PDF + ZIP変換処理(ファイルごとにExcel起動) 25# ---------------------------- 26def convert_to_pdf_and_zip(folder_path): 27 for file in os.listdir(folder_path): 28 if file.endswith(".xlsx") and not file.startswith("~$"): 29 xlsx_path = os.path.join(folder_path, file) 30 pdf_path = xlsx_path.replace(".xlsx", ".pdf") 31 zip_path = xlsx_path.replace(".xlsx", ".zip") 32 33 try: 34 print(f"[処理中] {file}") 35 excel = win32.gencache.EnsureDispatch("Excel.Application") 36 excel.Visible = False 37 38 wb = excel.Workbooks.Open(xlsx_path) 39 if wb is None: 40 print(f"[スキップ] Excelで開けませんでした: {file}") 41 excel.Quit() 42 continue 43 44 try: 45 ws = wb.Sheets("試験成績表") 46 except: 47 print(f"[スキップ] シートが存在しません: {file}") 48 wb.Close(False) 49 excel.Quit() 50 continue 51 52 ws.PageSetup.Zoom = False 53 ws.PageSetup.FitToPagesWide = 1 54 ws.PageSetup.FitToPagesTall = 1 55 ws.PageSetup.PrintArea = "A1:Y63" 56 ws.PageSetup.CenterHorizontally = True 57 ws.PageSetup.LeftMargin = 0.2 58 ws.PageSetup.RightMargin = 0.2 59 ws.PageSetup.TopMargin = 0.2 60 ws.PageSetup.BottomMargin = 0.2 61 ws.PageSetup.HeaderMargin = 0.1 62 ws.PageSetup.FooterMargin = 0.1 63 64 if os.path.exists(pdf_path): 65 os.remove(pdf_path) 66 67 wb.ExportAsFixedFormat(0, pdf_path) 68 wb.Close(False) 69 excel.Quit() 70 71 with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf: 72 zipf.write(pdf_path, os.path.basename(pdf_path)) 73 74 print(f"[成功] PDF+ZIP 完了: {file}") 75 76 except Exception as e: 77 print(f"[エラー] PDFまたはZIPに失敗: {file}: {e}") 78 79
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
chatgptなどでエラーの改善を聞いてみましたが効果がありませんでした。
補足
特になし
> 文字数が多かったので不要なコードは一部削除してます。
省かれたコード内に問題があった場合、問題解決できません。
現状のコードから省くのではなく、
質問に掲載するエラーが再現できる・「実行可能な」最小のコードを
新たに作成して質問文に掲載してください。(問題の再現に必要ならば読み込み対象のファイルも)

回答3件
あなたの回答
tips
プレビュー