乐于分享
好东西不私藏

批量将全桥工程数量表转PDF

批量将全桥工程数量表转PDF

有的时候一堆全桥工程数量表,每次出版都要单独打开Excel、选中「全桥工程数量表」、另存为PDF。几十个文件挨个手动转换,耗时又费力。用AI写个PYTHON代码省时省力。

# -*- coding: utf-8 -*-

"""

Excel转PDF工具

选择多个Excel文件,将"全桥工程数量表"工作表转换为PDF

使用方法:

    双击运行,选择多个Excel文件后自动转换

"""

import tkinter as tk

from tkinter import filedialog, messagebox, ttk

from pathlib import Path

import os

import sys

# 尝试导入win32com

try:

import win32com.client as win32

    HAS_WIN32 =True

exceptImportError:

    HAS_WIN32 =False

print("正在安装pywin32...")

    os.system(f"{sys.executable} -m pip install pywin32 -q")

try:

import win32com.client as win32

        HAS_WIN32 =True

except:

pass

classExcelToPdfTool:

def__init__(selfroot):

self.root = root

self.root.title("Excel转PDF工具")

self.root.geometry("600x550")

self.root.resizable(FalseFalse)

# 变量

self.selected_files = []

self.sheet_name = tk.StringVar(value="全桥工程数量表")

self.progress_var = tk.DoubleVar(value=0)

self.create_widgets()

# 检查依赖

ifnot HAS_WIN32:

            messagebox.showerror("错误""无法导入win32com,请确保已安装Microsoft Excel和pywin32\n\n安装命令:pip install pywin32")

defcreate_widgets(self):

"""创建界面元素"""

# 标题

        tk.Label(self.root, text="Excel转PDF工具"

font=("微软雅黑"16"bold")).pack(pady=10)

# 文件选择区域

        file_frame = tk.Frame(self.root)

        file_frame.pack(fill="x"padx=20pady=5)

        tk.Button(file_frame, text="选择Excel文件..."command=self.select_files,

bg="#2196F3"fg="white"font=("微软雅黑"11),

width=20height=2).pack(side="left"padx=5)

        tk.Button(file_frame, text="清空选择"command=self.clear_files,

bg="#FF9800"fg="white"font=("微软雅黑"11),

width=10height=2).pack(side="left"padx=5)

# 文件列表显示

        list_frame = tk.LabelFrame(self.root, text="已选择的文件"font=("微软雅黑"10))

        list_frame.pack(fill="both"expand=Truepadx=20pady=5)

self.file_listbox = tk.Listbox(list_frame, height=8width=70)

self.file_listbox.pack(side="left"fill="both"expand=Truepadx=5pady=5)

        scrollbar = tk.Scrollbar(list_frame, command=self.file_listbox.yview)

        scrollbar.pack(side="right"fill="y")

self.file_listbox.config(yscrollcommand=scrollbar.set)

# 工作表名称

        sheet_frame = tk.Frame(self.root)

        sheet_frame.pack(fill="x"padx=20pady=5)

        tk.Label(sheet_frame, text="工作表名称:").pack(side="left")

        tk.Entry(sheet_frame, textvariable=self.sheet_name, width=30).pack(side="left"padx=5)

# 提示

        tk.Label(self.root, text="提示:将转换指定工作表为PDF,文件名与Excel相同"

fg="gray"font=("微软雅黑"9)).pack(pady=2)

# 进度条

self.progress = ttk.Progressbar(self.root, variable=self.progress_var, 

maximum=100length=500)

self.progress.pack(padx=20pady=5)

# 执行按钮

        btn_frame = tk.Frame(self.root)

        btn_frame.pack(pady=10)

        tk.Button(btn_frame, text="开始转换"command=self.start_convert,

bg="#4CAF50"fg="white"font=("微软雅黑"12"bold"),

width=15height=2).pack(side="left"padx=10)

        tk.Button(btn_frame, text="退出"command=self.root.quit,

bg="#f44336"fg="white"font=("微软雅黑"12),

width=10height=2).pack(side="left"padx=10)

# 结果显示

self.result_text = tk.Text(self.root, height=6width=65)

self.result_text.pack(padx=20pady=5)

self.result_text.insert("1.0""等待操作...\n")

self.result_text.config(state="disabled")

defselect_files(self):

"""选择Excel文件"""

        files = filedialog.askopenfilenames(

title="选择Excel文件",

filetypes=[("Excel文件""*.xlsx;*.xls"), ("所有文件""*.*")]

        )

if files:

forfilein files:

iffilenotinself.selected_files:

self.selected_files.append(file)

self.file_listbox.insert("end", Path(file).name)

self.log(f"已选择 {len(self.selected_files)} 个文件")

defclear_files(self):

"""清空选择的文件"""

self.selected_files.clear()

self.file_listbox.delete(0"end")

self.log("已清空选择")

deflog(selfmessage):

"""输出日志"""

self.result_text.config(state="normal")

self.result_text.insert("end", message +"\n")

self.result_text.see("end")

self.result_text.config(state="disabled")

self.root.update()

defclear_log(self):

"""清空日志"""

self.result_text.config(state="normal")

self.result_text.delete("1.0""end")

self.result_text.config(state="disabled")

defconvert_excel_to_pdf(selfexcel_pathpdf_pathsheet_name):

"""

        将Excel指定工作表转换为PDF

        """

        excel =None

        wb =None

try:

# 创建Excel应用

            excel = win32.Dispatch("Excel.Application")

            excel.Visible =False

            excel.DisplayAlerts =False

# 打开工作簿

            wb = excel.Workbooks.Open(str(excel_path))

# 查找指定工作表

            target_sheet =None

for sheet in wb.Sheets:

if sheet.Name == sheet_name:

                    target_sheet = sheet

break

if target_sheet isNone:

self.log(f"  未找到工作表 '{sheet_name}',将使用第一个工作表")

                target_sheet = wb.Sheets(1)

# 激活工作表

            target_sheet.Activate()

# 导出为PDF

            target_sheet.ExportAsFixedFormat(

Type=0,  # 0 = PDF

Filename=str(pdf_path),

Quality=0,  # 0 = 标准质量

IncludeDocProperties=True,

IgnorePrintAreas=False

            )

# 关闭工作簿

            wb.Close(SaveChanges=False)

            wb =None

            excel.Quit()

            excel =None

returnTrue

exceptExceptionas e:

self.log(f"  转换失败: {e}")

if wb:

try:

                    wb.Close(SaveChanges=False)

except:

pass

if excel:

try:

                    excel.Quit()

except:

pass

returnFalse

defstart_convert(self):

"""开始转换"""

# 检查依赖

ifnot HAS_WIN32:

            messagebox.showerror("错误""无法导入win32com,请确保已安装Microsoft Excel和pywin32\n\n安装命令:pip install pywin32")

return

# 检查文件

ifnotself.selected_files:

            messagebox.showwarning("警告""请先选择Excel文件")

return

# 确认对话框

        sheet_name =self.sheet_name.get().strip()

ifnot sheet_name:

            messagebox.showwarning("警告""请输入工作表名称")

return

ifnot messagebox.askyesno("确认"

f"将处理 {len(self.selected_files)} 个Excel文件\n"

f"工作表: {sheet_name}\n\n是否继续?"):

return

# 清空日志并开始

self.clear_log()

self.log(f"开始处理 {len(self.selected_files)} 个文件")

self.log(f"工作表: {sheet_name}")

self.log("="*50)

        success_count =0

        error_count =0

        skipped_count =0

        total =len(self.selected_files)

for i, excel_file inenumerate(self.selected_files):

# 更新进度

            progress = (i / total) *100

self.progress_var.set(progress)

self.root.update()

            excel_path = Path(excel_file)

            pdf_path = excel_path.parent /f"{excel_path.stem}.pdf"

# 检查是否已存在

if pdf_path.exists():

self.log(f"[跳过] {excel_path.name} - PDF已存在")

                skipped_count +=1

continue

self.log(f"[处理] {excel_path.name}")

# 转换

ifself.convert_excel_to_pdf(excel_path, pdf_path, sheet_name):

self.log(f"  ✓ 已保存: {pdf_path.name}")

                success_count +=1

else:

                error_count +=1

# 完成进度

self.progress_var.set(100)

self.root.update()

# 统计

self.log("="*50)

self.log(f"完成!成功:{success_count} 跳过:{skipped_count} 失败:{error_count}")

        messagebox.showinfo("完成"

f"转换完成!\n成功: {success_count}\n跳过: {skipped_count}\n失败: {error_count}")

defmain():

    root = tk.Tk()

    app = ExcelToPdfTool(root)

    root.mainloop()

if__name__=="__main__":

    main()