Excel模板填充工具(工具&脚本分享)

前言

这是一个基于Python的Excel自动化工具,能够根据数据模板批量生成个性化的多工作表Excel文件。能让测试人员告别手动复制粘贴!一键将数据批量填充到模板,自动生成上百份标准化报告。

现成工具分享:

通过网盘分享的文件:TestTool_V3.0.exe

链接: https://pan.baidu.com/s/1y2uoE-c0BaZMW5lIl04Amg?pwd=i5pq 提取码: i5pq

工具介绍:

导入模板文件+信息文件,选择输出文件位置,点击"生成测试用例"按钮,自动生成完整的用例表并自动调整列宽。

背景

模板表如下:

信息表如下:

如上:信息表提供了两个人的信息。现在需要在模板表的基础上,分别为2人生成一个sheet,并将模板中{}的内容替换为信息表中对应的数据。

预期效果如下:

一、clean_sheet_name()

Excel本身有一套针对sheet的命名规则。clean_sheet_name() 函数的作用就是写出命名规则,具体是:

  • 预处理:在数据传给 Excel 前,确保名称合规

  • 避免错误:防止写入 Excel 时失败

  • 保持一致性:确保所有工作表名称都符合规范

1.1 切片操作

python 复制代码
name = 'Hello world'
print(name[:3])
print(name[0:3])
print(name[slice(0,3)])

结果:

1.2 strip()移除首尾两端的空格

python 复制代码
name = '  12Hello world34  '
print(f"移除首尾空格:",name.strip())
print(f"移除左边空格:",name.lstrip())
print(f"移除右边空格:",name.rstrip())
# 先移除首端的空白再移除数字
print(f"移除指定字符:",name.lstrip().strip('12'))

结果:

通过strip()检查字符串是否为空:

python 复制代码
# 确保名称不为空
# 方法1
    if not name.strip():
        name = "Sheet"

# 方法2
if name.strip() == "":
    name = "Sheet"

# 方法3
if len(name.strip()) == 0:
    name = "Sheet"

(1)not name.strip() 的判断逻辑

在Python中,空字符串 "" 在布尔上下文中被视为 False,非空字符串被视为 True

所以:

  • name.strip() 返回空字符串 → if not ""True

  • name.strip() 返回非空字符串 → if not "some_value"False

(2)Python中可以写 if False,但它没有实际意义,不会执行

python 复制代码
# 实际上,if 语句会自动进行布尔转换
value = ""
if value:  # 这里会自动转换为 if bool(value)
    print("非空")
else:
    print("空")  # 会执行这个

# 所以这些都是等价的:
if not value:
    pass
    
if value == "":
    pass
    
if len(value) == 0:
    pass
    
if bool(value) == False:
    pass

1.3 clean_sheet_name()修改不合规则的sheet名

  • pd.isna():专门检测 pandas/Numpy的缺失值(None, np.nan, NaT等)
python 复制代码
import pandas as pd
def clean_sheet_name(name, max_length=31):
    """
    清理sheet名称,确保符合Excel命名规则

    参数:
    name: 原始sheet名称
    max_length: 最大长度限制(Excel限制为31个字符)
    """
    if pd.isna(name):
        name = "Sheet"
    else:
        name = str(name)

    # 移除非法字符
    illegal_chars = [':', '\\', '/', '?', '*', '[', ']']
    for char in illegal_chars:
        name = name.replace(char, '')

    # 截断到最大长度
    if len(name) > max_length:
        name = name[:max_length]

    # 确保名称不为空
    if not name.strip():
        name = "Sheet"

    return name
# 测试各种情况
test_cases = [
    None,                     # 空值
    "销售数据:2024年/第一季度",  # 包含非法字符
    "这是一个非常非常非常长的Excel工作表名称超过了31个字符llll",  # 超长
    "   ",                    # 只有空白
    "正常名称",               # 正常情况
]

for test in test_cases:
    print(f"原始Sheet名称:{test} -> 清理后名称:{clean_sheet_name(test)}")

结果:

二、Pandas内置方法

2.1 iterrows()

iterrows() 返回一个迭代器,每次迭代返回一个元组,包含两个值:

  • 第一个值:行索引(从0开始的整数)

  • 第二个值:该行的数据(pandas Series对象)

python 复制代码
import pandas as pd

df = pd.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'c']})

for idx,row in df.iterrows():
    print(f"索引:{idx},行数据:{row['A']},{row['B']}")

结果:

1、可以只接收行数据,不要索引吗?

可以,但需要用下划线 _ 表示不关心的变量:

python 复制代码
for _,row in df.iterrows():
    print(f"行数据:{row['A']},{row['B']}")

2.2 read_excel()

read_excel() 是 pandas 的一个内置函数, 是一个顶级函数。

复制代码
# 读取Excel文件
df = pd.read_excel('文件.xlsx', sheet_name='Sheet1')

2.3 .loc()

test_case_df.loc[idx, col] 的作用是:

  1. 精确定位 :通过行标签idx和列标签col找到DataFrame中的特定单元格

  2. 支持CRUD:可用于读取、修改、创建数据

  3. 标签导向:使用有意义的标签而非容易变化的位置索引

python 复制代码
import pandas as pd

df = pd.DataFrame({
    'A': [1, 2, 3],
    'B': [4, 5, 6],
    'C': [7, 8, 9]
}, index=['row1', 'row2', 'row3'])

# 使用.loc - 基于标签
print(df.loc['row2', 'B'])  # 输出: 5

# 使用.iloc - 基于位置(整数索引)
print(df.iloc[1, 1])       # 输出: 5 (第2行第2列)

loc()会选择DataFrame中特定行和列的单个值(也就是单元格的值), 这是Pandas中最常用、最推荐的数据选择方法之一。

2.4 columns返回列名

python 复制代码
import pandas as pd

# 创建一个DataFrame
df = pd.DataFrame({
    '姓名': ['张三', '李四', '王五'],
    '年龄': [25, 30, 28],
    '城市': ['北京', '上海', '广州']
})

# .columns 返回列名
print(df.columns)
# 输出: Index(['姓名', '年龄', '城市'], dtype='object')
print(type(df.columns))  # <class 'pandas.core.indexes.base.Index'>

2.5 f-string中花括号的转义规则

python 复制代码
name = "张三"
age = 25

print(f"{name}")           # 张三
print(f"{{name}}")         # {name}
print(f"{{{name}}}")       # {张三}
print(f"{{{{{name}}}}}")   # {{张三}}

三、主函数

3.1 with pd.ExcelWriter() as writer

这是上下文管理器的使用方式

python 复制代码
# 等价写法(不推荐,因为需要手动关闭)
writer = pd.ExcelWriter(output_file, engine='openpyxl')
try:
    # 写入操作
    total_rows = len(info_df)
    # ...
finally:
    writer.save()  # 必须手动保存
    writer.close()  # 必须手动关闭

# 使用 with 语句(推荐)
# 自动处理资源的打开和关闭,即使出错也会正确关闭
with pd.ExcelWriter(...) as writer:
    # 写入操作
    pass
# 退出 with 块时自动调用 writer.save() 和 writer.close()

(1)参数说明:

  • output_file:输出文件的路径字符串

  • engine='openpyxl':指定使用 openpyxl 引擎处理 Excel 文件

(2) 基本用法

writer 指的是什么?
writerpd.ExcelWriter 创建的一个Excel写入器对象,它代表了名为"output.xlsx"的这个Excel文件。

python 复制代码
import pandas as pd

# 创建示例数据
info_df = pd.DataFrame({
    '姓名': ['张三', '李四', '王五'],
    '年龄': [25, 30, 35],
    '城市': ['北京', '上海', '广州']
})

output_file = r'C:\Users\uexwcl\Downloads\output.xlsx'
with pd.ExcelWriter(output_file,engine='openpyxl') as writer:
    total_rows = len(info_df)

#     1.将DataFrame写入Excel,指定sheet名
    info_df.to_excel(writer, sheet_name='员工信息', index=False)
#     2.写入多个工作表
    summary_df = pd.DataFrame({
        '统计': ['总行数', '平均年龄'],
        '数值': [total_rows, info_df['年龄'].mean()]
    })
    summary_df.to_excel(writer,sheet_name='统计',index=False)

结果:

3.2 替换占位符逻辑(优化)

仍然是4层循环,不过是先提取模板表中每个单元格的占位符,并对占位符进行去重处理,再来和信息表中的列名比对。一致则替换。

算法层通过占位符去重减少计算;数据层使用Pandas向量化操作;内存层采用流式处理和模板复用来控制内存峰值。

python 复制代码
 # 4. 为信息表中的每一行生成一个sheet
            for index, row in info_df.iterrows():
                # 获取编号(用于sheet名称)
                sheet_name = clean_sheet_name(row.get('编号'))

                print(f"正在处理第 {index + 1}/{total_rows} 行: {sheet_name}")

                # 复制模板
                test_case_df = template_df.copy()

                # 5. 替换模板中的占位符
                for col in test_case_df.columns:
                    for idx in test_case_df.index:
                        cell_value = clean_value(test_case_df.loc[idx, col])

                        # 提取实际存在的占位符-- 非贪婪匹配,匹配 { 和 } 之间的所有内容
                        placeholders = re.findall(r'\{(.*?)\}', cell_value)

                        if placeholders:  # 只有存在占位符时才处理
                            for placeholder in set(placeholders):  # 去重
                                if placeholder in info_df.columns:
                                    replacement = clean_value(row.get(placeholder, ""))
                                    cell_value = cell_value.replace(f"{{{placeholder}}}", replacement)

                        test_case_df.loc[idx, col] = cell_value

四、问题记录

1、模板中{}里包含":"、空格,就无法替换成信息表的具体内容

复制代码
# 提取实际存在的占位符
placeholders = re.findall(r'\{(\w+)\}', cell_value)
python 复制代码
import re

# 示例1
cell_value = "Hello {name}, your score is {score_2023}"
placeholders = re.findall(r'\{(\w+)\}', cell_value)
# 结果: ['name', 'score_2023']

# 示例2 - 不匹配的情况
cell_value = "No placeholders here"
placeholders = re.findall(r'\{(\w+)\}', cell_value)
# 结果: []

使用正则表达式从字符串中提取的占位符特点:

  • 只提取花括号 {} 内的内容

  • 占位符名称只能包含:字母、数字、下划线(\w 的含义)

  • 区分大小写

  • 不支持带空格的占位符名称

  • 不支持特殊字符(如 {user-name} 不会被匹配)

2、自动调整列宽

python 复制代码
def auto_adjust_column_width(worksheet, df):
    """
    自动调整Excel列的宽度以适应内容

    参数:
    worksheet: openpyxl的worksheet对象
    df: 对应的DataFrame
    """
    try:
        # 遍历DataFrame的每一列
        for column in df:
            # 获取列索引(从1开始)
            column_letter = openpyxl.utils.get_column_letter(df.columns.get_loc(column) + 1)

            # 计算列的最大宽度
            # 考虑列名本身的宽度
            max_length = max(
                len(str(column)),  # 列名宽度
                df[column].astype(str).map(len).max()  # 该列数据最大宽度
            )

            # 添加一些边距(增加20%的宽度或至少5个字符)
            adjusted_width = max_length * 1.2 + 5

            # 设置列宽,限制在5到50之间
            adjusted_width = max(5, min(adjusted_width, 50))

            # 应用列宽
            worksheet.column_dimensions[column_letter].width = adjusted_width

五、源码

51. CaseOutput.py

python 复制代码
import pandas as pd
import openpyxl
import warnings
import re  # 正则表达式模块,用于提取占位符

warnings.filterwarnings('ignore')


def clean_sheet_name(name, max_length=31):
    """
    清理sheet名称,确保符合Excel命名规则

    参数:
    name: 原始sheet名称
    max_length: 最大长度限制(Excel限制为31个字符)
    """
    if pd.isna(name):
        name = "Sheet"
    else:
        name = str(name)

    # 移除非法字符
    illegal_chars = [':', '\\', '/', '?', '*', '[', ']']
    for char in illegal_chars:
        name = name.replace(char, '')

    # 截断到最大长度
    if len(name) > max_length:
        name = name[:max_length]

    # 确保名称不为空
    if not name.strip():
        name = "Sheet"

    return name


def clean_value(value):
    """
    清理单元格值,处理NaN和None

    参数:
    value: 原始值
    返回: 清理后的字符串
    """
    if pd.isna(value):
        return ""
    return str(value)


def auto_adjust_column_width(worksheet, df):
    """
    自动调整Excel列的宽度以适应内容

    参数:
    worksheet: openpyxl的worksheet对象
    df: 对应的DataFrame
    """
    try:
        # 遍历DataFrame的每一列
        for column in df:
            # 获取列索引(从1开始)
            column_letter = openpyxl.utils.get_column_letter(df.columns.get_loc(column) + 1)

            # 计算列的最大宽度
            # 考虑列名本身的宽度
            max_length = max(
                len(str(column)),  # 列名宽度
                df[column].astype(str).map(len).max()  # 该列数据最大宽度
            )

            # 添加一些边距(增加20%的宽度或至少5个字符)
            adjusted_width = max_length * 1.2 + 5

            # 设置列宽,限制在5到50之间
            adjusted_width = max(5, min(adjusted_width, 50))

            # 应用列宽
            worksheet.column_dimensions[column_letter].width = adjusted_width

    except Exception as e:
        print(f"自动调整列宽时发生错误: {e}")
        # 如果出错,设置默认列宽
        for column in df.columns:
            column_letter = openpyxl.utils.get_column_letter(df.columns.get_loc(column) + 1)
            worksheet.column_dimensions[column_letter].width = 20
def generate_test_cases_from_files(template_file, info_file, output_file):
    """
    处理文件生成测试用例

    参数:
    template_file: 模板文件路径
    info_file: 信息表文件路径
    output_file: 输出文件路径

    返回: 生成的测试用例数量
    """
    try:
        print("正在读取模板文件...")

        # 1. 读取模板文件,保持空单元格为空字符串
        template_df = pd.read_excel(
            template_file,
            dtype=str,  # 所有列都读取为字符串类型
            keep_default_na=False
        )

        print("正在读取信息表...")

        # 2. 读取信息表,保持空单元格为空字符串
        info_df = pd.read_excel(
            info_file,
            dtype=str,
            keep_default_na=False
        )

        print("正在生成Excel文件...")

        # 3. 创建Excel写入对象
        with pd.ExcelWriter(output_file, engine='openpyxl') as writer:
            total_rows = len(info_df)

            # 4. 为信息表中的每一行生成一个sheet
            for index, row in info_df.iterrows():
                # 获取编号(用于sheet名称)
                sheet_name = clean_sheet_name(row.get('编号'))

                print(f"正在处理第 {index + 1}/{total_rows} 行: {sheet_name}")

                # 复制模板
                test_case_df = template_df.copy()

                # 5. 替换模板中的占位符
                for col in test_case_df.columns:
                    for idx in test_case_df.index:
                        cell_value = clean_value(test_case_df.loc[idx, col])

                        # 提取实际存在的占位符-- 非贪婪匹配,匹配 { 和 } 之间的所有内容
                        placeholders = re.findall(r'\{(.*?)\}', cell_value)

                        if placeholders:  # 只有存在占位符时才处理
                            for placeholder in set(placeholders):  # 去重
                                if placeholder in info_df.columns:
                                    replacement = clean_value(row.get(placeholder, ""))
                                    cell_value = cell_value.replace(f"{{{placeholder}}}", replacement)

                        test_case_df.loc[idx, col] = cell_value

                # 6. 将当前指示灯的测试用例保存到sheet
                test_case_df.to_excel(
                    writer,
                    sheet_name=sheet_name,
                    index=False
                )
                # 获取当前sheet的worksheet对象
                worksheet = writer.sheets[sheet_name]

                # 调用自动调整列宽函数
                auto_adjust_column_width(worksheet, test_case_df)

                print(f"  已自动调整 {sheet_name} 的列宽")

        print(f"Excel文件生成完成,共生成 {total_rows} 个测试用例")
        return total_rows

    except KeyError as e:
        raise Exception(f"Excel文件中缺少必要的列: {e}")
    except PermissionError as e:
        raise Exception(f"文件访问权限错误,请关闭Excel文件后重试: {e}")
    except Exception as e:
        raise Exception(f"文件处理错误: {e}")

5.2 panel.py

python 复制代码
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import os
from CaseOutput import generate_test_cases_from_files


class TestCaseGeneratorGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("测试用例生成器")
        self.root.geometry("650x350")

        # 初始化文件路径
        self.template_file = ""
        self.info_file = ""
        self.output_file = ""

        # 设置样式
        self.setup_styles()

        # 创建界面
        self.create_widgets()

    def setup_styles(self):
        """设置界面样式"""
        style = ttk.Style()
        style.theme_use('clam')

        # 自定义大按钮样式
        style.configure(
            'Large.TButton',
            font=('Microsoft YaHei', 11, 'bold'),
            padding=(10, 8),
            anchor='center',
            relief='raised',
            width=15
        )

        # 标签样式
        style.configure(
            'File.TLabel',
            font=('Microsoft YaHei', 10),
            padding=(5, 2)
        )

        # 标签框样式
        style.configure(
            'TLabelframe',
            font=('Microsoft YaHei', 11, 'bold'),
            padding=10
        )

    def create_widgets(self):
        """创建界面组件"""
        # 主容器
        main_container = ttk.Frame(self.root, padding=20)
        main_container.pack(fill='both', expand=True)

        # 标题
        title_label = tk.Label(
            main_container,
            text="测试用例生成工具",
            font=("Microsoft YaHei", 18, "bold"),
            fg="#2c3e50",
            bg="#ecf0f1",
            pady=15
        )
        title_label.pack(fill='x', pady=(0, 20))

        # 创建内容框架
        content_frame = ttk.Frame(main_container)
        content_frame.pack(fill='both', expand=True)

        # 文件选择区域
        self.create_file_selection(content_frame)

        # 按钮区域
        self.create_button_area(content_frame)

    def create_file_selection(self, parent):
        """创建文件选择区域"""
        # 模板文件选择区域
        template_frame = ttk.LabelFrame(parent, text="1. 选择模板文件")
        template_frame.pack(fill="x", padx=10, pady=10)

        template_inner = ttk.Frame(template_frame)
        template_inner.pack(fill='x', padx=5, pady=8)

        self.template_label = ttk.Label(
            template_inner,
            text="未选择文件",
            foreground="gray",
            style='File.TLabel',
            width=50,
            anchor='w'
        )
        self.template_label.pack(side="left", fill='x', expand=True, padx=(10, 5))

        template_btn = ttk.Button(
            template_inner,
            text="选择模板文件",
            command=self.select_template_file,
            style='Large.TButton'
        )
        template_btn.pack(side="right", padx=5)

        # 信息表文件选择区域
        info_frame = ttk.LabelFrame(parent, text="2. 选择信息表")
        info_frame.pack(fill="x", padx=10, pady=10)

        info_inner = ttk.Frame(info_frame)
        info_inner.pack(fill='x', padx=5, pady=8)

        self.info_label = ttk.Label(
            info_inner,
            text="未选择文件",
            foreground="gray",
            style='File.TLabel',
            width=50,
            anchor='w'
        )
        self.info_label.pack(side="left", fill='x', expand=True, padx=(10, 5))

        info_btn = ttk.Button(
            info_inner,
            text="选择信息表",
            command=self.select_info_file,
            style='Large.TButton'
        )
        info_btn.pack(side="right", padx=5)

        # 输出文件选择区域
        output_frame = ttk.LabelFrame(parent, text="3. 选择输出文件位置")
        output_frame.pack(fill="x", padx=10, pady=10)

        output_inner = ttk.Frame(output_frame)
        output_inner.pack(fill='x', padx=5, pady=8)

        self.output_label = ttk.Label(
            output_inner,
            text="未选择位置",
            foreground="gray",
            style='File.TLabel',
            width=50,
            anchor='w'
        )
        self.output_label.pack(side="left", fill='x', expand=True, padx=(10, 5))

        output_btn = ttk.Button(
            output_inner,
            text="选择输出位置",
            command=self.select_output_file,
            style='Large.TButton'
        )
        output_btn.pack(side="right", padx=5)

    def create_button_area(self, parent):
        """创建按钮区域"""
        button_frame = ttk.Frame(parent)
        button_frame.pack(pady=30)

        # 使用tk.Button获得更多控制
        self.generate_btn = tk.Button(
            button_frame,
            text="生成测试用例",
            font=('Microsoft YaHei', 12, 'bold'),
            command=self.generate_test_cases,
            state="disabled",
            bg="#27ae60",
            fg="white",
            activebackground="#229954",
            activeforeground="white",
            relief="raised",
            bd=2,
            padx=30,
            pady=12,
            cursor="hand2",
            width=15
        )
        self.generate_btn.pack(side="left", padx=20)

        self.clear_btn = tk.Button(
            button_frame,
            text="清空选择",
            font=('Microsoft YaHei', 12, 'bold'),
            command=self.clear_selection,
            bg="#e74c3c",
            fg="white",
            activebackground="#c0392b",
            activeforeground="white",
            relief="raised",
            bd=2,
            padx=30,
            pady=12,
            cursor="hand2",
            width=12
        )
        self.clear_btn.pack(side="left", padx=20)

    def select_template_file(self):
        """选择模板文件"""
        file_path = filedialog.askopenfilename(
            title="选择模板文件",
            filetypes=[("Excel文件", "*.xlsx *.xls"), ("所有文件", "*.*")]
        )
        if file_path:
            self.template_file = file_path
            file_name = os.path.basename(file_path)
            self.template_label.config(text=file_name, foreground="black")
            self.check_generate_button()

    def select_info_file(self):
        """选择信息表文件"""
        file_path = filedialog.askopenfilename(
            title="选择信息表",
            filetypes=[("Excel文件", "*.xlsx *.xls"), ("所有文件", "*.*")]
        )
        if file_path:
            self.info_file = file_path
            file_name = os.path.basename(file_path)
            self.info_label.config(text=file_name, foreground="black")
            self.check_generate_button()

    def select_output_file(self):
        """选择输出文件位置"""
        file_path = filedialog.asksaveasfilename(
            title="保存测试用例文件",
            defaultextension=".xlsx",
            filetypes=[("Excel文件", "*.xlsx"), ("所有文件", "*.*")]
        )
        if file_path:
            self.output_file = file_path
            file_name = os.path.basename(file_path)
            self.output_label.config(text=file_name, foreground="black")
            self.check_generate_button()

    def check_generate_button(self):
        """检查是否启用生成按钮"""
        if self.template_file and self.info_file and self.output_file:
            self.generate_btn.config(state="normal", bg="#27ae60")
        else:
            self.generate_btn.config(state="disabled", bg="#95a5a6")

    def clear_selection(self):
        """清空所有选择"""
        self.template_file = ""
        self.info_file = ""
        self.output_file = ""
        self.template_label.config(text="未选择文件", foreground="gray")
        self.info_label.config(text="未选择文件", foreground="gray")
        self.output_label.config(text="未选择位置", foreground="gray")
        self.generate_btn.config(state="disabled", bg="#95a5a6")

    def generate_test_cases(self):
        """生成测试用例"""
        try:
            # 检查文件是否存在
            if not os.path.exists(self.template_file):
                messagebox.showerror("错误", f"模板文件不存在: {self.template_file}")
                return

            if not os.path.exists(self.info_file):
                messagebox.showerror("错误", f"信息表文件不存在: {self.info_file}")
                return

            # 调用生成函数
            result = generate_test_cases_from_files(
                self.template_file,
                self.info_file,
                self.output_file
            )

            if result:
                messagebox.showinfo(
                    "生成成功",
                    f"测试用例生成成功!\n\n"
                    f"保存位置: {self.output_file}\n"
                    f"共生成 {result} 个测试用例"
                )
            else:
                messagebox.showerror("错误", "生成失败,请检查文件格式")

        except Exception as e:
            messagebox.showerror("错误", f"生成过程中发生错误:\n{str(e)}")


def main():
    root = tk.Tk()

    # 设置窗口居中
    window_width = 650
    window_height = 400
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
    x = (screen_width - window_width) // 2
    y = (screen_height - window_height) // 2
    root.geometry(f"{window_width}x{window_height}+{x}+{y}")

    # 创建应用
    app = TestCaseGeneratorGUI(root)

    # 运行主循环
    root.mainloop()


if __name__ == "__main__":
    main()

六、打包方法

1. 安装 PyInstaller

python 复制代码
pip install pyinstaller

2. 创建打包脚本

在项目根目录创建 build_exe.py

python 复制代码
# build_exe.py - 打包脚本
import PyInstaller.__main__
import os
import shutil
import sys

def build_executable():
    """构建可执行文件"""
    
    # 主程序入口文件
    main_script = "panel.py"  # 假设您的主程序是 panel.py
    
    # PyInstaller 配置参数
    args = [
        main_script,                # 主脚本
        '--name=TestCaseGenerator', # 程序名称
        '--onefile',                # 打包成单个exe文件
        '--windowed',               # 如果是GUI程序(控制台程序去掉这个)
        '--icon=icon.ico',         # 图标文件(可选)
        '--add-data=templates;templates',  # 包含模板文件夹
        '--add-data=*.xlsx;.',     # 包含Excel文件
        '--hidden-import=pandas',
        '--hidden-import=openpyxl',
        '--hidden-import=numpy',
        '--clean',                  # 清理临时文件
    ]
    
    # 运行打包
    PyInstaller.__main__.run(args)
    
    print("打包完成!可执行文件在 dist/TestCaseGenerator.exe")

if __name__ == "__main__":
    build_executable()

3. 简单打包命令

python 复制代码
# 1. 将panel.py修改为可执行入口(如果需要)
# 2. 执行打包命令
pyinstaller --onefile --name=TestTool panel.py
  1. 打包效果
相关推荐
Draina2 小时前
CBC填充预言攻击-CBC Padding Oracle Crypto Attack
python·安全·web安全·网络安全·密码学·安全性测试
Angel Q.2 小时前
特征提取 | DINO 到 DINOv3
图像处理·python
不如语冰3 小时前
AI大模型入门-pytorch-张量2 tensor创建
python
NPE~3 小时前
[AI]Agent开发——ADK框架使用
人工智能·python·ai·教程·adk·agent开发
矮个史蒂芬3 小时前
统计verilog .v文件中output 的bit数
python
gwf2163 小时前
磨损均衡算法(Wear Leveling)——SSD如何让每块闪存“公平退休“?
运维·数据库·人工智能·python·嵌入式硬件·算法·智能硬件
爱吃提升3 小时前
python 分布式爬虫、爬虫合规与综合实战项目
分布式·爬虫·python
审小匠OpenCPAi3 小时前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
元Y亨H5 小时前
Pandas 解析 Excel 导致的内存溢出(MemoryError)
python·excel
chouchuang5 小时前
day-040-Pandas可视化与实战
pandas