用Python写个空课表生成器-Excel文件操作实例
用Python写个空课表生成器
开发背景
刚入大学的CYQ加入了我们学校的学生会,面对繁杂的工作,能“偷懒”就“偷懒”。这不,最近要举办几场活动,部门要安排人员值班,需要十几人的空课表。此时,CYQ自告奋勇,接下了制作任务,没想到,困难重重,效率低下,重复性劳动,小学加减法算得头皮发麻。聪明的CYQ终于在倒下前的那一刻,想起了自己的身份,在午夜时分,完成了这个小程序。
前提准备
Python3.7
安装xlrd,xlwd第三方库
(建议用pip安装,官方原装速度感人,镜像速度贼快)自行百度,python国内镜像源电脑
南昌航空大学官方总课表(这里仅仅是对我们学校的版本,可自行更改源代码,达到自己的需求)
脑子
需求分析
- 能够根据一份总的课程表(有课)生成一份空课表Excel表
- 并能根据开始周数和结束周数进行在线生成
- 操作要求简单,易操作
功能实现(较为简单)
- 生成函数
- 可视化图形界面(日后优化)
问题分析
- 如何实现对xls文件读取呢?
我们借用了第三方库xlrd,xlwd对于这两种函数的介绍,这里不细讲。
我们知道xlrd是用于读取.xls文件的,xlwd是写入.xls文件的,我们可以通过观察,r和w的区别记忆,read和write。
这里有几个关键的用法xrld部分
用于打开一个Excel文件
work_book = xlrd.open_workbook('filename.xls')
获取Excel文件的所有sheet,这里我们暂时不用,因为CYQ的课表只有一个sheet
work_sheets = work_book.sheet_names()
通过索引来访问一个表单
table = work_book.sheet_by_index(0)
获取到文档的行数
nrows = table.nrows
类推这是列数
ncols = table.ncols
通过索引来访问第row_index行的所有数据,以字符串形式返回
table.row_values(row_index)
- 如何实现对xls文件写入操作呢?
xrwd部分
这是对写入文档的编码规定为ascii
workbook = xlwt.Workbook(encoding = 'ascii')
创建一个sheet,名称为sheet_1
里面的cell_overwrite_ok = True参数是为了防止重复操作,导致报错sheet_1 = workbook.add_sheet('sheet_1',cell_overwrite_ok = True)
新建一个样式
style = xlwt.XFStyle()
字体样式
font = xlwt.Font()
字体类型为这个东东
font.name = 'Times New Roman'
实例化
font.bold = True style.font = font
这是最重要的,把Contents写入到sheet_1中的row行col列,用你设置的style来写入(也可以不用style,上面的新建样式就可以省去)
sheet_1.write(row,col,"Contens",style)
- 数据的处理
首先,确定我们要的数据结构
用字典用得方便些
所以用一个字典来存储全部人的数据
all_the_data = {}##存储总的数据
首先获取本目录下的满足要求的文件
import os
files = [d for d in os.listdir('.')]
通过生成器来生成一个文件列表
之后通过一个大循环来获取所需的数据(根据我们课表的特征)
名字在第一行,可以通过正则来匹配
前三行为无效数据,最后一行为无效数据
剩下的为有效数据,通过正则来匹配
大循环开始
for i in files:if (i[-4:]=='.xls' and i != 'Blank_Courses.xls'):work_book = xlrd.open_workbook(i) #open file to read contenswork_sheets = work_book.sheet_names()table = work_book.sheet_by_index(0) # by_name('')sheet()[x]nrows = table.nrowsncols = table.ncolsname = re.findall(' (.*?) ',table.cell(0,0).value)[0]print(name+"OK!\n")course = {}#用一个字典来存储一个循环里面一个人的信息for i in range(nrows-4):#从上往下遍历表单内容li = [] #用一个表存储临时数据for j in table.row_values(i+3):li.append(j)course[i] = li
以上有个判断,从本目录下的所有xls文件,过滤生成文件,加入到程序的处理链条中
匹配一下名字,正则这样写,会更好一点,名字存在name里面
之后从上到下遍历初始数据
为了得到有效信息,我们继续处理
Course = {}
for index in range(len(course)):li_a = [] #创建一个列表,储存每大节课的周for i in range(len(course[index])):#从每大节课遍历if(i==0): #跳过无效数据continueli = []#创建一个小列表,存储星期所对的课data = re.findall(r'\n.*?\n.*?\n(.*?)\n.*?\n',course[index][i])#正则匹配数据for j in data:i.append(j.replace('[周]','').split(',')) #存储到小列表中li_a.append(li) #存储到大列表中Course[index] = li_a #将列表存储到字典中,获得了一个完整的有课表
聪明的你如果对正则感兴趣的话,可以搜索相关资料。
上面我们又对数据进行了处理,将时间匹配到了
程序设计基础
杨老师()
9[周]
B203
我们学校的表单信息是这种格式,正则就按上面这样写
之后我们同理,将数据存储起来
for index in Course:L = []for i in range(len(Course[index])):have = e_to_have(Course[index][i])#生成有课的所有时间点ha_not = e_to_not(have,start,end)#生成无课的区间,和所有点if(index not in all_the_data.keys()):s = '\n'+name #这是else:s = all_the_data[index][i] + '\n' + name #追加写入,不删除之前的我数据temp = ' '#用来判断是不是全员无课的标记for j in ha_not:temp = temp+j+' 'if(temp==' '):L.append(' '+s)#标记在这里添加else :L.append(s+temp)all_the_data[index] = L #存入总的数据字典里
大循环到此结束
以上我们使用了两个函数
def e_to_have(li):L = []for i in li:#传入的i是一个列表,但只有一个元素,用i[0]表示它的值if(len(i[0])<=2):#没有出现-连接(表示区间)时,小于2L.append(i[0])else:sp = i[0].split('-')##进行切片for i in range(int(sp[1])-int(sp[0])+1):#循环加入单点到有课列表L.append(str(int(sp[0])+i))return L
转化为无课的区间或者时间点
def e_to_not(li,start,end):L = []##生成无课单点表for i in range(end-start+1):##循环次数,也表示总的课区间if(str(i+start)not in li):L.append(i+start)#若此单点不在有课表内,就表示无课,加入其中 S = []##生成无课区间和单点po = 0##初始一个区间头for i in range(len(L)-1):if(L[i]+1!=L[i+1]):if(L[po]!=L[i]):S.append(str(L[po])+'-'+str(L[i]))else:S.append(str(L[po]))po = i+1else:if(i==len(L)-2):S.append(str(L[po])+'-'+str(L[i+1]))#此算法要对最后一个要进行特判,才能加入连续区间return S
里面的算法就不细讲了,思路重要
之后我们进行写入操做
将字典里面的数据依次写入到文件里面
#进行写入操作workbook = xlwt.Workbook(encoding = 'ascii')sheet_1 = workbook.add_sheet('NCHU_Blank_Courses',cell_overwrite_ok = True) #create sheet objectstyle = xlwt.XFStyle()font = xlwt.Font()font.name = 'Times New Roman'font.bold = Truestyle.font = font #字体样式设置,可以跳过for index in range(len(all_the_data)):for i in range(len(all_the_data[index])):sheet_1.col(i).width = 256*25sheet_1.row(index).height = 256*25if (all_the_data[index][i][:2] != ' '):sheet_1.write(index,i,all_the_data[index][i],style)else:sheet_1.write(index,i,"全员无课",style)
到这里大概的框架就完成了,接下来就是漫长的迭代过程。或者是shi沉大海
不过我们也不能忘记了用户体验,配置文件README.docx
还是要写一下的,程序开头的初步使用操作也是要写的
程序执行过程中的状态,也是要写的,哪怕甩点什么数据出来也是可以的
麻雀虽小,五脏可还得俱全啊!
最后来甩几张图
最后完整代码
def e_to_have(li):L = []for i in li:##i是一个列表,但只有一个元素,用i[0]表示它的值if(len(i[0])<=2):#没有出现-连接(表示区间)时,小于2L.append(i[0])else:sp = i[0].split('-')##进行切片for i in range(int(sp[1])-int(sp[0])+1):##循环加入单点到有课列表L.append(str(int(sp[0])+i))return Ldef e_to_not(li,start,end):L = []##生成无课单点表for i in range(end-start+1):##循环次数,也表示总的课区间if(str(i+start)not in li):L.append(i+start)##若此单点不在有课表内,就表示无课,加入其中 S = []##生成无课区间和单点po = 0##初始一个区间头for i in range(len(L)-1):if(L[i]+1!=L[i+1]):if(L[po]!=L[i]):S.append(str(L[po])+'-'+str(L[i]))else:S.append(str(L[po]))po = i+1else:if(i==len(L)-2):S.append(str(L[po])+'-'+str(L[i+1]))##此算法要对最后一个要进行特判,才能加入连续区间return Sdef main():print("=========================\n使用前,阅读使用文档(README.docx)\n目前只可以使用南昌航空大学课程表\n请将成员课表(.xls文件)放在本程序目录下\n目录下不要放其他文件\n本程序上级目录尽量不要为中文名\nMADE FOR NCHU WITH PYTHON\n=========================")try:print("请输入课程周数内的合理数字\n")start = int(input("请输入开始周数:\n"))end = int(input("请输入结束周数:\n"))if(start > 25 or start < 0 or end > 25 or end < 0 or start > end):print("请输入课程合理的数字\n你的输入有误,程序自动退出")input()returnexcept:print("请输入合理的数字\n你的输入有误,程序自动退出")input()returnimport re,osimport xlrd #用来读取excel文件,不能修改数据import xlwt #创建Excel文件并对其进行操作,但不能对已有的Excel文件进行修改import xlutils #对已有的Excel文件进行修改all_the_data = {}##存储总的数据files = [d for d in os.listdir('.')]for i in files:if (i[-4:]=='.xls' and i != 'Blank_Courses.xls'):####################################循环体work_book = xlrd.open_workbook(i) #open file to read contenswork_sheets = work_book.sheet_names()table = work_book.sheet_by_index(0) # by_name('')sheet()[x]nrows = table.nrowsncols = table.ncolsname = re.findall(' (.*?) ',table.cell(0,0).value)[0]print(name+"OK!\n")course = {}for i in range(nrows-4):#从上往下遍历li = [] #用一个表存储数据for j in table.row_values(i+3):li.append(j)course[i] = liCourse = {}for index in range(len(course)):li_a = [] #创建一个列表,储存每大节课的周for i in range(len(course[index])):#从每大节课遍历if(i==0): #跳过无效数据continueli = []#创建一个小列表,存储星期所对的课data = re.findall(r'\n.*?\n.*?\n(.*?)\n.*?\n',course[index][i])#正则匹配数据for j in data:li.append(j.replace('[周]','').split(',')) #存储到小列表中li_a.append(li) #存储到大列表中Course[index] = li_a #将列表存储到字典中,获得了一个完整的有课表for index in Course:L = []for i in range(len(Course[index])):have = e_to_have(Course[index][i])ha_not = e_to_not(have,start,end)if(index not in all_the_data.keys()):s = '\n'+nameelse:s = all_the_data[index][i] + '\n' + nametemp = ' 'for j in ha_not:temp = temp+j+' 'if(temp==' '):L.append(' '+s)else :L.append(s+temp)all_the_data[index] = L##############################循环体#进行写入操作workbook = xlwt.Workbook(encoding = 'ascii')sheet_1 = workbook.add_sheet('NCHU_Blank_Courses',cell_overwrite_ok = True) #create sheet objectstyle = xlwt.XFStyle()font = xlwt.Font()font.name = 'Times New Roman'font.bold = Truestyle.font = fontfor index in range(len(all_the_data)):for i in range(len(all_the_data[index])):sheet_1.col(i).width = 256*25sheet_1.row(index).height = 256*25if (all_the_data[index][i][:2] != ' '):sheet_1.write(index,i,all_the_data[index][i],style)else:sheet_1.write(index,i,"全员无课",style)#sheet_1.write(index,i,s,style) #sheet_1.write(r,c,val,style) #write dates in the sheet whith style workbook.save('Blank_Courses.xls')print("=========================\nCongratulations!生成空课表成功!\n若程序出现问题可以互相交流QQ1614143338\n=========================")input()
# print(Course)if __name__ == '__main__':main()
写的不是很好,由于写入文件需要在同一函数中,创建文件和保存文件,导致很难再拆分主函数里面的功能。那就为了代码的集中,区域模块化,干脆就把读取数据也写入到主函数中。上述的原因导致不能较好的模块化程序,引发一些程序的漏掉和不稳定性,望大佬们指正。也可以一起交流学习。
用Python写个空课表生成器-Excel文件操作实例相关推荐
- python自动化之excel文件操作
excel文件操作 首先为什么要讲excel文件操作呢,因为一般用到的自动化框架中大部分都是用excel存放测试用例数据,是数据驱动的来源. 一.安装 本次分享的是通过openpyxl 这个模块来操作 ...
- excel数据导入python后不对齐_Python处理Excel文件的实用姿势
真正的勇士,敢于直面银行卡上的余额,敢于正视磅秤上的数字. 表格数据是最常见的数据类型,Excel是日常办公中最常接触的文件. 上一章提过Python可以通过openpyxl模块处理Excel文件. ...
- python 导出大量数据到excel_怎么在python中将大量数据导出到Excel文件
怎么在python中将大量数据导出到Excel文件 发布时间:2021-01-16 11:09:40 来源:亿速云 阅读:76 作者:Leah 这期内容当中小编将会给大家带来有关怎么在python中将 ...
- Python使用xlwt和xlrd读写excel文件
Python使用xlwt和xlrd读写excel文件 xlwt和xlrd是两个相互配套的模块,在Python中,用于将数据写入Excel文件和读取Excel文件的数据. 从字面即可看出xlwt是对xl ...
- 使用Python批量筛选上千个Excel文件中的某一行数据并另存为新Excel文件(下篇)
点击上方"Python爬虫与数据挖掘",进行关注 回复"书籍"即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 野火烧不尽,春风吹又生. 大家好, ...
- Python使用openpyxl和pandas处理Excel文件实现数据脱敏案例一则
推荐图书: <Python程序设计(第3版)>,(ISBN:978-7-302-55083-9),清华大学出版社,2020年6月第1次印刷 送书活动火爆进行中:董老师又双叒叕送书啦,30本 ...
- 使用Python解决对比出两个Excel文件中的不同项并将结果重新写入一个新的Excel文件
使用Python解决对比出两个Excel文件中的不同项并将结果重新写入一个新的Excel文件 因为有统计成员到会情况的任务,每次汇总时都很麻烦,需要一个个对应腾讯会议导出名单的成员,然后在总表上进行标 ...
- python 横向合并_使用Python横向合并excel文件的实例
起因: 有一批数据需要每个月进行分析,数据存储在excel中,行标题一致,需要横向合并进行分析. 数据示意: 具有多个 代码: # -*- coding: utf-8 -*- "" ...
- python处理excel教程实例-python 读写excel文件操作示例【附源码下载】
本文实例讲述了python 读写excel文件操作.分享给大家供大家参考,具体如下: 对excel文件的操作,python有第三方的工具包支持,xlutils,在这个工具包中包含了xlrd,xlwt等 ...
最新文章
- .NET弹出对话框小结
- DBGridEh使用指南
- “10亿赌约”董明珠赢了!格力电器2018年总收入超2000亿
- android布局错,Android Studio布局错误
- 第十二课:OpenGL扩展
- Hilbert变换器
- TRNSYS模块中英文对照
- Python源码学习笔记:Python万物皆对象
- 购买一台服务器安装 青龙面版 撸京豆 ~超详细~
- U3D Shader
- 2020家用千兆路由器哪款好_家用千兆路由器哪款好(2020年千兆路由器排行榜)...
- iphone控制中心自定义没有计算机,如何在iPhone上自定义iOS 11控制中心功能
- JAVA音视频解决方案----视频基础知识
- 业务设计师(产品经理)P级晋升必备职能(P3-P7)
- android手机电视互动,安卓手机投屏酷开电视如何实现 多屏互动这么玩
- python期末大作业_上海交通大学python期末大作业题目(姚天昉)
- Oracle数据库版本
- 2022年吉林最新中级消防员模拟试题题库及答案
- Python搭建博客网站小结
- 《请别叫我奥特曼,我只是你望尘莫及的神话》