背景需求:
2024年9月第一学期给每个班级都做了一份“节假日是灰色”的点名册,广受好评——“这样很清楚,没有双休日,就不会像以前那样,很容易填错格子。”
现在是2025年2月第二学期,我只需要从原来已经生成的第一学期的灰色点名册里提取上学期幼儿的名单。
但是有孩子转入转出,下学期的名单肯定不一样了。
(o(╥﹏╥)o,转出的人数多于转入的人数,孩子真的越来越少了),
所以我需要把每个年级做成一张EXCEL工作簿(内有一个年级的多个班级工作表)。包含学号、姓名、男女人数。
原理:
1、提取每个班级工作簿的第1个工作表的A4-B38的内容(学号和姓名,有空缺的)
2、提取L3、S3的数字(男女人数合计)
读取“00上学期做好的名单”里面所有文件夹里的xlsx,分别合并成三个工作簿
代码展示:
'''
提取上学期作过的点名册里的姓名,变成共享文档,更改插班转园生
星火讯飞、阿霞
20250210
'''
import os
import pandas as pd
from openpyxl import load_workbook
from openpyxl.styles import Alignment
# 设置文件夹路径
path=r'C:\Users\jg2yXRZ\OneDrive\桌面\20250220开学点名册批量制作\00上学期做好的名单'
# title='01托小班'
# title='02中班'
title='03大班'
folder_path = path+fr'\{title}'
# 创建一个空列表来存储所有嵌套列表
all_data = []
# 创建一个字典来存储每个文件的数据
data_dict = {}
# 遍历文件夹中的所有文件
for filename in os.listdir(folder_path):
if filename.endswith('.xlsx') or filename.endswith('.xls'):
# 构建完整的文件路径
file_path = os.path.join(folder_path, filename)
# 班级名称
print(filename[8:12])
# 读取Excel文件的第一张工作表(所有内容,表格形式)
df = pd.read_excel(file_path, sheet_name=0)
# print(df)
# 提取特定列的内容,这里假设'A'和'B'对应第3列和第4列
class_info = [filename[8:9]+'班', filename[9:12]+'班', '学号', '姓名']
# 提取姓名
data = df.iloc[3:37, 0:2].values.tolist() # AB列,实际是第5行开始,第4行开始到38行,一共34人
# 将提取的数据添加到总列表中(拆成单个)
for d in data:
for f in d:
if pd.isna(f): # 如果是‘nan'
class_info.append(' ')
else:
class_info.append(str(f))
# 提取男女
class_info.append('男')
# 提取第5行的数据(假设是男性数据),3行,12列
male_data = df.iloc[1, 11]
# print(male_data)
class_info.append(str(int(male_data)))
# # 提取第6行的数据(假设是女性数据)6行 14列
class_info.append('女')
female_data = df.iloc[1, 18]
# # 将提取的数据添加到总列表中
class_info.append(str(int(female_data)))
# 将当前文件的数据存储到字典中
data_dict[filename[8:12]] = class_info
print(class_info)
# 创建一个新的DataFrame来存储所有数据
columns = ['确认', ' ']
# 保存到新的Excel文件
# 假设 path, title, data_dict, columns 已经定义
output_path = path + fr'\{title}-点名册信息更新.xlsx'
with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
for sheet_name, data in data_dict.items():
num_rows = len(data) // 2
new_df = pd.DataFrame([data[i:i+2] for i in range(0, len(data), 2)], columns=columns)
new_df.to_excel(writer, sheet_name=sheet_name, index=False)
# 加载工作簿和工作表
wb = writer.book
ws = wb[sheet_name]
# 设置单元格居中
for row in ws.iter_rows(min_row=1, max_col=len(columns), max_row=num_rows + 1):
for cell in row:
cell.alignment = Alignment(horizontal='center', vertical='center')
# 调整列宽和行高(可选)
for sheet_name in data_dict.keys():
ws = wb[sheet_name]
for col in ws.columns:
max_length = 10
column = col[0].column_letter # Get the column name
for cell in col:
try:
if len(str(cell.value)) > max_length:
max_length = len(cell.value)
except:
pass
adjusted_width = (max_length + 2)
ws.column_dimensions[column].width = adjusted_width
# 自动调整行高(可选)
for row in ws.rows:
max_height = 0
for cell in row:
try:
if len(str(cell.value)) > max_height:
max_height = len(cell.value)
except:
pass
adjusted_height = 15 if max_height == 0 else (max_height * 1.2) + 10
ws.row_dimensions[cell.row].height = adjusted_height
# 保存工作簿
writer.save()
# 另存为新文件
new_output_path = output_path.replace('.xlsx', '2.xlsx')
wb.save(new_output_path)
做出更新2的三份。
每份的格式都是一样的
第1行:第1个空格是确认,第2个空格是教师确认后输入自己的名字
第2行:年级、班级号,防止选错班级
第3行:标题行(学号、姓名
第4-38行:学号最多34人(现在出生率低,大班最多也就32,33个凑不到34)
第38行是男,人数
第39行是女,人数
最下面的标签都是“班级”
然后转成exlce共享编辑模式。发到微信,各年级老师自己在线填写,添补插班生信息。
等所有的表单都填上了教师姓名
就在手机端下载这份表格xlsx
把更新后的正确名单,复制到“下学期名单”替换原来的生成的名单
更改EXCLE的模版:把第一学期改成第二学期
最后,就是读取EXCLE模版,生成下学期的“灰色日期基础模版”
以下都是各月需要填充灰色的日期
代码展示
import openpyxl
from datetime import datetime, timedelta
import time,os
import openpyxl
from openpyxl.styles import PatternFill
day='2025年2月'
names='XX幼儿园'
path=r'C:\Users\jg2yXRZ\OneDrive\桌面\20250220开学点名册批量制作'
# 打开名单
workbook = openpyxl.load_workbook(path+fr'\01原始点名表_{names}.xlsx')
print('1.原版点名册标签日期更改')
# 读取所有工作表标签名称
sheet_names = workbook.sheetnames
print(sheet_names)
# ['2上', '2下', '3上', '3下', '4上', '4下', '5上', '5下', '6上', '6下']
# ['2上', '2下', '3上', '3下', '4上', '4下', '5上', '5下', '6上', '6下']
# 获取新日期
from datetime import datetime, timedelta
start_date = datetime(2025, 2, 17)
end_date = datetime(2025, 6, 30)
date_set = set()
while start_date <= end_date:
date_set.add(start_date.strftime('%Y-%m'))
start_date += timedelta(days=1)
date_list =[date for date in list(sorted(date_set)) for _ in range(2)]# 去掉重复,排序
print(date_list)
# ['2024-09', '2024-09', '2024-10', '2024-10', '2024-11', '2024-11', '2024-12', '2024-12', '2025-01', '2025-01']
# ['2025-02', '2025-02', '2025-03', '2025-03', '2025-04', '2025-04', '2025-05', '2025-05', '2025-06', '2025-06']
# 组合新的标签名字
new_sheet_names = []
for n in range(len(sheet_names)):
new_name = date_list[n]+sheet_names[n][-1:]
new_sheet_names.append(new_name)
print(new_sheet_names)
# ['2024-09上', '2024-09下', '2024-10上', '2024-10下', '2024-11上', '2024-11下', '2024-12上', '2024-12下', '2025-01上', '2025-01下']
# 下学期没有2月上,但是删除表格,就会出现少一个模板的问题。
# ['2025-02上', '2025-02下', '2025-03上', '2025-03下', '2025-04上', '2025-04下', '2025-05上', '2025-05下', '2025-06上', '2025-06下']
# 替换标签
for old_name, new_name in zip(sheet_names, new_sheet_names):
workbook[old_name].title = new_name
print('2.更改日期和双休日灰色')
sheet_names = workbook.sheetnames
n=0
# 读取每张表格
for sheet_name in sheet_names:
print(sheet_name)
# 读取表格名称
sheet = workbook[sheet_name]
# ������������д��'AB3'��Ԫ��
sheet['AB3'] = new_sheet_names[n][-3:-1]
sheet['W3'] = new_sheet_names[n][:4]
n+=1
# 创建一个灰色填充样式
gray_fill = PatternFill(start_color='D3D3D3', end_color='D3D3D3', fill_type='solid')
# 读取第一张表格(上半月)上半月没有16,但是为了表格好看,把16位置也加灰,下半月的31日要变灰,11没有31日
xx=[[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],[16,22,23,29,30,31],\
[1,2,8,9,15,16],[16,22,23,29,30],\
[4,5,6,12,13,16],[19,20,26,31],\
[1,2,3,4,5,10,11,16],[17,18,24,25,31],\
[1,2,7,8,14,15,16],[21,22,28,29,31]]
for bg in range(0,len(xx)): # 10张表
sheet = workbook.worksheets[bg]
if bg%2==0: # 如果工作表的索引数字是双数,就输入原数
date=xx[bg] # [7,8,15]
for d in date: # 7
# 遍历C5到C42的单元格并填充灰色
for row in range(4, 43): # 不变
for col in range(d*2+1, d*2+3): # 列
cell = sheet.cell(row=row, column=col)
cell.fill = gray_fill
else: # 如果工作表的索引数字是单,就把原数-15, 下月的表从16开始,等于上月表的1,所以需要减去15才能正确填充灰色
date=xx[bg] # [7,8,15]
for d in date: # 7
# 遍历C5到C42的单元格并填充灰色
for row in range(4, 43): # 不变
for col in range((d-15)*2+1, (d-15)*2+3): # 列
cell = sheet.cell(row=row, column=col)
cell.fill = gray_fill
# 保存修改后的工作簿
workbook.save(path+fr'\{day}点名册模版_{names}.xlsx')
2月上,全部用不到(不打印)
2月下
下学期的灰色日期模版做好了,接下去就是在姓名和男女人数格子里批量添加各班信息,并保存为单独的班级工作簿。
合并代码
'''
把原来的点名表标签、日期更改,根据日期添加灰色列(批量生成多个班级
星火讯飞阿夏
20250218
'''
'''1、把原来的点名表标签、日期月份更改'''
import openpyxl
from datetime import datetime, timedelta
import time,os
import openpyxl
from openpyxl.styles import PatternFill
day='2025年2月'
names='XX幼儿园'
path=r'C:\Users\jg2yXRZ\OneDrive\桌面\20250220开学点名册批量制作'
# 打开名单
workbook = openpyxl.load_workbook(path+fr'\01原始点名表_{names}.xlsx')
print('1.原版点名册标签日期更改')
# 读取所有工作表标签名称
sheet_names = workbook.sheetnames
print(sheet_names)
# ['2上', '2下', '3上', '3下', '4上', '4下', '5上', '5下', '6上', '6下']
# ['2上', '2下', '3上', '3下', '4上', '4下', '5上', '5下', '6上', '6下']
# 获取新日期
from datetime import datetime, timedelta
start_date = datetime(2025, 2, 17)
end_date = datetime(2025, 6, 30)
date_set = set()
while start_date <= end_date:
date_set.add(start_date.strftime('%Y-%m'))
start_date += timedelta(days=1)
date_list =[date for date in list(sorted(date_set)) for _ in range(2)]# 去掉重复,排序
print(date_list)
# ['2024-09', '2024-09', '2024-10', '2024-10', '2024-11', '2024-11', '2024-12', '2024-12', '2025-01', '2025-01']
# ['2025-02', '2025-02', '2025-03', '2025-03', '2025-04', '2025-04', '2025-05', '2025-05', '2025-06', '2025-06']
# 组合新的标签名字
new_sheet_names = []
for n in range(len(sheet_names)):
new_name = date_list[n]+sheet_names[n][-1:]
new_sheet_names.append(new_name)
print(new_sheet_names)
# ['2024-09上', '2024-09下', '2024-10上', '2024-10下', '2024-11上', '2024-11下', '2024-12上', '2024-12下', '2025-01上', '2025-01下']
# 下学期没有2月上,但是删除表格,就会出现少一个模板的问题。
# ['2025-02上', '2025-02下', '2025-03上', '2025-03下', '2025-04上', '2025-04下', '2025-05上', '2025-05下', '2025-06上', '2025-06下']
# 替换标签
for old_name, new_name in zip(sheet_names, new_sheet_names):
workbook[old_name].title = new_name
print('2.更改日期和双休日灰色')
sheet_names = workbook.sheetnames
n=0
# 读取每张表格
for sheet_name in sheet_names:
print(sheet_name)
# 读取表格名称
sheet = workbook[sheet_name]
# ������������д��'AB3'��Ԫ��
sheet['AB3'] = new_sheet_names[n][-3:-1]
sheet['W3'] = new_sheet_names[n][:4]
n+=1
# 创建一个灰色填充样式
gray_fill = PatternFill(start_color='D3D3D3', end_color='D3D3D3', fill_type='solid')
# 读取第一张表格(上半月)上半月没有16,但是为了表格好看,把16位置也加灰,下半月的31日要变灰,11没有31日
xx=[[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],[16,22,23,29,30,31],\
[1,2,8,9,15,16],[16,22,23,29,30],\
[4,5,6,12,13,16],[19,20,26,31],\
[1,2,3,4,5,10,11,16],[17,18,24,25,31],\
[1,2,7,8,14,15,16],[21,22,28,29,31]]
for bg in range(0,len(xx)): # 10张表
sheet = workbook.worksheets[bg]
if bg%2==0: # 如果工作表的索引数字是双数,就输入原数
date=xx[bg] # [7,8,15]
for d in date: # 7
# 遍历C5到C42的单元格并填充灰色
for row in range(4, 43): # 不变
for col in range(d*2+1, d*2+3): # 列
cell = sheet.cell(row=row, column=col)
cell.fill = gray_fill
else: # 如果工作表的索引数字是单,就把原数-15, 下月的表从16开始,等于上月表的1,所以需要减去15才能正确填充灰色
date=xx[bg] # [7,8,15]
for d in date: # 7
# 遍历C5到C42的单元格并填充灰色
for row in range(4, 43): # 不变
for col in range((d-15)*2+1, (d-15)*2+3): # 列
cell = sheet.cell(row=row, column=col)
cell.fill = gray_fill
# 保存修改后的工作簿
workbook.save(path+fr'\{day}点名册模版_{names}.xlsx')
print('读取新生单名单')
import openpyxl
path2=path+r'\01下学期名单'
path3=path+fr'\04{day}景二所有名单'
os.makedirs(path2,exist_ok=True)
os.makedirs(path3,exist_ok=True)
# 获取目录下的所有文件
files = [f for f in os.listdir(path2) if f.endswith('.xlsx')]
# 只取前三个文件(第四个是其他学校的),可以单独选1托小班,2中班,3大班
# excel_files = files[:3]
excel_files = files[:3]
print(excel_files)
# 取新生单名单
# 02中班-点名册信息更新2.xlsx
# 初始化计数器
counter = 0
for file in excel_files:
file_path = os.path.join(path2, file)
print(f"Processing file: {file_path}")
# 打开工作簿
workbook = openpyxl.load_workbook(file_path)
sheet_names = workbook.sheetnames
print("Sheet names:", sheet_names)
# for sheet_name in sheet_names:
# sheet = workbook[sheet_name]
# # ['小1班', '小2班', '小3班', '小4班', '小5班', '小6班', '托1班', '托2班']
for bg in range(0,len(sheet_names)): # 10张表
# 遍历每个工作表
name=[]
sheet = workbook.worksheets[bg]
# 读取B列和C列的数据
for row in range(4, 38):
b_value = sheet.cell(row=row, column=2).value
# print(b_value)
if b_value==None:
bb=''
name.append(bb)
else:
name.append(b_value)
c_value = sheet.cell(row=row, column=3).value
# 初始化计数器
## 获取男性数量和女性数量
male_count = sheet['B38'].value
female_count = sheet['B39'].value
# 输出结果
print(f"Sheet: {sheet_name}")
print("男性数量:", male_count if male_count is not None else 0)
print("女性数量:", female_count if female_count is not None else 0)
# 打印班级名称
classroom = sheet_names[bg][0]+"("+sheet_names[bg][2]+")"
print(classroom)
# # # # # 调用模版
# # 打开工作簿
workbook2 = openpyxl.load_workbook(path+fr'\{day}点名册模版_{names}.xlsx')
# # 遍历所有工作表
for sheet2 in workbook2:
# 在C3-C34写入列表a的内容
for index, v1 in enumerate(name):
print(v1)
cell = sheet2.cell(row=index+5, column=2)
cell.value =v1
# 在C3写入班级
title_cell = sheet2.cell(row=3, column=3)
title_cell.value = classroom
# 在C3写入男人数
title_cell = sheet2.cell(row=3, column=12)
title_cell.value = male_count
# 在C3写入女人数
title_cell = sheet2.cell(row=3, column=19)
title_cell.value = female_count
# 合并第一行
for sheet in workbook2:
sheet.merge_cells('A2:AH2') # 合并标题
sheet.merge_cells('C3:G3') # 合并班级
sheet.merge_cells('L3:M3') # 合并男
sheet.merge_cells('S3:T3') # 合并女
sheet.merge_cells('W3:Z3') # 合并年
sheet.merge_cells('Ab3:AC3') # 合并月
for i in range(16):
sheet.merge_cells(start_row=4, start_column=3+2*i, end_row=4, end_column=3+2*i+1)
# 起始行4,起始列3,终点行4,终点列4
# # # 保存修改后的工作簿
workbook2.save(path3+fr'\{day}{classroom}每月点名表_{names}.xlsx')
counter += 1