python处理Excel的单机小工具:自动合并相同数据的行, 并同时计算其他列的加和

news/2025/9/22 9:32:44/文章来源:https://www.cnblogs.com/iLoveMyD/p/19104565

2025-09-22

场景: 一个表格, 比如有 序号, 姓名, 班级, 考分 几列, 要求:

1. 要按照班级合并, 相同的班级的行合并在一起

2. 序号这一列也同时合并

3. 合并后, 计算每个班级的总考分

原始表:

image 

处理后的表:

 

image

 

 软件交互:

1: 选择原始文件, sheet, 以及需要合并的列名

image

 

2. 选择其他要一起合并的列名, (可选项, 可以多选)

image

 

3. 选择需要求和的列名 (可选项, 可多选)

image

 

 4. 小工具只在本地运行, 不会上传数据, 有需要可加QQ群: 748194967 群名称: Excel便捷小工具.  也可以在评论区留言, 说出你想要的小工具需求. 

 5. 源代码

  1 # 合并某一列的某几行
  2 # 支持同时合并其他列的对应行
  3 import os
  4 import sys
  5 import shutil
  6 import tkinter as tk
  7 from tkinter import filedialog, messagebox, scrolledtext
  8 
  9 import openpyxl
 10 from openpyxl import load_workbook
 11 
 12 from utils import select_file, read_excel, tool, log, alert,style,org,ward_map
 13 
 14 excel = False
 15 selected = False
 16 merge_index = False
 17 
 18 #选择文件路径的公共方法
 19 def open_file_dialog():
 20     # 打开文件选择对话框
 21     file_path = select_file.excel_one("选择系数分报表文件", False)
 22     if file_path:
 23         append_text(f"选择文件:{file_path}")
 24         merge_file_path = file_path + '-合并结果.xlsx'
 25         if os.path.exists(merge_file_path):
 26             os.remove(merge_file_path)
 27         shutil.copy(file_path, merge_file_path) # 复制一份
 28         read_file_data(merge_file_path)
 29     else:
 30         return
 31 
 32 def read_file_data(file_path):
 33     append_text(f"读取数据")
 34     global excel
 35     global selected
 36     global merge_index
 37 
 38     excel = read_excel.ExcelTool(file_path).excel
 39     excel.all_data()
 40     append_text(f"选择sheet: {excel.sheet_name}")
 41     
 42     selected = select_file.radio(excel.title, "1.选择要合并的列, 单选")
 43     label11.config(text=selected)
 44     idx = excel.title_flip[selected]  
 45     col = tool.num_to_excel_col(idx+1)
 46     merge_index = tool.same_content_index(excel.file_data, idx)
 47     append_text(f"合并的行: {str(merge_index)}")
 48     for v in merge_index:
 49         start = v[0]
 50         end = v[1]
 51         if start < end:
 52             excel.sheet.merge_cells(f"{col}{start}:{col}{end}")
 53 
 54 def select_merge_cols():
 55     global excel
 56     global selected
 57     global merge_index
 58 
 59     other_cols = select_file.checkbox(excel.title, "2.请选择其他需要一起合并的列, 多选")
 60     if other_cols and len(other_cols) > 0:
 61         str_cols = ', '.join(other_cols)
 62         label32.config(text=str_cols)
 63 
 64         for col in other_cols:
 65             if col == selected:
 66                 continue
 67             idx = excel.title_flip[col] + 1
 68             col_num = tool.num_to_excel_col(idx)
 69             #print([col, idx, col_num])
 70             for v in merge_index:
 71                 start = v[0]
 72                 end = v[1]
 73                 if start < end:
 74                     excel.sheet.merge_cells(f"{col_num}{start}:{col_num}{end}")
 75 
 76 
 77 def select_sum_cols():
 78     global excel
 79     global merge_index
 80     global selected
 81 
 82     sum_cols = select_file.checkbox(excel.title, "3.请选择需要求和的列, 多选")
 83     if sum_cols and len(sum_cols) > 0:
 84         str_sum_cols = ', '.join(sum_cols)
 85         label42.config(text=str_sum_cols)
 86 
 87         max_col = excel.sheet.max_column
 88         for col in sum_cols:
 89             if col == selected:
 90                 continue
 91             #新加一列用于存放加和后的值
 92             max_col += 1
 93             max_col_num = tool.num_to_excel_col(max_col)
 94             excel.sheet.insert_cols(idx=max_col)
 95             #sheet.cell(row=1, column=max_col, value=f"{col}(合计)")
 96 
 97             #读取待加和的列值
 98             idx = excel.title_flip[col] + 1
 99             col_num = tool.num_to_excel_col(idx)
100             col_data = excel.sheet[col_num]
101             for v in merge_index: 
102                 start = v[0]
103                 end = v[1]
104                 if start == end: #单行,不需要合并,直接讲数值写到新列
105                     excel.sheet.cell(row=start,column=max_col, value=col_data[start-1].value)
106                 else:
107                     sum_value = 0
108                     for i in range(start, end+1):
109                         sum_value += col_data[i-1].value
110                     excel.sheet.cell(row=start,column=max_col, value=sum_value)
111                     excel.sheet.merge_cells(f"{max_col_num}{start}:{max_col_num}{end}")
112 
113 
114 def button_ok():
115     global excel
116     excel.wb.save(excel.file_path)
117     tool.open_excel(excel.file_path)
118 
119 def button_cancel():
120     sys.exit()
121 
122 def append_text(str):
123     str += "\n\n"
124     text_area.insert(tk.END, str)
125 
126 #######################################主窗口
127 # 创建主窗口
128 root = tk.Tk()
129 root.title("合并行")
130 root.geometry("650x400")  # 设置窗口大小
131 
132 ########################################选择文件
133 frame1 = tk.Frame(root)
134 frame1.pack(anchor=tk.W)
135 
136 # 创建一个标签
137 label1 = tk.Label(frame1, text="基础信息表:")
138 label1.pack(side=tk.LEFT, padx=10, pady=10)
139 
140 # 创建一个按钮
141 button1 = tk.Button(frame1, text="选择文件", command=open_file_dialog)
142 button1.pack(side=tk.LEFT, pady=10)
143 
144 label11 = tk.Label(frame1, text="单选")
145 label11.pack(side=tk.LEFT, pady=10)
146 
147 ########################################选择按钮
148 frame3 = tk.Frame(root)
149 frame3.pack(anchor=tk.W)
150 
151 # 创建一个按钮
152 button31 = tk.Button(frame3, text="选择要同时合并的列", command=select_merge_cols)
153 button31.pack(side=tk.LEFT, padx=10, pady=10)
154 
155 label32 = tk.Label(frame3, text="非必须, 多选")
156 label32.pack(side=tk.LEFT, pady=10)
157 
158 ########################################选择按钮
159 frame4 = tk.Frame(root)
160 frame4.pack(anchor=tk.W)
161 
162 
163 # 创建一个按钮
164 button41 = tk.Button(frame4, text="选择要同时合并求和的列", command=select_sum_cols)
165 button41.pack(side=tk.LEFT, padx=10, pady=10)
166 
167 label42 = tk.Label(frame4, text="非必须, 多选")
168 label42.pack(side=tk.LEFT, pady=10)
169 
170 
171 ########################################选择文件
172 frame2 = tk.Frame(root)
173 frame2.pack(expand=True, fill=tk.X)
174 
175 # 创建一个按钮
176 button21 = tk.Button(frame2, text="确认", command=lambda:button_ok())
177 button21.pack(side=tk.LEFT, expand=True)
178 
179 # 创建一个按钮
180 button22 = tk.Button(frame2, text="退出", command=lambda:button_cancel())
181 button22.pack(side=tk.LEFT, expand=True)
182 
183 
184 ########################################检查过程
185 # 创建一个可滚动的 Text 小部件
186 text_area = scrolledtext.ScrolledText(root, wrap=tk.WORD, width=40, height=60)
187 text_area.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)
188 text_area.insert(tk.END, "提醒: \n\n")
189 
190 # 运行应用程序
191 root.mainloop()
View Code

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/909218.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

297、瑶瑟怨

297、瑶瑟怨 297、瑶瑟怨 唐●温庭筠 冰簟银床梦不成,碧天如水夜云轻。 雁声远过潇湘去,十二楼中月自明。【现代诗意译】 月光下 铺着清凉竹席的床上 我难以入眠 团圆美梦也做不成了 天空碧蓝如水 飘着几片薄薄夜云一…

极飞科技携手纷享销客CRM实现业务全链条数字化

极飞科技股份有限公司(以下简称“极飞科技”)是全球领先的农业机器人公司,致力于用机器人、人工智能和新能源技术赋能农业。随着业务持续拓展与战略升级,极飞客户面临线索管理分散、多系统数据孤岛等挑战。为进一步…

接私活神器!一个轻量级的 Java 快速开发平台!

X-SpringBoot —— 一个轻量级的 Java 快速开发平台,用于快速构建中小型 API、RESTful API 项目,代码简洁,架构清晰,能快速开发项目并交付(接私活神器)。大家好,我是 Java陈序员。 在日常开发中,无论是企业内部…

第四届能源与动力工程国际学术会议(EPE 2025)

第四届能源与动力工程国际学术会议(EPE 2025) 2025 4th International Conference on Energy and Power Engineering 由大连理工大学主办、中国科学报社支持的第四届能源与动力工程国际学术会议(EPE 2025)将于2025…

第五届电子信息工程与计算机技术国际学术会议(EIECT 2025)

第五届电子信息工程与计算机技术国际学术会议(EIECT 2025) 2025 5th International Conference on Electronic Information Engineering and Computer Technology 随着科学技术的高速发展,计算机技术革新日新月异,…

2025年污染治理与可持续发展国际学术会议(PGSD 2025)

2025年污染治理与可持续发展国际学术会议(PGSD 2025) 2025 International Conference on Pollution Governance and Sustainable Development 由马来西亚理工大学主办的2025年污染治理与可持续发展国际学术会议(PGS…

深入解析:对比:ClickHouse/MySQL/Apache Doris

深入解析:对比:ClickHouse/MySQL/Apache Dorispre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", …

实用指南:揭秘Pixie Dust攻击:利用路由器WPS漏洞离线破解PIN码接入无线网络

实用指南:揭秘Pixie Dust攻击:利用路由器WPS漏洞离线破解PIN码接入无线网络pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-fam…

深入解析:2025-09-05 CSS3——盒子模型

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

JDK 25 正式发布,长期支持

JDK 25 是 LTS(长期支持版),至此为止,有 JDK8、JDK11、JDK17、JDK21 和 JDK 25 这四个长期支持版了。 JDK 25 共有 18 个新特性,这篇文章会挑选其中较为重要的一些新特性进行详细介绍 语言特性 基本类型模式匹配(…

2025 年(2026 届)计算机保研记录

925 后发布。经验分享篇。 在写了,925 后发布。作者@Luckyblock,转载请声明出处。

linux驱动制作

linux驱动制作2025-09-22 08:59 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family:…

实用指南:RESTful API:@RequestParam与@PathVariable实战对比

实用指南:RESTful API:@RequestParam与@PathVariable实战对比pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Co…

Android普通应用切到后台后,多长时间会被系统回收 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

变分法和欧拉-拉格朗日方程 - Emi

基本概念函数(function):函数是一种映射,输入一个数,输出一个数。 泛函(functional):泛函也是一种映射,输入一个函数,输出一个数。故我们可以说泛函是函数的函数。 微分(derivation):微分是函数的”输入和…

【Android】View 的滑动 - 实践

【Android】View 的滑动 - 实践2025-09-22 08:49 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !importa…

AT_arc194_d [ARC194D] Reverse Brackets

考虑将包含关系建出一棵树,那么答案相当于你可以重排儿子,相同大小儿子不区分,问能得到多少种树的形态。 简单用树哈希做就好了。

2025.9.22——1橙

普及- P10376 [GESP202403 六级] 游戏 很简单的DP,但要注意数组偏移,把负数也存进去。

huggingface.co 无法访问

Ping查询结果: huggingface.co 查询时间:2025-09-22 08:46:27

202403_QQ_brutezip

流量分析,文件分离,ZIP文件,掩码爆破Tags:流量分析,文件分离,ZIP,掩码爆破 0x00. 题目 题目表述 附件路径:https://pan.baidu.com/s/1GyH7kitkMYywGC9YJeQLJA?pwd=Zmxh#list/path=/CTF附件 附件名称:202403_QQ_brut…