import xlrd
import xlrd
from docxtpl import DocxTemplate, InlineImage
from docx.shared import Mm
import pyecharts
import numpy as np
from random import random
import matplotlib.pyplot as plt
import matplotlib
import os
from docxtpl import DocxTemplate, InlineImage
from docx.shared import Mm
#===================开始设置中文字体=================
font = {
'family' : 'SimHei',
'size' : 20
}
matplotlib.rc('font', **font)
#===================结束设置中文字体=================
class GenerateReport:
def __init__(self, files, stuClass='1.1'):
if not files:
return None
else:
self.files = files
self.radarIndex = 0
# TODO:这种字符串可以用字符串分割方法生成数组
# 反之用数字拼接字符串可以降低拼写的效率
# 怪不得校园宝要设置学科
self.subjects = ['语文','数学','英语','历史','道法','地理','生物','物理']
self.subjects_en = ['chinese','maths','english','history','tao','geography','bio','physical']
self.root = stuClass
def mkdir(path):
if not os.path.isdir(path):
mkdir(os.path.split(path)[0],'/')
else:
return
os.mkdir(path)
if not os.path.exists(self.root):
os.mkdir(self.root)
os.mkdir("/{}/doc".format(self.root))
os.mkdir("/{}/line".format(self.root))
os.mkdir("/{}/radar".format(self.root))
self.dataset = self.processFiles(files)
def setTemplate(self, file):
self.template = file
def paraXls(self, filename):
# TODO:要添加异常处理
# {
# 'stuName': 'langxm',
# 'scores': [
# {
# 'chinese': 80,
# 'math' : 90
# },
# ],
# 'grades': [
# {
# 'chinese': A,
# 'math' : B
# },
# ],
# 'sum': 20,
# 'rank': 20,
# 'total': 20
# }
dataset = {}
wb = xlrd.open_workbook(filename)
sht = wb.sheet_by_index(0)
rows = sht.nrows
cols = sht.ncols
header = sht.row_values(0, 0, cols)
self.students = sht.col_values(0, 1, rows)
# 查询index的代码有待优化
def getIndex(value, valuelist):
# TODO:重名的情况
return valuelist.index(value)
subjectIndexes = [getIndex(subject, header) for subject in self.subjects]
# TODO:numpy的数组加载xls处理效率更高,可以用numpy的np数组改写
for i in range(1, rows):
line = sht.row_values(i, 0, cols)
stuName = line[0]
scores = [line[index] for index in subjectIndexes]
grades = [line[index + 1] for index in subjectIndexes]
examData = {}
item = {}
item['scores'] = scores
item['grades'] = grades # 这些项目都是可以做成可以配置的
# 可以用工厂模式改写
item['total'] = sum(scores)
item['avg'] = sum(scores) / len(subjectIndexes)
examData[stuName] = item
dataset[stuName] = examData
return dataset
def processFiles(self, files):
d = {}
def setValue(key, value):
d[key] = value
[setValue(file, self.paraXls(file)) for file in files]
return d
def drawRadar(self, stuName, index=0):
pass
labels = np.array(self.subjects[index:]) # 标签
dataLenth = len(labels) # 数据长度
angles = np.linspace(0, 2*np.pi, dataLenth, endpoint=False) # 分割圆周长
angles = np.concatenate((angles, [angles[0]])) # 闭合
dataset = []
# stuName = '徐文清'
for file in self.files[index:]:
dataset.append(self.dataset[file][stuName][stuName]['scores'])
polars = []
plt.clf()
for ds in dataset:
ds = np.concatenate((ds, [ds[0]]))
p1, = plt.polar(angles, ds, 'o-', linewidth=1) #做极坐标系
polars.append(p1)
plt.legend(polars,[file[0:-5] for file in self.files[index:]] ,prop={'family':'SimHei'})
plt.thetagrids(angles * 180/np.pi, labels, fontproperties='SimHei') # 设置网格、标签
plt.ylim(0,100) # polar的极值设置为ylim
plt.savefig(self.root + '/radar/{}radar.png'.format(stuName))
pass
plt.close('all')
plt.clf()
labels = np.array(self.subjects) # 标签
fig, ax1 = plt.subplots(figsize=(12,9))
# stuName = '徐文清'
# plt.cla()
for file in self.files:
ax1.plot(labels, self.dataset[file][stuName][stuName]['scores'], label=file[0:-5])
plt.title("{}期中期末成绩折线图".format(stuName),fontproperties='SimHei',fontsize=30)
ax1.legend()
ax1.grid(axis="y",color="grey",linestyle="--",alpha=0.5)
ax1.tick_params(axis="x",labelsize=16)
ax1.tick_params(axis="y",labelsize=16)
ax1.set_ylabel("成绩",fontsize = 16)
ax1.set_xlabel("学科",fontsize = 16)
ax1.set_ylim(0,100)
for tl in ax1.get_yticklabels():
tl.set_color('r')
ax1.spines['top'].set_visible(True)
plt.savefig(self.root + '/line/{}line.png'.format(stuName))
plt.close(0)
def drawLine(self, stuName):
pass
labels = np.array(self.subjects) # 标签
fig, ax1 = plt.subplots(figsize=(12,9))
# stuName = '徐文清'
for file in self.files:
ax1.plot(labels, self.dataset[file][stuName][stuName]['scores'], label=file[0:-5])
plt.title("{}期中期末成绩折线图".format(stuName),fontproperties='SimHei',fontsize=30)
ax1.legend()
ax1.grid(axis="y",color="grey",linestyle="--",alpha=0.5)
ax1.tick_params(axis="x",labelsize=16)
ax1.tick_params(axis="y",labelsize=16)
ax1.set_ylabel("成绩",fontsize = 16)
ax1.set_xlabel("学科",fontsize = 16)
ax1.set_ylim(0,100)
for tl in ax1.get_yticklabels():
tl.set_color('r')
ax1.spines['top'].set_visible(True)
plt.savefig(self.root + '/line/{}line.png'.format(stuName))
plt.close()
def saveDoc(self, stuName):
# plt.clear()
pass
# TODO:模板生成word虽然方便但是写模板变量太烦了
# 后面改成直接生成
doc = DocxTemplate(r"./{}".format(self.template))
dataset = []
# stuName = '徐文清'
context = {}
for file in self.files:
dataset.append(self.dataset[file][stuName][stuName])
context['stuName'] = stuName
for key, ds in enumerate(dataset):
context['file'+str(key)] = self.files[key]
scores = ds["scores"]
for i in range(len(scores)):
context[self.subjects_en[i]+str(key)] = scores[i]
context['linechart'] = InlineImage(doc, 'line/{}line.png'.format(stuName), width=Mm(100))
context['radarchart'] = InlineImage(doc, 'radar/{}radar.png'.format(stuName), width=Mm(100))
doc.render(context)
doc.save(r"./{}/doc/{}.docx".format(self.root, stuName))
def genDocs(self):
for stuName in self.students:
# self.drawLine(stuName)
if stuName == '赵烁源':
continue
self.drawRadar(stuName,index=self.radarIndex)
# TODO:文件名应该是可以配置的包括路径
self.saveDoc(stuName)
print('{}的文档已经生成,位于./{}/doc/{}.docx'.format(stuName, self.root, stuName))
if __name__ == "__main__":
pass
gr = GenerateReport(['86.xlsx','861.xlsx','862.xlsx','863.xlsx'])
gr.setTemplate('86temp.docx')
# gr.drawLine('徐文清')
print(len(gr.students))
gr.genDocs()
# print(gr.dataset)
2020-01-09
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 赚钱、提升自己 这是我2020年人生规划里的两个重大选项,面对人生境遇、面对生活压力,这是目前最需要解决的问题。今...
- 聊聊2020年怎么赚钱? 酣畅淋漓的看完罗胖的跨年演讲,对个人财富的基本盘最感兴趣。 曾鸣教授说:“容易赚的钱肯定...