自用EXCEL拆分工具

查看 151|回复 11
作者:宋长雨   
公司有个对比数据的文档,要拆分很多单位,背对背发送,每次要浪费很多时间。
闲来无事,开发代码不太会,用AI训练了很久才训练好。
只是一个简单的excel拆分软件,是一次性把excel中所有的sheet都拆分,并且按照列分组进行命名,保持原始数据的格式,这样就不用再拆分后进行格式调整了,而且会保留所有sheet,这个是我的需求,你们有没有这个需求就不清楚了。
因为我这边的需求是差不多的,用索引比较方便,都在第一列或者第几列,而且列名可能不一样,所以我选择用索引。
不要要求我添加功能,我也不会,大家用的到就帮忙点点热心。
打完包很大,不会弄。哈哈哈。。
下面是示例:


1.png (54.87 KB, 下载次数: 0)
下载附件
2024-6-13 16:07 上传



2.png (63.28 KB, 下载次数: 0)
下载附件
2024-6-13 16:07 上传

工具界面:


界面.png (36 KB, 下载次数: 0)
下载附件
2024-6-13 16:07 上传



界面3.png (48.81 KB, 下载次数: 0)
下载附件
2024-6-13 16:07 上传

拆分后:


界面4.png (50.47 KB, 下载次数: 0)
下载附件
2024-6-13 16:08 上传

数据类型都保留了,而且背景颜色也保留了,而且按照切分的列分组进行命名


界面5.png (32.1 KB, 下载次数: 0)
下载附件
2024-6-13 16:08 上传

百度网盘:https://pan.baidu.com/s/1mKjPSvkxrNr2ddVyxQ_UHA?pwd=52pj 提取码: 52pj

下载次数, 下载附件

宋长雨
OP
  


nuxingxp 发表于 2024-6-13 21:28
有码吗?可以分享下吗

有的,出了bug自己调,我不太会。优化好了可以发出来,大家一块用
[Asm] 纯文本查看 复制代码import tkinter as tk
from tkinter import filedialog, messagebox
import os
import threading
from openpyxl import load_workbook, Workbook
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
def collect_data_and_style(sheet, key_column_index=0):
    """收集单个工作表的数据及其样式信息,包括列头,现在可以指定分组列,并处理百分比格式"""
    groups = {}
    header_info = []
    for row in sheet.iter_rows(min_row=1):
        if row[0].row == 1:
            header_info = [(cell.value, {
                'font': Font(name=cell.font.name, sz=cell.font.sz, b=cell.font.b, i=cell.font.i,
                             u=cell.font.u, strike=cell.font.strike, color=cell.font.color),
                'alignment': Alignment(horizontal=cell.alignment.horizontal, vertical=cell.alignment.vertical,
                                       wrapText=cell.alignment.wrapText, shrinkToFit=cell.alignment.shrinkToFit),
                'fill': PatternFill(fill_type=cell.fill.fill_type, start_color=cell.fill.start_color,
                                    end_color=cell.fill.end_color, patternType=cell.fill.patternType),
                'border': Border(left=Side(border_style=cell.border.left.border_style, color=cell.border.left.color),
                                 right=Side(border_style=cell.border.right.border_style, color=cell.border.right.color),
                                 top=Side(border_style=cell.border.top.border_style, color=cell.border.top.color),
                                 bottom=Side(border_style=cell.border.bottom.border_style,
                                             color=cell.border.bottom.color)),
                'number_format': cell.number_format,  # 添加这一行来收集单元格的数字格式
            }) for cell in row]
            continue
        group_key = str(row[key_column_index].value)
        if group_key not in groups:
            groups[group_key] = []
        row_data = [(cell.value, {
            'font': Font(name=cell.font.name, sz=cell.font.sz, b=cell.font.b, i=cell.font.i,
                         u=cell.font.u, strike=cell.font.strike, color=cell.font.color),
            'alignment': Alignment(horizontal=cell.alignment.horizontal, vertical=cell.alignment.vertical,
                                   wrapText=cell.alignment.wrapText, shrinkToFit=cell.alignment.shrinkToFit),
            'fill': PatternFill(fill_type=cell.fill.fill_type, start_color=cell.fill.start_color,
                                end_color=cell.fill.end_color, patternType=cell.fill.patternType),
            'border': Border(left=Side(border_style=cell.border.left.border_style, color=cell.border.left.color),
                             right=Side(border_style=cell.border.right.border_style, color=cell.border.right.color),
                             top=Side(border_style=cell.border.top.border_style, color=cell.border.top.color),
                             bottom=Side(border_style=cell.border.bottom.border_style, color=cell.border.bottom.color)),
            'number_format': cell.number_format,  # 同样收集每个单元格的数字格式
        }) for cell in row]
        groups[group_key].append(row_data)
    for group_data in groups.values():
        group_data.insert(0, header_info)
    return groups
def create_merged_excel(output_path, grouped_data):
    output_wb = Workbook()
    for sheet_name, sheet_data in grouped_data.items():
        ws = output_wb.create_sheet(title=sheet_name)
        for row_index, row_data_with_styles in enumerate(sheet_data, start=1):
            for col_index, (value, style_info) in enumerate(row_data_with_styles, start=1):
                new_cell = ws.cell(row=row_index, column=col_index, value=value)
                if style_info:
                    new_cell.font = style_info.get('font', None)
                    new_cell.alignment = style_info.get('alignment', None)
                    new_cell.fill = style_info.get('fill', None)
                    new_cell.border = style_info.get('border', None)
                    number_format = style_info.get('number_format', '')
                    if '%)' in number_format:
                        new_cell.value *= 100
                        new_cell.number_format = number_format.replace('0', '0%')
                    else:
                        new_cell.number_format = number_format
    # 删除默认的Sheet,如果有的话
    default_sheet_name = "Sheet"
    if default_sheet_name in output_wb.sheetnames:
        del output_wb[default_sheet_name]
    output_wb.save(output_path)
    output_wb.close()
def extract_and_merge_sheets(input_file, output_directory, key_column_index=0):
    """主函数,负责遍历输入文件的所有工作表,收集数据并创建合并的Excel文件,处理百分比等格式问题"""
    wb = load_workbook(input_file, read_only=True)
    all_groups_data = {}
    for sheet in wb:
        sheet_groups = collect_data_and_style(sheet, key_column_index=key_column_index)
        for group_key, group_data in sheet_groups.items():
            if group_key not in all_groups_data:
                all_groups_data[group_key] = {}
            all_groups_data[group_key][sheet.title] = group_data
    os.makedirs(output_directory, exist_ok=True)
    for group, sheets_data in all_groups_data.items():
        if sheets_data:
            output_path = os.path.join(output_directory, f"{group}.xlsx")
            create_merged_excel(output_path, {sheet_name: data for sheet_name, data in sheets_data.items() if data})
def select_input_file(entry_widget):
    filepath = filedialog.askopenfilename()
    entry_widget.delete(0, tk.END)
    entry_widget.insert(0, filepath)
def select_output_directory(entry_widget):
    directory = filedialog.askdirectory()
    entry_widget.delete(0, tk.END)
    entry_widget.insert(0, directory)
def process_in_background(input_path, output_directory, column_index, submit_button):
    try:
        submit_button.config(state=tk.DISABLED, bg="#FF0000")
        extract_and_merge_sheets(input_path, output_directory, column_index)
        submit_button.config(state=tk.NORMAL, bg="#4CAF50")
        messagebox.showinfo("完成", "处理结束。")
    except ValueError:
        submit_button.config(state=tk.NORMAL, bg="#4CAF50")
        messagebox.showerror("错误", "列索引必须是整数。")
    except Exception as e:
        submit_button.config(state=tk.NORMAL, bg="#4CAF50")
        messagebox.showerror("错误", f"处理过程中发生错误: {str(e)}")
def submit(input_var, output_var, column_var, submit_button):
    input_path = input_var.get()
    output_directory = output_var.get()
    try:
        column_index = int(column_var.get())
        thread = threading.Thread(target=process_in_background, args=(input_path, output_directory, column_index, submit_button))
        thread.start()
    except ValueError:
        messagebox.showerror("错误", "列索引必须是整数。")
def setup_gui():
    global root
    root = tk.Tk()
    root.title("Excel拆分工具")
    root.geometry("350x500")
    root.configure(bg="#F0F0F0")
    root.resizable(True, True)
    tk.Label(root, text="选择输入文件:", font=("Arial", 12), bg="#F0F0F0").pack(pady=20)
    input_entry = tk.Entry(root, font=("Arial", 12), relief=tk.FLAT, bg="white")
    input_entry.pack(ipady=4, pady=10, padx=10)
    tk.Button(root, text="浏览", command=lambda: select_input_file(input_entry), font=("Arial", 12), bg="#4CAF50", fg="white", activebackground="#45a049", relief=tk.FLAT, cursor="hand2").pack(pady=5, padx=10)
    tk.Label(root, text="选择输出目录:", font=("Arial", 12), bg="#F0F0F0").pack(pady=20)
    output_entry = tk.Entry(root, font=("Arial", 12), relief=tk.FLAT, bg="white")
    output_entry.pack(ipady=4, pady=10, padx=10)
    tk.Button(root, text="浏览", command=lambda: select_output_directory(output_entry), font=("Arial", 12), bg="#4CAF50", fg="white", activebackground="#45a049", relief=tk.FLAT, cursor="hand2").pack(pady=5, padx=10)
    tk.Label(root, text="输入列索引:", font=("Arial", 12), bg="#F0F0F0").pack(pady=20)
    column_entry = tk.Entry(root, font=("Arial", 12), relief=tk.FLAT, bg="white")
    column_entry.pack(ipady=4, pady=10, padx=10)
    submit_button = tk.Button(root, text="开始处理", command=lambda: submit(input_entry, output_entry, column_entry, submit_button),
                              font=("Arial", 12), bg="#4CAF50", fg="white", activebackground="#45a049", relief=tk.FLAT, cursor="hand2")
    submit_button.pack(pady=20, padx=10)
    root.mainloop()
if __name__ == "__main__":
    setup_gui()
宋长雨
OP
  


nojon 发表于 2024-6-13 18:13
谢谢分享,方方格子也有,但不知是否适合你

方方格子还有kutools都用过,不好使,方方格子几乎不能使,需要很多步骤,还不能保留格式,背景啥的。kutools能用,但是也需要很多步骤才能达到目的。我有8个sheet,27家单位,好几百个临时文件来回折腾,得用20多分钟,还得来回改名排序,太麻烦了
52soft   

这个工具不错
ok667   

很实用的工具
superjason   

请问用什么工具开发的啊
nojon   

谢谢分享,方方格子也有,但不知是否适合你
w-c-f5522   

很不错 , 感谢楼主的分享
mygame361   

请问用 用AI训练 是怎么个训练? 我都是自己写一遍遍的改VBA代码才实现拆分合并啥的
kisa   

看着不赖啊
您需要登录后才可以回帖 登录 | 立即注册

返回顶部