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

【办公类-109-09】20260228挂牌长方形挂牌卡片(只有word编辑单面,添加有效日期)(85*54mm横板和54*85mm竖版,一页9张)

背景需求

制作幼儿挂牌里面的信息卡片

 这是上学期的样式,

第一版 横版和竖版

【办公类-109-04】20250807托小班新生的卡套长方形纸牌制作Python3.11.5 32(85*54mm横板和54*85mm竖版,一页9张)https://mp.csdn.net/mp_blog/creation/editor/150009366

第二版,有照片位置预留,PDF

【办公类-109-07】20250823(有1寸照片)托小班新生的卡套长方形纸牌制作Python3.11.5 32(85*54mm横板和54*85mm竖版,一页9https://mp.csdn.net/mp_blog/creation/editor/150774366

第三班 word可编辑

【办公类-109-05】20250915挂牌长方形卡片(word编辑单面)(85*54mm横板和54*85mm竖版,一页9张)https://mp.csdn.net/mp_blog/creation/editor/151723723

这是上学期的样式,

虽然我觉得好像放在卡套里的长方形竖版横版纸片用了6个月,基本没有坏。但是我还是再做一份下学期的备份。

关键是添加上卡片的“有效日期”(2026.2-2026.6)

代码部分

''' 1.制作20250901托小班长方形卡片,横版85*54mm和竖版54*85mm,一页9张单面 2.添加姓名拼音显示功能(拼音在姓名上方,带声调) 3.python 3.7.8 3. 横版布局:单列显示园区和班级,双列显示拼音、姓名和学号 4. 竖版布局:单列显示所有信息 5. 添加照片占位符:2.5cm宽*3.5cm高,黑色框线,中间写"贴照片" 6、生成全部班级或生成指定班级(中1-中6班) 7、添加日期2026.2-2026.6 豆包,deepseek,阿夏 20260228 ''' # ========== 记录程序开始时间 ========== import time start_time = time.time() # ========== 创建照片占位符图片 ========== import os from copy import deepcopy from PIL import Image, ImageDraw, ImageFont import shutil import pandas as pd from pypinyin import pinyin, Style from docx import Document from docx.shared import Cm, Pt from docx.enum.text import WD_PARAGRAPH_ALIGNMENT from docx.oxml.ns import qn from docx.oxml import OxmlElement import glob from docx.oxml.shared import qn as oxml_qn from docx.oxml import parse_xml from docx.enum.text import WD_BREAK from docx.oxml.shared import qn from docx.oxml import parse_xml date='2026.2—2026.6' def create_photo_placeholder(image_path): """创建照片占位符图片""" try: # 确保目录存在 os.makedirs(os.path.dirname(image_path), exist_ok=True) # 设置图片尺寸 (2.5cm x 3.5cm) width, height = int(2.5/2.54*300), int(3.5/2.54*300) # 转换为300dpi的像素 # 创建白色背景图片 img = Image.new('RGB', (width, height), 'white') draw = ImageDraw.Draw(img) # 绘制黑色边框 draw.rectangle([(10, 10), (width-10, height-10)], outline='black', width=2) # 添加文字 try: # 尝试使用微软雅黑字体 font = ImageFont.truetype("msyh.ttc", 20) except: # 如果找不到字体,使用默认字体 font = ImageFont.load_default() text = "贴照片" text_bbox = draw.textbbox((0, 0), text, font=font) text_width = text_bbox[2] - text_bbox[0] text_height = text_bbox[3] - text_bbox[1] text_x = (width - text_width) // 2 text_y = (height - text_height) // 2 draw.text((text_x, text_y), text, fill='black', font=font) # 保存图片 img.save(image_path) print(f"已创建照片占位符: {image_path}") return True except Exception as e: print(f"创建照片占位符失败: {str(e)}") return False # ========== 读取Excel数据 ========== def read_excel_data(file_path): """读取Excel文件所有工作表数据,返回字典{班级名: 数据列表}""" # 特殊姓氏读音字典 SPECIAL_SURNAMES = { "乐": "Yuè", "单": "Shàn", "解": "Xiè", "查": "Zhā", "盖": "Gě", "仇": "Qiú", "种": "Chóng", "朴": "Piáo", "翟": "Zhái", "区": "Ōu", "繁": "Pó", "覃": "Qín", "召": "Shào", "华": "Huà", "纪": "Jǐ", "曾": "Zēng", "缪": "Miào", "员": "Yùn", "车": "Chē", "过": "Guō", "尉": "Yù", "万": "Wàn" } # 复姓处理字典 COMPOUND_SURNAMES = { "欧阳": "Ōu yáng", "上官": "Shàng guān", "皇甫": "Huáng fǔ", "尉迟": "Yù chí", "万俟": "Mò qí", "长孙": "Zhǎng sūn", "司徒": "Sī tú", "司空": "Sī kōng", "司马": "Sī mǎ", "诸葛": "Zhū gě", "东方": "Dōng fāng", "独孤": "Dú gū", "慕容": "Mù róng", "宇文": "Yǔ wén" } def correct_surname_pinyin(name): """校正姓氏拼音,处理多音字问题""" if not name or not isinstance(name, str) or name.strip() == "": return "" name = name.strip() # 先检查复姓 for surname in COMPOUND_SURNAMES: if name.startswith(surname): surname_pinyin = COMPOUND_SURNAMES[surname] given_name = name[2:] given_pinyin = ' '.join([p[0] for p in pinyin(given_name, style=Style.TONE)]) return f"{surname_pinyin} {given_pinyin}" # 检查单姓 first_char = name[0] if first_char in SPECIAL_SURNAMES: surname_pinyin = SPECIAL_SURNAMES[first_char] given_name = name[1:] given_pinyin = ' '.join([p[0] for p in pinyin(given_name, style=Style.TONE)]) return f"{surname_pinyin} {given_pinyin}" return ' '.join([p[0] for p in pinyin(name, style=Style.TONE)]) try: xls = pd.ExcelFile(file_path) class_data = {} for sheet_name in xls.sheet_names: df = pd.read_excel( file_path, sheet_name=sheet_name, usecols=range(5), header=None, dtype={0: str} ) df = df.iloc[1:] data_list = [] for index, row in df.iterrows(): row_num = index + 2 raw_id = str(row[0]).strip() if pd.notna(row[0]) else "" # 如果没有学号但有名字,或者有学号但没有名字,都创建记录 name = str(row[3]).strip() if pd.notna(row[3]) else "" try: # 处理学号 if raw_id.isdigit(): id_num = int(raw_id) formatted_id = f"{id_num:02d}" id_display = f"{id_num}号" else: # 如果没有学号,使用行号作为学号 id_num = index + 1 formatted_id = f"{id_num:02d}" id_display = f"{id_num}号" campus = str(row[1]).strip() if pd.notna(row[1]) else "" class_name = str(row[2]).strip() if pd.notna(row[2]) else "" gender = str(row[4]).strip() if pd.notna(row[4]) else "" # 如果没有名字,使用"张三" if not name: name = "张三" name_pinyin = correct_surname_pinyin(name) data_list.append({ 'id_display': id_display, 'id_file': formatted_id, 'campus': campus, 'name': name, 'name_pinyin': name_pinyin, 'class_name': class_name, 'gender': gender }) except Exception as e: print(f"处理第{row_num}行数据时出错: {str(e)}") continue if data_list: class_data[sheet_name] = data_list return class_data except Exception as e: print(f"读取Excel文件失败:{str(e)}") return {} def expand_students_to_target_count(students, class_name): """将学生列表扩展到目标人数(托小班27人,中大班36人)""" # 确定目标人数 if "托" in class_name : target_count = 27 elif "小" in class_name: target_count = 27 elif "中" in class_name: target_count = 36 else: target_count = 36 # 如果实际人数已经达到或超过目标人数,直接返回实际人数 if len(students) >= target_count: return students[:target_count] # 扩展学生列表 expanded_students = students.copy() # 获取第一个学生的园区和班级信息(用于填充空白学生) if students: base_campus = students[0]['campus'] base_class = students[0]['class_name'] else: base_campus = "" base_class = class_name # 添加空白学生 for i in range(len(students), target_count): empty_student = { 'id_display': f"{i+1}号",
http://www.cnnetsun.cn/news/3557561.html

相关文章:

  • 如何通过三天学习记录分析学习模式与优化教学策略
  • 终极指南:如何用AutoRemesher快速优化3D网格模型
  • Starship极速优化:从500ms到50ms,让你的终端提示符飞起来!
  • Unity加载OSGB三维模型:从数据解析到性能优化的完整实践指南
  • VCAP-DTM考试完整信息:Deploy实操实验考试标准时长4小时
  • Amphenol ICC DRPC21A003940线束组件应用分析
  • GPT-5.6 Sol与Codex:AI编程工具实战指南与避坑策略
  • 嵌入式视频处理内存优化:DMM/TILER硬件配置与缓冲区布局实战
  • 3分钟打造专属电脑监控屏:Turing智能显示屏Python项目完全指南
  • 深入解析CPSW中断与DMA机制:嵌入式网络驱动开发核心
  • YOLO-World语义分割架构解析:从实时检测到像素级理解的性能优化实践
  • MOSS-Music-8B-Thinking-4bit技术架构揭秘:多模态音乐模型的工作原理
  • 抖音批量下载终极指南:揭秘高效收藏背后的技术密码
  • 如何用Video2X实现视频画质AI增强:从模糊到4K的终极指南
  • 如何让AI成为你的私人象棋教练:Vin象棋深度学习分析工具完全指南
  • TI C2000 CLA协处理器编程与调试实战指南
  • 体育器材管理系统
  • 自定义Il2CppDumper:逆向分析Unity应用的核心原理与实战
  • 运维工程师到技术合伙人的成长路径与技能跃迁
  • XAutoDaily:5大实用功能揭秘,让QQ自动签到成为你的时间管理神器
  • Akebi-GC:突破原神游戏限制的高级内存操作框架
  • AI成熟度测评:从工具应用到组织进化的四个维度
  • AI时代编程分工变革与人机协作实践
  • AgentScope 2.0:生产级智能体开发框架解析与实践
  • 2026年频繁跳槽叙事重构指南:AI辅助职业主线提炼+4款工具实测,把跳槽从减分项变成加分项
  • 微软Win11持续更新策略解析:商业与技术平衡之道
  • C++哈希表深度解析:开放定址法与哈希桶实现原理与性能对比
  • 如何用Python构建智能桌面伙伴:DyberPet开源框架的完整指南
  • 工程实践范式深度解析:andrej-karpathy-skills与测试驱动开发的技术融合
  • Converter NOW:你的跨平台单位转换终极解决方案