当前位置: 首页 > news >正文

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

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.hskmm.com/?act=detail&tid=13024

相关文章:

  • 297、瑶瑟怨
  • 极飞科技携手纷享销客CRM实现业务全链条数字化
  • 接私活神器!一个轻量级的 Java 快速开发平台!
  • 基于MATLAB的车辆二自由度悬架鲁棒控制
  • 微指令控制器的基本结构
  • AT_arc108_d [ARC108D] AB
  • 7-Zip 官方网站怎么下载?7zip和bandizip选哪个?选哪个?如何选择?
  • 2026 NOI 做题记录(三)
  • 第四届能源与动力工程国际学术会议(EPE 2025)
  • 第五届电子信息工程与计算机技术国际学术会议(EIECT 2025)
  • 2025年污染治理与可持续发展国际学术会议(PGSD 2025)
  • 抽象类和抽象方法
  • 深入解析:对比:ClickHouse/MySQL/Apache Doris
  • 实用指南:揭秘Pixie Dust攻击:利用路由器WPS漏洞离线破解PIN码接入无线网络
  • 权限修饰符
  • JDK 25 正式发布,长期支持
  • 2025 年(2026 届)计算机保研记录
  • 实用指南:RESTful API:@RequestParam与@PathVariable实战对比
  • 变分法和欧拉-拉格朗日方程 - Emi
  • AT_arc194_d [ARC194D] Reverse Brackets
  • 2025.9.22——1橙
  • huggingface.co 无法访问
  • 202403_QQ_brutezip
  • Day19回顾方法的调用
  • 「微积分 A1」极限与连续函数
  • PHP OOP 面向对象进阶 27 个问题让你充分了解对象特性
  • 202312_DASCTF_蚁剑流量
  • 网页开发入门:CSS与JS基础及BS/CS架构解析 - 实践
  • 实用指南:Vue开发准备
  • AppSpider 7.5.020 for Windows - Web 应用程序安全测试