首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >python-tkinter:拆分excel文件

python-tkinter:拆分excel文件

原创
作者头像
极致python
发布2025-03-24 18:20:55
发布2025-03-24 18:20:55
9400
举报

利用python、tkinter开发、打包成单机版exe软件工具,可以在本地电脑打开软件对Excel(xlsx、csv)的文件,按照给定行数进行拆分。

一、工具介绍

1、工具界面

图片
图片

2、使用说明:

2.1 检测文件模块

① 拆分文件:点击该按钮,读取Excel文件,获取Excel存放路径;

② 文件编码: 用于拆分csv文件,指定的文件编码,对Excel无作用;

③ 预览数据:点击该按钮,用于检测是否可以正常读取数据、并且读取到的数据,是否有乱码;

2.2 拆分文件模块:

① 拆分行数:拆分后每个文件是多少行,例如按照每 10000行拆分为一个文件;

② 保存文件夹:点击该按钮,读取保存拆分文件的文件夹;

③ 执行拆分文件:用于执行拆分文件程序

2.3 数据处理信息窗口

图片
图片

二、下载链接:

链接: https://pan.baidu.com/s/1FvY7ZjaBjdI-2WMKzo0Krw 提取码: 6666

三、代码:

链接: https://pan.baidu.com/s/1hWjX2eQrxHICNLHZGAUkOA 提取码: 8888

代码语言:javascript
复制
from tkinter import *
import tkinter.ttk as ttk
from tkinter.filedialog import *
from tkinter import messagebox
import pandas as pd
import time
import os
import math

#读取拆分文件,获取文件路径
def openFile():
    global dir_filename, mer_df_col_cnt
    filepath = askopenfilename()  # 选择打开什么文件,返回文件名
    if filepath.strip() != '':
        select_filename.set(filepath)  # 设置变量filename的值
        dir_filename = select_filename.get()
        in_file_entry.configure(fg='black')
    else:
        select_filename.set("没有选择文件")
        dir_filename = select_filename.get()
        in_file_entry.configure(fg='red')

#创建一个弹窗,显示excel文件是否有乱码
def create_excel_popup(dir_filename, encoding_type):
    #创建一个顶级窗口
    popup = Toplevel(root)
    popup.title("Excel数据预览")
    popup.geometry("900x260+200+200")
    suffix_type = dir_filename.split(".")[-1]
    try:
        if suffix_type == "xlsx":
            df_temp = pd.read_excel(dir_filename, nrows=10)
        elif suffix_type == "csv":
            df_temp = pd.read_csv(dir_filename, nrows=10, encoding=encoding_type)

        # 创建一个Treeview控件
        tree = ttk.Treeview(popup)
        xscroll = Scrollbar(popup, orient=HORIZONTAL)  # 添加滑动块
        yscroll = Scrollbar(popup, orient=VERTICAL)
        xscroll.config(command=tree.xview)
        xscroll.pack(side=BOTTOM, fill=X)
        yscroll.config(command=tree.yview)
        yscroll.pack(side=RIGHT, fill=Y)
        tree['show'] = "headings"
        tree.pack(fill='both', expand=True)  # 让Treeview填充整个窗口空间

        # 设置列标题(需要手动设置每一列)
        tree['columns'] = list(df_temp.columns)  # 获取列名作为列标题列表
        for col in df_temp.columns:
            tree.heading(col, text=col)  # 设置列标题文本和列ID相同,即列名本身。
            tree.column(col, width=100, anchor='center')  # 设置列宽和居中对齐方式。可以根据需要调整。

        # 插入数据行(手动插入每一行)
        for index, row in df_temp.iterrows():
            tree.insert('', 'end', values=list(row))
    except:
        print("出问题")
        label = Label(popup,
                      text="可能出现以下问题:\n 1、可能选择文件:只支持xlsx、csv格式的文件;\n 2、文件编码选错:请在下拉框中选择其他的文件编码,默认为gb18030",
                      font=("黑体", 12),  justify=LEFT, anchor="w")
        label.pack()


#输出文件夹路径
def openDir():
    global dir_route
    fileDir = askdirectory()  # 选择目录,返回目录名
    if fileDir.strip() != '':
        out_file_filename.set(fileDir)  # 设置变量outputpath的值
        dir_route = out_file_filename.get()
        out_file_entry.configure(fg='black')
    else:
        out_file_filename.set("没有选择保存拆分数据的文件夹")
        dir_route = out_file_filename.get()
        out_file_entry.configure(fg='red')

#判断是否数字
def is_number(s):
    try:
        float(s)
        return True
    except:
        return False

#拆分文件
def excel_split_func():
    col_cnt = col_cnt_Var.get()
    encode_type = file_encode_combobox.get()
    file_name = (os.path.split(dir_filename)[1]).split('.')[-2]
    if is_number(col_cnt):
        col_cnt_s = int(col_cnt)
        if col_cnt_s > 0:
            try:
                suffix_type = dir_filename.split(".")[-1]
                if suffix_type == "xlsx":
                    mer_df = pd.read_excel(dir_filename)
                    mer_df_col_cnt = mer_df.shape[0]
                    all_file_cnt = math.ceil(mer_df_col_cnt / col_cnt_s)
                    result_msg_text.delete('1.0', END)
                    begin_time = time.time()
                    result_msg_text.insert(INSERT, "-----------开始拆分Excel文件-----------\n")
                    param_str = "拆分的Excel文件行数为:" + str(mer_df_col_cnt) + "\n" + "每" + str(
                        col_cnt_s) + "行拆分为一个Excel文件\n"
                    result_msg_text.insert(INSERT, param_str)
                    result_msg_text.update()
                    result_msg_text.see("end")
                    i = 1

                    for r_cnt in range(all_file_cnt):
                        df_temp = mer_df.iloc[r_cnt * col_cnt_s:(r_cnt+1)*col_cnt_s, :]

                        param_str = "\n" + str(i) + "、" + "共拆分为" + str(all_file_cnt) + "个文件, 正在拆分第" + str(
                            i) + "个文件,"
                        result_msg_text.insert(INSERT, param_str)
                        result_msg_text.update()
                        result_msg_text.see("end")
                        df_temp.to_excel(dir_route + "/" + file_name + "_part" + str(i) + ".xlsx", index=False)
                        # mer_df_chunk.to_csv(dir_route+"/" + file_name + "_part" + str(i) + ".csv", index=False)

                        end_time = time.time()

                        param_str = "\n\t完成拆分, 已用时(分):" + str(round((end_time - begin_time) / 60, 2))
                        result_msg_text.insert(INSERT, param_str)
                        result_msg_text.update()
                        result_msg_text.see("end")
                        i = i + 1
                elif suffix_type == "csv":
                    mer_df_chunks0 = pd.read_csv(dir_filename, encoding=encode_type, chunksize=100000)
                    mer_df_col_cnt = 0
                    for mer_df_chunk in mer_df_chunks0:
                        mer_df_col_cnt = mer_df_col_cnt + mer_df_chunk.shape[0]
                    mer_df_chunks = pd.read_csv(dir_filename, encoding=encode_type, chunksize=col_cnt_s, low_memory=False)

                    all_file_cnt = math.ceil(mer_df_col_cnt/col_cnt_s)
                    result_msg_text.delete('1.0', END)
                    begin_time = time.time()
                    result_msg_text.insert(INSERT, "-----------开始拆分Excel文件-----------\n")
                    param_str = "拆分的Excel文件行数为:" + str(mer_df_col_cnt) + "\n" + "每" + str(col_cnt_s) + "行拆分为一个Excel文件\n"
                    result_msg_text.insert(INSERT, param_str)
                    result_msg_text.update()
                    result_msg_text.see("end")
                    i = 1
                    for mer_df_chunk in mer_df_chunks:
                        param_str = "\n" + str(i) + "、" + "共拆分为" + str(all_file_cnt) + "个文件, 正在拆分第" + str(
                            i) + "个文件,"
                        result_msg_text.insert(INSERT, param_str)
                        result_msg_text.update()
                        result_msg_text.see("end")
                        mer_df_chunk.to_excel(dir_route+"/" + file_name + "_part" + str(i) + ".xlsx", index=False)
                        # mer_df_chunk.to_csv(dir_route+"/" + file_name + "_part" + str(i) + ".csv", index=False)

                        end_time = time.time()

                        param_str =  "\n\t完成拆分, 已用时(分):" + str(round((end_time - begin_time) / 60, 2))
                        result_msg_text.insert(INSERT, param_str)
                        result_msg_text.update()
                        result_msg_text.see("end")
                        i = i + 1
                param_str = "\n\n--拆分已全部完成--"
                result_msg_text.insert(INSERT, param_str)
                result_msg_text.update()
                result_msg_text.see("end")
            except:
                messagebox.showinfo("提示", "拆分Excel文件出错")
                raise
        else:
            messagebox.showinfo("提示", "拆分行数<=0,请输入>0的数值")
    else:
        messagebox.showinfo("提示", "拆分行数,非数值,请输入数值")

if __name__ == '__main__':
    root = Tk()
    root.title("Excel文件拆分(包含xlsx/csv)")
    root.geometry("450x560+200+100")
    root.resizable(False, False)
    # ------------------------------------------
    # 2个模块,文件拆分模块、处理信息模块
    # 第一层:frame 容器
    file_frame = Frame(root, background="white")
    file_frame.place(width=450, height=150, x=0, y=0)

    split_frame = Frame(root, background="white")
    split_frame.place(width=450, height=150, x=0, y=150)

    msg_frame = Frame(root, background="white")
    msg_frame.place(width=450, height=260, x=0, y=300)
    # 1、检测文件
    label_file1 = Label(file_frame, text="1、检测文件", font=("黑体", 10, "bold"), background="#00b9f1",
                       fg="white", anchor="w")
    label_file1.place(x=0, y=0, width=230, height=30)

    in_btn_file = Button(file_frame, command=openFile, text="拆分文件", font=("黑体", 9), relief="raised")
    in_btn_file.place(x=10, y=35, width=85, height=30)
    select_filename = StringVar()
    in_file_entry = Entry(file_frame, textvariable=select_filename, relief="flat", font=("黑体", 9))
    in_file_entry.configure(highlightthickness=1, highlightbackground="#C0C0C0")
    in_file_entry.place(x=100, y=35, width=325, height=28)

    in_btn_file_encode = Label(file_frame, text="文件编码", font=("黑体", 9), bg="white")
    in_btn_file_encode.place(x=10, y=72, width=85, height=30)
    file_encode_var = StringVar()
    file_encode_combobox = ttk.Combobox(file_frame, textvariable=file_encode_var, value=('gb18030', 'utf-8', 'utf-8-sig'))
    file_encode_combobox.current(0)
    file_encode_combobox.place(x=100, y=72, width=325, height=28)

    #创建一个按钮,打开excel数据预览窗口
    excel_popup_bt = Button(file_frame, text = "预览数据", command=lambda: create_excel_popup(dir_filename, file_encode_combobox.get()))
    excel_popup_bt.place(x=10, y = 107, width=85, height=28)

    #2、文件拆分
    label_file2 = Label(split_frame, text="2、拆分文件", font=("黑体", 10, "bold"), background="#00b9f1",
                       fg="white", anchor="w")
    label_file2.place(x=0, y=0, width=230, height=30)

    label_col_cnt = Label(split_frame, text="拆分行数", font=("黑体", 9), background="white")
    label_col_cnt.place(x=10, y=35, width=85, height=30)
    col_cnt_Var = StringVar()
    col_cnt_entry = Entry(split_frame, textvariable=col_cnt_Var, relief="flat", font=("黑体", 9))
    col_cnt_entry.configure(highlightthickness=1, highlightbackground="#C0C0C0")
    col_cnt_entry.place(x=100, y=35, width=325, height=28)

    out_btn_file = Button(split_frame, command=openDir, text="保存文件夹", font=("黑体", 9), relief="raised")
    out_btn_file.place(x=10, y=72, width=85, height=30)
    out_file_filename = StringVar()
    out_file_entry = Entry(split_frame, textvariable=out_file_filename, relief="flat", font=("黑体", 9))
    out_file_entry.configure(highlightthickness=1, highlightbackground="#C0C0C0")
    out_file_entry.place(x=100, y=72, width=325, height=28)
    # 执行拆分按钮
    btn_split = Button(split_frame, text="执行拆分数据", command=excel_split_func, font=("黑体", 9), relief="raised")
    btn_split.place(x=10, y=110, width=110, height=30)
    #3、显示处理信息模块
    label_msg = Label(msg_frame, text="3、数据处理信息窗口", font=("黑体", 10, "bold"), background="#00b9f1",
                      fg="white", anchor="w")
    label_msg.place(x=0, y=0, width=230, height=30)

    result_msg_text = Text(msg_frame, relief="flat", font=("黑体", 9))  # 处理结果展示
    result_msg_text.place(x=10, y=35, width=415, height=200)
    result_msg_text.configure(highlightthickness=1, highlightbackground="#C0C0C0")
    yscrollbar = Scrollbar(result_msg_text)
    yscrollbar.pack(side=RIGHT, fill=Y)
    yscrollbar.config(command=result_msg_text.yview)
    result_msg_text.config(yscrollcommand=yscrollbar.set)
    # ------------------------------------------
    root.mainloop()

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档