背景需求
前期制作了“门牌号黏贴卡”5种。
【教学类-29-02】20230402《门牌号-黏贴版&打印数量调查&教学实践(6层*5间)》-(中班《我爱我家》偏数学)_29-2-02-03房间号-CSDN博客文章浏览阅读487次。文章描述了一位教育工作者在设计和实施门牌号黏贴版学具教学过程中遇到的问题,包括难以精确预估打印数量和控制操作时长。通过分层设计和增加备用数量来解决这些问题,并在实际教学中根据幼儿的表现调整学具和教学方法,如添加下划线辅助识别。活动反馈显示,多数幼儿对门牌号的理解仍初级,教学重点在于引入数字概念和游戏化学习体验。
https://blog.csdn.net/reasonsummer/article/details/129898075?sharetype=blogdetail&sharerId=129898075&sharerefer=PC&sharesource=reasonsummer&spm=1011.2480.3001.8118
现在我想制作有底纹、有下划线的版本。包含题目卡和答案卡。
单独样式(输入空格数量)
'''
名称:大班学具:灰色门牌号(黏贴卡)(题目+答案版)输入需要几个空格,0,5,10,15,20(15卡片+5手写)
作者:阿夏
修改:20250808 合并多版本功能,支持动态配置参数
'''
import random, os, time
import docx
from docx.oxml import parse_xml
from docx.oxml.ns import nsdecls
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx import Document
from docx.shared import Pt, RGBColor
from docx.oxml.ns import qn
from docx2pdf import convert
from PyPDF2 import PdfFileMerger
import shutil
# 用户输入参数
num = int(input('生成多少份(按班级人数)\n'))
Number = int(input('黏贴片数,0,5,10,15,20)\n')) # 总格子数保持20个
size = 42
height1 = 6
weight1 = 5
height2 = 3
weight2 = 5
# 颜色设置
gray_text = 170 # 灰色文字
gray_bg = 221 # 灰色背景
black = 0 # 黑色文字
# 创建输出文件夹
path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250808黏贴门牌号'
temp_folder = path + r'\零时Word'
os.makedirs(temp_folder, exist_ok=True)
# 房间表格位置
bg1 = []
for x1 in range(0, height1):
for y1 in range(0, weight1):
ww1 = f'{x1}{y1}'
bg1.append(ww1)
# 贴纸表格位置
bg2 = []
for x2 in range(0, height2):
for y2 in range(0, weight2):
ww2 = f'{x2}{y2}'
bg2.append(ww2)
def generate_documents():
# 保存每份的空缺位置信息
blank_positions = []
# 先生成所有题目文档,记录空缺位置
for z in range(0, num):
# 生成门牌号列表
N = []
for x in range(6, 0, -1):
for y in range(1, 6):
s1 = f'{x}{y:02d}'
N.append(s1)
# 随机抽取门牌号
C = random.sample(N, Number)
blank_positions.append(C) # 保存空缺位置
# 加载模板
doc = Document(path + r'\02_00黏贴门牌号模板(6层5间).docx')
# 设置标题
table = doc.tables[0]
cell = table.cell(0, 1)
cell.text = ""
paragraph = cell.paragraphs[0]
title = f"门牌{height1}*{weight1}\n 编号{z+1}"
run = paragraph.add_run(title)
run.font.name = '黑体'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '黑体')
run.font.size = Pt(30)
run.font.color.rgb = RGBColor(0, 0, 0)
run.bold = True
paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
# 处理房间表格(表1)- 保持不变
table = doc.tables[1]
for t1 in range(0, len(bg1)):
pp1 = int(bg1[t1][0])
qq1 = int(bg1[t1][1])
k1 = N[t1]
# 题目模式:空白处用下划线表示
if k1 in C:
k1 = ' '
# 确保单元格有段落(避免index out of range)
if not cell.paragraphs:
cell.add_paragraph()
run = table.cell(pp1, qq1).paragraphs[0].add_run(k1)
run.font.color.rgb = RGBColor(gray_text, gray_text, gray_text)
if k1 == ' ':
run.underline = True
# 通用格式设置
run.font.name = '黑体'
run.font.size = Pt(size)
run.bold = True
run.underline = True
r = run._element
r.rPr.rFonts.set(qn('w:eastAsia'), '黑体')
table.cell(pp1, qq1).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
# 处理贴纸表格(表2)- 题目部分:15个黑色文字+灰色底纹,5个黑色文字+无底纹
table = doc.tables[2]
for t2 in range(0, len(bg2)):
pp2 = int(bg2[t2][0])
qq2 = int(bg2[t2][1])
cell = table.cell(pp2, qq2)
cell.text = "" # 清空单元格原有内容
# 确保单元格有段落
if not cell.paragraphs:
cell.add_paragraph()
# 只处理前20个单元格(Number=20)
if t2 < Number:
k2 = C[t2]
# 前15个单元格:灰色底纹
if t2 < 15:
shading_elm = parse_xml(
f'<w:shd xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" '
f'w:fill="{gray_bg:02x}{gray_bg:02x}{gray_bg:02x}"/>'
)
cell._tc.get_or_add_tcPr().append(shading_elm)
# 添加文字(统一黑色)
run = cell.paragraphs[0].add_run(k2)
run.font.name = '黑体'
run.font.size = Pt(size)
run.font.color.rgb = RGBColor(gray_text, gray_text, gray_text) # 修正为黑色文字
run.bold = True
run.underline = True
r = run._element
r.rPr.rFonts.set(qn('w:eastAsia'), '黑体')
else:
# 多余的单元格留空
run = cell.paragraphs[0].add_run(' ')
run.font.name = '黑体'
run.font.size = Pt(size)
cell.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
# 保存题目文件
docx_path = os.path.join(temp_folder, f'{z+1:02}_题目.docx')
pdf_path = os.path.join(temp_folder, f'{z+1:02}_题目.pdf')
doc.save(docx_path)
# 转换为PDF
convert(docx_path, pdf_path)
# 生成所有答案文档
for z in range(0, num):
# 生成门牌号列表
N = []
for x in range(6, 0, -1):
for y in range(1, 6):
s1 = f'{x}{y:02d}'
N.append(s1)
# 加载模板
doc = Document(path + r'\02_00黏贴门牌号模板(6层5间).docx')
# 设置标题
table = doc.tables[0]
cell = table.cell(0, 1)
cell.text = ""
paragraph = cell.paragraphs[0]
title = f"门牌{height1}*{weight1}\n 答案{z+1}"
run = paragraph.add_run(title)
run.font.name = '黑体'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '黑体')
run.font.size = Pt(30)
run.font.color.rgb = RGBColor(black, black, black)
run.bold = True
paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
# 处理房间表格(表1)- 按表格2的20个数据区分格式
table = doc.tables[1]
first_15 = blank_positions[z][:15] # 前15个数据
last_5 = blank_positions[z][15:] # 后5个数据
for t1 in range(0, len(bg1)):
pp1 = int(bg1[t1][0])
qq1 = int(bg1[t1][1])
k1 = N[t1]
cell = table.cell(pp1, qq1)
# 清除单元格原有格式和内容
cell.text = ""
if cell._tc.tcPr is not None:
for child in cell._tc.tcPr.getchildren():
if child.tag.endswith('shd'):
cell._tc.tcPr.remove(child)
# 确保单元格有段落(核心修复:避免index out of range)
if not cell.paragraphs:
cell.add_paragraph()
# 前15个数据:灰色底纹+黑色文字
if k1 in first_15:
shading_elm = parse_xml(
f'<w:shd xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" '
f'w:fill="{gray_bg:02x}{gray_bg:02x}{gray_bg:02x}"/>'
)
cell._tc.get_or_add_tcPr().append(shading_elm)
run = cell.paragraphs[0].add_run(k1)
run.font.color.rgb = RGBColor(black, black, black)
# 前15个是有底纹有的黏贴卡片,下划线+加粗
run.bold = True
run.underline = True
run.font.size = Pt(size)
# 后5个数据:无底色+黑色文字
elif k1 in last_5:
run = cell.paragraphs[0].add_run(k1)
run.font.color.rgb = RGBColor(black, black, black)
# 后5个是手写的,无底纹+无下划线+加粗+倾斜+字号变大
run.italic = True
run.bold = False
run.underline = False
run.font.size = Pt(50)
# 非空白位置:白色背景+灰色文字
else:
run = cell.paragraphs[0].add_run(k1)
run.font.color.rgb = RGBColor(gray_text, gray_text, gray_text)
# 原来就有的数字,下划线+加粗
run.bold = True
run.underline = True
run.font.size = Pt(size)
# 通用格式设置
run.font.name = '黑体'