学校事务自动化——用电子表格自动生成评价计划书初稿

힘센캥거루
2026년 3월 30일(수정됨)
6
33

随着 2022 修订课程标准的实施,科目变多了,相应地,每学期都要重新撰写评价计划书的情况也随之出现。

问题在于,评价计划书要求把各单元的成就标准、成就水平等全部逐项填写,是一个形式化的工作。

而这些标准又并不是教师自己撰写的内容,而只是单纯的复制+粘贴

于是我先把相关内容整理成表格,然后利用 Excel 或电子表格中的 FILTERTEXTJOIN 函数,尝试让它自动合并生成。

1. 制作成就水平数据库

各选修课程的成就水平可以在下方的 KICE 学生评价支援门户中获取。

从顶部目录中的 [小学/初中/高中] -> [课程成就标准] -> [成就标准资料室] 中搜索后下载即可。

例如“世界公民与地理”的成就水平如下所示。

问题是,这样的成就标准少则 15 条,每一条成就标准对应的成就水平都要复制并合并成 A~E 五个等级。

现在来把这些资料制作成表格。

学校事务自动化——用电子表格自动生成评价计划书初稿-1

首先,把 hwp 格式的文件另存为 hwpx 文件

hwpx 文件会以 xml 数据形式保存内部文件结构,因此可以用其他程序对其内部进行解析。

学校事务自动化——用电子表格自动生成评价计划书初稿-2

然后使用 Python 抽取 hwpx 内部的表格。

下面的代码当然借助了 chatGPT 大佬的帮助。

hwpx 文件是 zip + xml 结构,因此可以用 Python 读取内部 xml 并抽取表格。

// 이 코드는 생성형 AI를 이용해 제작한 코드입니다.

import zipfile
import xml.etree.ElementTree as ET
from openpyxl import Workbook

hwpx_path = "사회과 선택과목 성취수준 현장 보급본.hwpx"
xlsx_path = "output.xlsx"


def tag_name(elem):
    return elem.tag.split("}")[-1]


def collect_text(node):
    texts = []

    # tc 내부에 중첩 tbl이 있으면 그 하위 텍스트는 제외한다.
    stack = [node]
    while stack:
        cur = stack.pop()

        if cur is not node and tag_name(cur) == "tbl":
            continue

        if tag_name(cur) == "t" and cur.text:
            t = cur.text.strip()
            if t:
                texts.append(t)

        children = list(cur)
        stack.extend(reversed(children))

    return "\n".join(texts)


def is_title_like(text):
    if not text:
        return False

    compact = text.replace(" ", "")

    # 표 전체 내용을 붙여 놓은 긴 문장은 제목으로 취급하지 않는다.
    if len(text) > 80:
        return False

    # 표 헤더/본문 키워드가 포함되면 제목 행으로 넣지 않는다.
    if "성취기준" in compact and "성취수준" in compact:
        return False

    return True


wb = Workbook()
ws = wb.active
ws.title = "tables"

saved_table_count = 0
current_row = 1

with zipfile.ZipFile(hwpx_path, "r") as z:
    section_files = sorted(
        name for name in z.namelist()
        if name.startswith("Contents/section") and name.endswith(".xml")
    )

    for section_file in section_files:
        xml_data = z.read(section_file)
        root = ET.fromstring(xml_data)

        elems = list(root.iter())

        for i, elem in enumerate(elems):
            if tag_name(elem) != "tbl":
                continue

            tbl = elem

            prev_text = ""
            for j in range(i - 1, -1, -1):
                if tag_name(elems[j]) != "p":
                    continue

                texts = []
                for x in elems[j].iter():
                    if tag_name(x) == "t" and x.text:
                        t = x.text.strip()
                        if t:
                            texts.append(t)

                candidate = " ".join(texts)
                if not candidate:
                    continue

                if is_title_like(candidate):
                    prev_text = candidate
                    break

            table_rows = []
            for tr in tbl:
                if tag_name(tr) != "tr":
                    continue

                row_values = []
                for tc in tr:
                    if tag_name(tc) != "tc":
                        continue
                    row_values.append(collect_text(tc))

                if row_values:
                    table_rows.append(row_values)

            if not table_rows:
                continue

            preview_text = "".join(table_rows[0])

            # 1행 1셀 같은 요약성/오검출 표는 제외한다.
            has_enough_shape = len(table_rows) >= 2 and any(len(r) >= 2 for r in table_rows)

            if "성취기준별" in preview_text and "성취수준" in preview_text and has_enough_shape:
                saved_table_count += 1

                table_title = prev_text if is_title_like(prev_text) else ""

                for row_values in table_rows:
                    # 1열에는 표 제목을 두고, 실제 표 데이터는 오른쪽(2열부터) 배치한다.
                    ws.cell(row=current_row, column=1, value=table_title)

                    first_value = row_values[0].strip() if row_values and isinstance(row_values[0], str) else ""
                    start_col = 3 if first_value in {"B", "C", "D", "E"} else 2

                    for col_idx, value in enumerate(row_values, start=start_col):
                        ws.cell(row=current_row, column=col_idx, value=value)

                    # 오른쪽으로 밀린(B/C/D/E) 행은 표의 첫 번째 열(2열)을 바로 윗행 값으로 채운다.
                    if start_col == 3 and current_row > 1:
                        ws.cell(row=current_row, column=2, value=ws.cell(row=current_row - 1, column=2).value)

                    current_row += 1

                # 표 사이 한 줄 띄우기
                current_row += 2

if saved_table_count == 0:
    ws["A1"] = "조건에 맞는 표를 찾지 못했습니다."

wb.save(xlsx_path)
print(f"완료: {saved_table_count}개 표를 하나의 시트에 저장")

这样一来,内部表格就会像下面这样被抽取出来。

即便如此,如果还有无法正确抽取出来的表格,那就手工稍微整理一下数据吧。

学校事务自动化——用电子表格自动生成评价计划书初稿-3

我就直接在 Excel 里用筛选和“分列”功能,把成就标准代码、内容、按成就标准划分的成就水平分别拆了出来。

如果对这些数据进行规范化,性能会更好,但人工核对会比较困难,所以我就保留成了重复字段。

做到这里,不禁想到,也许干脆申请公开这个数据库会更好。

2. 制作电子表格

一般学校在评价计划中会按周次填入相应的成就代码和成就标准。

所以我想,如果只要按月份选择成就代码,就能自动填充内容,那么输入评价计划会轻松得多。

电子表格是利用 filterunique 函数,把要输入的科目、单元、成就代码组合起来生成的。

如果觉得难的话,我建议可以和 AI 一起做一做看。

学校事务自动化——用电子表格自动生成评价计划书初稿-4

在第一个工作表中,只要输入月份、周次、单元名、成就标准代码,最右边就会生成内容,只需复制粘贴即可。

中间绿色框部分是为了方便我核对自己输入的成就标准而做的。

通过这样的选择,就能自动完成单元别的成就标准及成就水平,以及学期层面的成就水平

学校事务自动化——用电子表格自动生成评价计划书初稿-5

其实在一般学科中,所有成就标准都会写入评价计划,所以就算“全部塞进去”也没关系,但我是考虑到课程重构才这样设计的。

我还在犹豫,要不要再加一个把 A~E 全部合并起来的工作表。

另外我也做了一个用于表现性评价的工作表。

学校事务自动化——用电子表格自动生成评价计划书初稿-6

只要输入我想用于表现性评价的成就标准代码,它就会把 A~E 水平全部合并好,方便直接写进评价计划书。

我们真正需要思考的,并不是复制、粘贴,而是究竟要实施怎样的评价。

3. 使用后感

学校事务自动化——用电子表格自动生成评价计划书初稿-7

令人遗憾的是,许多教师即便在评价计划上倾注了大量时间,教室里的任何人也不会对那些成就水平的句子感到好奇。

这是因为,相比评价计划本身,按照评价计划落实出来的“评价本身”才更重要

对那些在把成就标准写入评价标准之后才毕业的人,如果去问他们成就标准具体是什么,我敢肯定,没有人能记得住

因此,可以说在评价标准中写入这些句子,只不过是毫无意义的形式化操作

学校里的教育现场并不是像成就代码、成就标准那样静态的,而是动态的。

我在想,我们是不是更应该把时间用在思考评价本身的质量问题上,而不是追求评价计划的公文式完备性。

或许真正的使用后记还得等到 7~8 月实际使用之后才能写出来。

把这个电子表格分享给旁边办公室的老师后,对方说好像立刻就能完成第二学期的评价计划了,很高兴。

我想这大概会帮上不少忙。

관련 글

模拟考试一览表无法上传到大教协、Uniiv、金英日时——保存为 PDF
模拟考试一览表无法上传到大教协、Uniiv、金英日时——保存为 PDF
模拟考试结束后,可以在评价院把成绩单以打印件或 PDF 形式输出。查看收到的 PDF 文件时,偶尔会发现内部完全没有任何数据,只是以图片形式存在,这种情况下要处理成绩就非常棘手。这时无论怎么尝试把成绩上传到升学软件中,都无法成功处理。1. 用于成绩上传的 PDF 输出方法如果想稍微轻松一点处理成绩,...
学校教室机器人吸尘器的运行方法
学校教室机器人吸尘器的运行方法
在教室里开始使用机器人吸尘器已经有4年了。今年我的目标是,我自己不再操心机器人吸尘器,而是让孩子们完全负责管理。1. 运行机器人吸尘器出乎意料、让我很惊讶的是,从来没有给机器人吸尘器做过清洁的孩子很多。即便是清空尘盒、把底部的刷子拆下来清理头发这种很简单的事情,也需要有人教。有时还会把刷子反着装上,...
2026年东国大学未来社会教师能力提升论坛线下参与后记
2026年东国大学未来社会教师能力提升论坛线下参与后记
有位老师给我推荐了一项看起来很有趣的培训。是在东国大学举办的与 AI 相关的培训。是 AI 相关培训就已经很好了,结果还是在酒店举行的?那我无论如何都得去一趟了。在当天一开放报名我就立刻报了名,最后得以线下参加。1. 首尔安巴萨德铂尔曼酒店一开始还好奇为什么要在交通不是特别方便的这家酒店举办培训,去...
学校事务自动化——利用 AI 检查学生综合素质评价(生记簿)科目别“细部能力及特长事项”
学校事务自动化——利用 AI 检查学生综合素质评价(生记簿)科目别“细部能力及特长事项”
如果要在学校工作里选出一项最无意义、最辛苦、最无聊的,我会选生记簿检查。在初中,学生综合素质评价(生活记录簿)并不那么重要,但在高中它与升学直接相关,因此极其重要。问题在于,这样的生记簿检查最终找的无非就是简单的错别字、禁止填写用语、拼写等。这篇文章就是从这样的疑问开始的。现在这种简单检查,是不是已...
韩国教育博览会(2026)参观后记
韩国教育博览会(2026)参观后记
偶然通过 Instagram 得知了韩国教育博览会的活动信息。去年因为和别的活动撞期没能去成,所以今年无论如何都想去一趟。于是立刻就进行了提前预约。提前预约者的门票是 8,000 韩元,现场登记则是 15,000 韩元。听熟人说教师可以免费入场,但今年并不是这样。1. 入场券发放这次活动在 COEX...
2022 修订课程地球科学内容预览 - 第3单元 太阳系天体与恒星和宇宙的演化
2022 修订课程地球科学内容预览 - 第3单元 太阳系天体与恒星和宇宙的演化
这次是地球科学浏览的最后一篇。打算来看一下第3单元。1. 内容体系第3单元的内容体系,是从之前《地球科学1》的天体单元中删去了系外行星和生命体探测的内容,新增了原本在《地球科学2》中出现的太阳系模型以及日食和月食。和其他单元相比,内容明显有缩减的感觉。2. 第3单元成就标准一览[12지구03-01]...

댓글을 불러오는 중...