【办公类-109-01】20250728托小班新生挂牌(学号姓名)
背景需求:
本来安排下学期我不进班,继续机动,本周领导突然通知还需要一位老师交流轮岗,然后派遣去年轮岗过的老师继续外出轮岗。
陆续有三位老师和我联系,原来我下学期带一分园的小二班
算算我长期在总园中大班“当后妈”,也有9年没有带过小班了,9年没有去分园了。
虽然我还是希望在总园,因为总园信息方面的资源更多(硬件、软件更多,打印机都是彩色双面打印)。我也担心领导需要技术支持,我就要来回跑,有点浪费时间。
但是在没有让我出去轮岗,生源越来越少的情况下,能给个一线岗位已经很感恩了。
实际需求:
根据9年前的经验,小班新生刚来园,需要有一个挂牌,便于老师保育员记忆“脸、名字、学号”
【办公类-19-02】办公中的思考——Python批量制作word文本框的名字小标签,用A4word打印(植物角、家长会、值日生)_如何打印人名标签-CSDN博客文章浏览阅读1.1k次。文章讲述了如何使用Python结合Word和Excel模板,通过编程方式高效地批量创建和编辑文本框标签,避免了手动操作的繁琐和易错,适用于各种形状和大小的标签制作,提高了工作效率。https://blog.csdn.net/reasonsummer/article/details/129269200?spm=1011.2415.3001.5331
5年编程经验,我想直接用Python的PIL做出圆形图片。再插入模版。
一、WORD模版
二、制作托小班的信息收集名单
代码
'''
制作班级幼儿信息收集表,包含学号、园区、班级、姓名、性别
豆包,阿夏
20250728
'''
import pandas as pd
import openpyxldef create_class_excel(file_path):# 班级列表classes = ["托1班", "托2班", "小1班", "小2班", "小3班", "小4班", "小5班", "小6班"]# 园区列表:前4个一分园,后4个二分园garden = ["一分园"] * 4 + ["二分园"] * 4print(f"园区分配: {garden}")print(f"班级分配: {classes}")# 确保班级数量和园区数量匹配if len(classes) != len(garden):print(f"警告: 班级数量({len(classes)})与园区数量({len(garden)})不匹配")return# 创建一个ExcelWriter对象with pd.ExcelWriter(file_path, engine='openpyxl') as writer:# 创建模板页template_data = {"学号": list(range(1, 26)), # 学号1-25"园区": [""] * 25,"班级": [""] * 25,"姓名": [""] * 25,"性别": [""] * 25}template_df = pd.DataFrame(template_data)template_df.to_excel(writer, sheet_name="模板", index=False)# 为每个班级创建工作表,同时填充对应的园区信息for i in range(len(classes)):class_name = classes[i]current_garden = garden[i]# 复制模板数据class_data = template_data.copy()# 填充班级列和园区列class_data["班级"] = [class_name] * 25class_data["园区"] = [current_garden] * 25# 创建DataFrame并写入Excelclass_df = pd.DataFrame(class_data)class_df.to_excel(writer, sheet_name=class_name, index=False)print(f"已创建工作表: {class_name} (园区: {current_garden})")print(f"\nExcel文件已生成: {file_path}")if __name__ == "__main__":# 生成的Excel文件路径和名称path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250728托小幼儿挂牌'excel_file = path + r"\班级信息表.xlsx"create_class_excel(excel_file)
每个班级都写好了指定园区和班级名称,后侧的姓名和性别需要自己填写
三、批量制作圆形卡片和每班的pdf
花费一下午的时间,逐步实现一个班幼儿的姓名学号做成图片、制作反面学号图、制作一个班级幼儿的图片合并pdf,批量读取Excel班级信息,制作每班一份的圆形学号姓名卡片
'''
制作托小班幼儿圆形挂牌(开学挂在幼儿身上) 小2班一个班级
豆包,阿夏
20250728
'''from PIL import Image, ImageDraw, ImageFont
import os
import pandas as pd
import glob
from docx import Document
from docx.shared import Cm
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
import win32com.client
from PyPDF2 import PdfMerger
import shutil# ========== 读取Excel数据 ==========
def read_excel_data(file_path):"""读取Excel文件第一张表数据,跳过第一行,返回包含学号、园区、姓名、班级、性别的列表"""try:# 读取第一张表,获取第1-5列数据(索引0-4),无表头df = pd.read_excel(file_path, sheet_name=0, usecols=[0, 1, 2, 3, 4], header=None)# 跳过第一行(索引为0的行),从第二行开始读取df = df.iloc[1:] data_list = []for index, row in df.iterrows():# 处理学号(核心修改:区分显示用和文件名用)raw_id = str(row[0]).strip() # 原始学号if not raw_id.isdigit(): # 确保是数字print(f"跳过第{index+1}行:学号不是数字")continueid_num = int(raw_id) # 转换为整数(用于图片显示,如1)formatted_id = f"{id_num:02d}" # 格式化为2位数(用于文件名,如01)# 其他字段campus = str(row[1]).strip() # 园区class_name = str(row[2]).strip() # 班级name = str(row[3]).strip() # 姓名 gender = str(row[4]).strip() # 性别# 跳过姓名为空的行if not name or name.lower() == 'nan':print(f"跳过第{index+1}行:姓名为空")continuedata_list.append({'id_display': f"{id_num}号", # 图片上显示的学号(如1号)'id_file': formatted_id, # 文件名中使用的学号(如01)'campus': campus,'name': name,'class_name': class_name,'gender': gender})return data_listexcept Exception as e:print(f"读取Excel失败:{e}")return []# ========== 正面图片生成函数 ==========def generate_image(data, output_dir):"""根据单条数据生成正面图片(图片学号显示为1号,文件名包含01)"""id_display = data['id_display'] # 图片上显示的学号(如1号)id_file = data['id_file'] # 文件名中使用的学号(如01)class_name = data['class_name']name = data['name']# 确保输出目录存在os.makedirs(output_dir, exist_ok=True)# 图片参数image_size = (830, 830) circle_diameter = 780 border_width = 30 # 小圆形参数small_circle_diameter = 50 small_circle_border = 5 small_circle_offset_y = -320 # 基础字体大小base_name_font_size = 200 class_font_size = 130 id_font_size = 100 # 根据姓名长度调整字号(4个字时减小20磅)name_length = len(name)name_font_size = base_name_font_size - 40 if name_length >= 4 else base_name_font_size# 位置偏移class_offset_y = -220 name_offset_y = -30 id_offset_y = 200 # 其他样式underline_thickness = 10 outer_circle_diameter = 830 outer_line_width = 5 zeng = 50 # 加载字体(强制微软雅黑)try:name_font = ImageFont.truetype("msyh.ttc", name_font_size)class_font = ImageFont.truetype("msyh.ttc", class_font_size)id_font = ImageFont.truetype("msyh.ttc", id_font_size)except Exception as e:print(f"字体加载失败:{e},使用默认字体")name_font = ImageFont.load_default()class_font = ImageFont.load_default()id_font = ImageFont.load_default()# 创建新图片img = Image.new('RGB', image_size, 'white')draw = ImageDraw.Draw(img)# 设置颜色line_color = text_color = outer_color = 'black'# 绘制圆形边框circle_x = (image_size[0] - circle_diameter) // 2circle_y = (image_size[1] - circle_diameter) // 2draw.ellipse([circle_x, circle_y, circle_x + circle_diameter, circle_y + circle_diameter], outline=line_color, width=border_width)# 绘制内部圆形inner_diameter = circle_diameter - 2 * border_widthinner_x = circle_x + border_widthinner_y = circle_y + border_widthdraw.ellipse([inner_x, inner_y, inner_x + inner_diameter, inner_y + inner_diameter], fill='white', outline='white')# 绘制外部实线圆outer_radius = outer_circle_diameter // 2outer_center = (image_size[0] // 2, image_size[1] // 2)outer_x1 = outer_center[0] - outer_radiusouter_y1 = outer_center[1] - outer_radiusouter_x2 = outer_center[0] + outer_radiusouter_y2 = outer_center[1] + outer_radiusdraw.ellipse([outer_x1, outer_y1, outer_x2, outer_y2],outline=outer_color, width=outer_line_width)# 绘制小圆形small_center_x = image_size[0] // 2small_center_y = image_size[1] // 2 + small_circle_offset_ysmall_radius = small_circle_diameter // 2draw.ellipse([small_center_x - small_radius,small_center_y - small_radius,small_center_x + small_radius,small_center_y + small_radius], fill='white', outline='black', width=small_circle_border)# 绘制班级文字class_bbox = draw.textbbox((0, 0), class_name, font=class_font)class_x = (image_size[0] - (class_bbox[2] - class_bbox[0])) // 2class_y = (image_size[1] - (class_bbox[3] - class_bbox[1])) // 2 + class_offset_yfor offset in [(0, 0), (1, 0), (-1, 0), (0, 1), (0, -1)]:draw.text((class_x + offset[0], class_y + offset[1]), class_name, font=class_font, fill=text_color)# 绘制姓名name_bbox = draw.textbbox((0, 0), name, font=name_font)name_x = (image_size[0] - (name_bbox[2] - name_bbox[0])) // 2name_y = (image_size[1] - (name_bbox[3] - name_bbox[1])) // 2 + name_offset_yfor offset in [(0, 0), (1, 0), (-1, 0), (0, 1), (0, -1)]:draw.text((name_x + offset[0], name_y + offset[1]), name, font=name_font, fill=text_color)# 绘制学号及下划线(使用图片显示用学号)id_bbox = draw.textbbox((0, 0), id_display, font=id_font)id_x = (image_size[0] - (id_bbox[2] - id_bbox[0])) // 2id_y = (image_size[1] - (id_bbox[3] - id_bbox[1])) // 2 + id_offset_yfor offset in [(0, 0), (1, 0), (-1, 0), (0, 1), (0, -1)]:draw.text((id_x + offset[0], id_y + offset[1]), id_display, font=id_font, fill=text_color)