【Python自动化办公脚本】Excel文件批量转PDF文件

import os
import win32com.client
import tkinter as tk
from tkinter import ttk
from ttkbootstrap import Style
from tkinter import filedialog, messagebox
from threading import Thread


class ExcelToPDFConverter:
    def __init__(self, master):
        self.master = master
        self.master.title("Excel转PDF工具 - 专业版")
        self.master.geometry("600x400")

        # 应用ttkbootstrap主题
        self.style = Style(theme='morph')
        self.style.configure('TButton', font=('微软雅黑', 10))

        # 界面组件
        self.create_widgets()
        self.running = False

    def create_widgets(self):
        """创建界面组件"""
        # 文件选择区域
        frame_files = ttk.Frame(self.master)
        frame_files.pack(pady=10, padx=20, fill='x')

        self.btn_select = ttk.Button(
            frame_files,
            text="选择Excel文件",
            command=self.select_files,
            style='primary'
        )
        self.btn_select.pack(side='left', padx=5)

        self.lbl_files = ttk.Label(frame_files, text="未选择文件")
        self.lbl_files.pack(side='left', fill='x', expand=True)

        # 输出目录区域
        frame_output = ttk.Frame(self.master)
        frame_output.pack(pady=10, padx=20, fill='x')

        self.btn_output = ttk.Button(
            frame_output,
            text="选择保存位置",
            command=self.select_output,
            style='info'
        )
        self.btn_output.pack(side='left', padx=5)

        self.lbl_output = ttk.Label(frame_output, text="未选择目录")
        self.lbl_output.pack(side='left', fill='x', expand=True)

        # 进度条
        self.progress = ttk.Progressbar(
            self.master,
            orient='horizontal',
            mode='determinate'
        )
        self.progress.pack(pady=15, padx=20, fill='x')

        # 日志区域
        self.log_text = tk.Text(
            self.master,
            height=8,
            state='disabled',
            font=('Consolas', 9)
        )
        self.log_text.pack(pady=10, padx=20, fill='both', expand=True)

        # 操作按钮
        frame_btn = ttk.Frame(self.master)
        frame_btn.pack(pady=10)

        self.btn_start = ttk.Button(
            frame_btn,
            text="开始转换",
            command=self.start_conversion,
            style='success'
        )
        self.btn_start.pack(side='left', padx=10)

        self.btn_clear = ttk.Button(
            frame_btn,
            text="清空日志",
            command=self.clear_log,
            style='warning'
        )
        self.btn_clear.pack(side='left', padx=10)

    def select_files(self):
        """选择Excel文件"""
        files = filedialog.askopenfilenames(
            filetypes=[("Excel文件", "*.xls *.xlsx")]
        )
        if files:
            self.file_paths = files
            self.lbl_files.config(text=f"已选择 {len(files)} 个文件")

    def select_output(self):
        """选择输出目录"""
        folder = filedialog.askdirectory()
        if folder:
            self.output_folder = folder
            self.lbl_output.config(text=folder)

    def log_message(self, msg):
        """记录日志"""
        self.log_text.config(state='normal')
        self.log_text.insert('end', msg + '\n')
        self.log_text.see('end')
        self.log_text.config(state='disabled')

    def clear_log(self):
        """清空日志"""
        self.log_text.config(state='normal')
        self.log_text.delete(1.0, 'end')
        self.log_text.config(state='disabled')

    def start_conversion(self):
        """启动转换线程"""
        if not hasattr(self, 'file_paths'):
            messagebox.showwarning("警告", "请先选择Excel文件")
            return
        if not hasattr(self, 'output_folder'):
            messagebox.showwarning("警告", "请选择输出目录")
            return

        if not self.running:
            self.running = True
            Thread(target=self.convert_files).start()

    def convert_files(self):
        """执行转换"""
        total = len(self.file_paths)
        excel = win32com.client.Dispatch("Excel.Application")
        excel.Visible = False
        excel.DisplayAlerts = False

        try:
            for i, file_path in enumerate(self.file_paths, 1):
                if not self.running:
                    break

                self.progress['value'] = (i / total) * 100
                self.master.title(f"转换中... {i}/{total}")

                try:
                    # 转换逻辑
                    workbook = excel.Workbooks.Open(file_path)
                    file_name = os.path.splitext(os.path.basename(file_path))[0]
                    output_path = os.path.join(self.output_folder, f"{file_name}.pdf")
                    workbook.ExportAsFixedFormat(0, output_path)
                    self.log_message(f"✓ 成功: {file_name}")
                except Exception as e:
                    self.log_message(f"✗ 失败: {os.path.basename(file_path)} - {str(e)}")
                finally:
                    if 'workbook' in locals():
                        workbook.Close(False)

            messagebox.showinfo("完成", "所有文件转换完成!")
        finally:
            excel.Quit()
            self.running = False
            self.master.title("Excel转PDF工具 - 专业版")
            self.progress['value'] = 0


if __name__ == "__main__":
    # 安装依赖:pip install ttkbootstrap pywin32
    root = tk.Tk()
    app = ExcelToPDFConverter(root)
    root.mainloop()

你可能感兴趣的:(python)