|
2022秋学期学校进行了线上期末考试,然而,期末试卷作为学科评估的重要材料,对存档有一定的要求。本文记录了使用程序自动化办公的方法,将导出的试卷批量重命名,并按学号顺序合并为一个PDF文件,提高存档质量,节约打印时间。
“期末试卷打包工具” 下载地址:
https://pan.baidu.com/s/1gYFgCMsOGyl__91DEWL-2g?pwd=sylg
注意:需解压压缩包后程序方能正常使用。
假定导出的word版本的试卷中的指定位置有学生的姓名,我们在教务系统导出的学生名单中找到姓名对应的学号、班级等信息,重命名学生的试卷为“学号+姓名+班级+考试科目.docx”。
学生填写的院系、班级、学号信息都有可能不准确,我们要以教务系统的为唯一标准,通过检索学生的姓名得到对应的院系、班级、学号信息,写入试卷。如果有需要,我们还需要在试卷的指定位置填写阅卷人、核分人的信息。
为方便打印与存档,我们需要写程序将修改后的word版试卷批量导出为pdf文件。
将班级中所有学生的PDF格式试卷合并为一个PDF文件,方便后续打印。
阅读程序实现的细节需要一定的计算机编程基础,不再赘述,python编译使用的源代码附于文末。
“期末试卷打包工具” 下载地址:
https://pan.baidu.com/s/1gYFgCMsOGyl__91DEWL-2g?pwd=sylg
提取码:sylg 复制这段内容后打开百度网盘手机App,操作更方便哦
3个程序使用的核心代码均来自互联网,没有二次开发。解压缩后,有3个文件夹:“1. 生成标准试卷” “2. 生成pdf” “3. 合并PDF”,请按步骤依次运行。
提示:python程序在windows10中编译,如果与你的系统不兼容,请使用源代码重新编译。
res文件夹中有一个名为stuInfo2.json的文件,其格式为:{"学号1":"姓名1","学号2":"姓名2",…},你也可以先将学生信息复制到stu.csv表格中,再通过运行csv2json.exe将csv表格中的内容导出为json文件。其中,csv表格中第一列是学号,第二列是姓名(姓名不能重复)。
将学习通中的试卷复制到程序“修改试卷.exe”所在的文件夹,双击运行。
1#主程序代码
2from win32com import client as wc
3import os
4import docx
5import json
6from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
7from docx.shared import Pt
8import warnings
9from setttings import *
10
11
12def get_stu_info(file_path):
13 file_temp = docx.Document(file_path)
14 paras=file_temp.paragraphs
15 flag=0
16 for para in paras:
17 if para.text.find(name_eigen)>-1:
18 runs = para.text.split(" ")
19 for run in runs:
20 run=run.strip()
21 # 如果姓名关键字后有空格,后面的run就是姓名
22 if flag==1 and len(run)>0:
23 return run.strip()
24
25
26 if len(run)>0 and run.find(name_eigen)>-1:
27 run_splits=run.split(name_eigen)
28 for run_s in run_splits:
29 # 如果姓名关键字后没空格,那么姓名紧跟在后面
30 if flag==1 and len(run_s.strip())>0:
31 return run_s
32 if len(run_s.strip())==0:
33 flag=1
34 else:
35 flag=0
36
37
38
39
40
41def insert_stu_num(file_path,stu_num,cls_name,stu_name):
42 file_temp = docx.Document(file_path)
43
44 tables = file_temp.tables
45 for table in tables:
46 for ii in range(len(table.rows)):
47 for jj in range(len(table.columns)):
48 cellData = str(table.cell(ii, jj).text).strip()
49 if cellData.find(calcu_eigen) > -1 and jj+1<len(table.columns):
50 table.cell(ii, jj+1).text=calcu_name
51 table.cell(ii, jj+1).alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
52 table.cell(ii, jj+1). paragraphs[0].runs[0].font.size = Pt(8)
53
54 if cellData.find(marker_eigen) > -1 and jj+1<len(table.columns):
55 table.cell(ii, jj+1).text=marker_name
56 table.cell(ii, jj+1).alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
57 table.cell(ii, jj+1). paragraphs[0].runs[0].font.size = Pt(8)
58
59 if cellData.find(chker_eigen) > -1 and jj+1<len(table.columns):
60 table.cell(ii, jj+1).text=chker_name
61 table.cell(ii, jj+1).alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
62 table.cell(ii, jj+1). paragraphs[0].runs[0].font.size = Pt(8)
63
64
65 paras=file_temp.paragraphs
66 flag=0
67 for para in paras:
68 for run in para.runs:
69 if flag>2:
70 # print("学习通排版后的试卷,正在直接修改学生的班级学号信息...")
71 para.text="院系:"+str(depart_name)+" 班级:"+str(cls_name)+" 姓名:"+str(stu_name)+" 学号:"+str(stu_num)
72 file_temp.save(os.getcwd()+'\\'+str(stu_num)+"+"+str(stu_name)+"+"+str(cls_name)+"+"+str(subject_name)+".docx")
73 return
74
75 if run.text.find(stu_num_eigen)>-1:
76 flag+=1
77 elif run.text.find(cls_eigen)>-1:
78 flag+=1
79 elif run.text.find(depart_eigen)>-1:
80 flag+=1
81 elif run.text.find(major_eigen)>-1:
82 flag+=1
83
84 # 不是学习通的排版后试卷
85 print(str(stu_name),"的试卷不是学习通排版后的格式,效果可能不理想...")
86 for para in paras:
87 for run in para.runs:
88 if run.text.find(stu_num_eigen)>-1:
89 flag=91
90 elif run.text.find(cls_eigen)>-1:
91 flag=92
92 elif run.text.find(depart_eigen)>-1:
93 flag=93
94 elif run.text.find(major_eigen)>-1:
95 flag=94
96 else:
97 flag=0
98
99 if flag==91:
100 run.text=str(stu_num)
101 elif flag==92:
102 run.text=str(cls_name)
103 elif flag==93:
104 run.text=str(depart_name)
105 elif flag==94:
106 run.text=str(major_name)
107
108
109 file_temp.save(os.getcwd()+'\\'+str(stu_num)+"+"+str(stu_name)+"+"+str(cls_name)+"+"+str(subject_name)+".docx")
110 return
111
112if __name__ == '__main__':
113 # 将doc转为docx文件,方便使用docx插件修改word文档
114 # 假定学生试卷和主程序放在一个目录中
115 word = wc.Dispatch("Word.Application")
116 lst_folders = os.listdir()
117
118
119 p_info="正在生成临时文件"
120 print(p_info)
121 ii=0
122 for lst_folder in lst_folders:
123 if str(lst_folder).endswith(".doc"):
124 os.system("cls")
125 ii+=1
126
127 if ii%3==0:
128 p_info="正在生成临时文件 /"
129 elif ii%3==1:
130 p_info="正在生成临时文件 --"
131 else:
132 p_info="正在生成临时文件 \\"
133 print(p_info)
134 doc = word.Documents.Open(os.getcwd()+"\\"+lst_folder)
135 # 为转换好的docx添加前缀,便于更好地区分
136 doc.SaveAs(os.getcwd()+"\\"+prefix_name+"+"+str(lst_folder)+"x", 12)
137 doc.Close()
138 word.Quit()
139
140
141 # 将教务系统中导出的学生信息存储到stuInfo2.json中
142 # json的格式为: "学号": "姓名"
143 with open('./res/stuInfo2.json', 'r', encoding='utf-8') as fp:
144 stu_infos = json.load(fp)
145 os.system("cls")
146 cls_name=input('请输入班级名称:')
147
148 lst_folders = os.listdir()
149 warn_infos=[]
150 for lst_folder in lst_folders:
151 print('.',end="")
152 if str(lst_folder).endswith(".docx") and str(lst_folder).startswith(prefix_name):
153 stu_name=get_stu_info(os.getcwd()+'\\'+lst_folder)
154 stu_num="未找到"
155 for stu in stu_infos:
156 if stu_infos[stu]==stu_name:
157 stu_num=stu
158 break
159 if stu_num=="未找到":
160 warn_infos.append([lst_folder,"姓名:"+str(stu_name)," 学号没有找到"])
161
162 insert_stu_num(os.getcwd()+'\\'+lst_folder,stu_num,cls_name,stu_name)
163 print("\n\n")
164 for warn_info in warn_infos:
165 print(warn_info)
166 input("已完成...")
settings.py,用来读取res文件夹中的配置信息,如阅读人、院系、科目名称等。
1# 配置文件代码
2# settings.py
3
4import os
5import sys, time
6
7
8
9Settings={"文档前缀":" ","考试科目":" ","试卷姓名特征字":"姓名","复核人特征字":"","阅卷人特征字":"","合分人特征字":"","复核人姓名":"","阅卷人姓名":"","合分人姓名":"","院系特征字":"","学号特征字":"","班级特征字":"","专业特征字":"","院系名称":"","专业名称":""}
10
11with open('./res/settings.ini', 'r', encoding='utf-8') as fp:
12 for line in fp:
13 if not line.strip().startswith('\ufeff') and len(line.strip())>2 and not line.strip().startswith("#") and len(line.split('='))>0 and len(line.split('=')[1].strip())>0:
14 Settings[line.split('=')[0].strip()]=line.split('=')[1].strip()
15
16
17
18
19prefix_name=Settings['文档前缀']
20subject_name=Settings['考试科目']
21name_eigen=Settings['试卷姓名特征字']
22chker_eigen=Settings["复核人特征字"]
23chker_name=Settings["复核人姓名"]
24calcu_eigen=Settings["合分人特征字"]
25calcu_name=Settings["合分人姓名"]
26marker_eigen=Settings["阅卷人特征字"]
27marker_name=Settings["阅卷人姓名"]
28depart_eigen=Settings["院系特征字"]
29cls_eigen=Settings["班级特征字"]
30stu_num_eigen=Settings["学号特征字"]
31major_eigen=Settings["专业特征字"]
32depart_name=Settings["院系名称"]
33major_name=Settings["专业名称"]
34
35
36for st in Settings:
37 print(st,"\t",Settings[st])
38print("配置文件中的信息如上表所示,程序将根据word文档中的特征字定位要修改的内容。")
39print("你可以手动修改位于res文件夹中的配置文件:settings.ini")
40print("若要修改配置文件,请在10秒内关闭程序")
41
42for ii in range(10):
43 print(".",end="")
44 sys.stdout.flush()
45 time.sleep(1)
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-11-23 09:13
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社