Word自动化排版画图,Python还能这么玩?
作者 | 李秋键
责编 | 晋兆雨
头图 | CSDN下载自视觉中国
继我们上次用Python实现Excel排版程序之后,我们这次通过使用Python建立Word自动排版程序。其中涉及的知识包括Word表格,字体大小粗细,布局,图表自动生成和计算等一件生成。通过程序一键计算Excel中的数据生成我们需要的标准Word文件,可以极大程度的减少我们的日常工作量,同时可以节省我们的时间。而我们相对于多使用Python去编程的原因,也正是因为Python相对简单容易上手,可以极大的节省我们的时间。
故这次我们将利用Python的一些基本绘图库、计算库、操作Word库等库去实现我们这次的自动化Word生成程序。最终生产的Word效果如下:
实验前的准备
首先我们使用的Python版本是3.6.5所用到的模块如下:
xlrd库,Python操作Excel主要用到xlrd和xlwt这两个库,即xlrd是读Excel,xlwt是写Excel的库。
math模块用来调用常见的运算函数。
matplotlib模块是 Python的绘图库。它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案。它也可以和图形工具包一起使用,如PyQt 和wxPython。
Docx库即为Python-docx包,这是一个很强大的包,可以用来创建docx文档,包含段落、分页符、表格、图片、标题、样式等几乎所有的Word文档中能常用的功能都包含了,这个包的主要功能便是用来创建文档。
下面我们需要将需要处理的数据文件放到同一目录下,部分文件数据如下图:
其中需要用到的三个文件分别是2019年期中成绩.xlsx、2019上机械制图平时成绩.xlsx和2019上机械制图期末成绩.xlsx。
数值计算
(1)处理2019上机械制图平时成绩.xlsx表格数据:
首先我们需要读取Excel中的数据,分别读取第一列等数据。代码如下:
'''计算平时成绩'''
excel_address="2019上机械制图平时成绩.xlsx"
workbook = xlrd.open_workbook(excel_address)
sheet1 = workbook.sheet_by_name("Sheet1")
col0 = sheet1.col_values(0) # 获取第1列内容,学号那一列
col1 = sheet1.col_values(1) # 获取第2列内容
col2 = sheet1.col_values(2) # 获取第3列内容
col3 = sheet1.col_values(3) # 获取第4列内容
col4 = sheet1.col_values(4) # 获取第5列内容
col5 = sheet1.col_values(5) # 获取第6列内容
col6 = sheet1.col_values(6)
col7 = sheet1.col_values(7)
col8 = sheet1.col_values(8)
col9 = sheet1.col_values(9)
col10 = sheet1.col_values(10)
col11 = sheet1.col_values(11)
col12 = sheet1.col_values(12)
然后通过叠加,计算1-5周的成绩总和、6-8周成绩总和和第9周、10-12周成绩总和,然后求取平均,分别保存为A1、A2、A3、A4变量,代码如下:
'''叠加,1-5周成绩总和,然后平均'''
sum1=0
for i in col1[1:]:
sum1+=i
for i in col2[1:]:
sum1+=i
for i in col3[1:]:
sum1+=i
for i in col4[1:]:
sum1+=i
for i in col5[1:]:
sum1+=i
A1=round((sum1/(len(col1[1:])*5))*41.7/100,1)
'''叠加,6-8周成绩总和,然后平均'''
sum2=0
for i in col6[1:]:
sum2+=i
for i in col7[1:]:
sum2+=i
for i in col8[1:]:
sum2+=i
A2=round((sum2/(len(col6[1:])*3))*25/100,1)
'''叠加,9周成绩总和,然后平均'''
sum3=0
for i in col9[1:]:
sum3+=i
A3=round((sum3/(len(col9[1:])*1))*8.3/100,1)
'''叠加,10-12周成绩总和,然后平均'''
sum4=0
for i in col10[1:]:
sum4+=i
for i in col11[1:]:
sum4+=i
for i in col12[1:]:
sum4+=i
A4=round((sum4/(len(col10[1:])*3))*25/100,1)
(2)处理2019年期中成绩.xlsx表格数据
同样是读取2019年期中成绩.xlsx表格中的数据,然后求平均,作为需要记录的期中成绩:
'''计算期中成绩'''
excel_address="2019年期中成绩.xlsx"
workbook = xlrd.open_workbook(excel_address)
sheet2 = workbook.sheet_by_name("Sheet1")
col21 = sheet2.col_values(13) # 获取第1列内容,学号那一列
sumqi=0
for i in col21[1:]:
sumqi+=i
B = round((sumqi / (len(col21[1:]) * 1)) * 100 / 100, 1)
(3)处理2019上机械制图期末成绩.xlsx数据
通过处理2019上机械制图期末成绩.xlsx中数据,计算期末成绩,流程和第一步相似,下面直接给出代码:
'''计算期末成绩'''
excel_address = "2019上机械制图期末成绩.xlsx"
workbook = xlrd.open_workbook(excel_address)
sheet3 = workbook.sheet_by_name("Sheet1")
col30 = sheet3.col_values(0) # 获取第1列内容,学号那一列
col31 = sheet3.col_values(1) # 获取第2列内容
col32 = sheet3.col_values(2) # 获取第3列内容
col33 = sheet3.col_values(3) # 获取第4列内容
col34 = sheet3.col_values(4) # 获取第5列内容
col35 = sheet3.col_values(5) # 获取第6列内容
col36 = sheet3.col_values(6)
col37 = sheet3.col_values(7)
col38 = sheet3.col_values(8)
col39 = sheet3.col_values(9)
col310 = sheet3.col_values(10)
col311 = sheet3.col_values(11)
col312 = sheet3.col_values(12)
col313 = sheet3.col_values(13)
'''叠加,计算内容1(1~3,11题,23分),然后平均'''
sum31 = 0
for i in col31[1:62]:
sum31 += i
for i in col32[1:62]:
sum31 += i
for i in col33[1:62]:
sum31 += i
for i in col311[1:62]:
sum31 += i
C1 = round(sum31 / (len(col31[1:62])), 1)
'''叠加,内容2(4~8,12题,48分)),然后平均'''
sum32 = 0
for i in col34[1:62]:
sum32 += i
for i in col35[1:62]:
sum32 += i
for i in col36[1:62]:
sum32 += i
for i in col37[1:62]:
sum32 += i
for i in col38[1:62]:
sum32 += i
for i in col312[1:62]:
sum32 += i
C2 = round(sum32 / (len(col32[1:62])), 1)
'''叠加,内容3(9~10题,10分),然后平均'''
sum33 = 0
for i in col39[1:62]:
sum33 += i
for i in col310[1:62]:
sum33 += i
C3 = round(sum33 / (len(col32[1:62])), 1)
'''叠加,内容4(第13题,19分),然后平均'''
sum34 = 0
for i in col313[1:62]:
sum34 += i
C4 = round(sum34 / (len(col32[1:62])), 1)
zongping=round(0.25*(A1+A2+A3+A4)+0.05*B+0.7*(C1+C2+C3+C4),1)
(4)计算A2值,即为计算平时成绩,部分代码如下
'''计算平时成绩'''
excel_address="2019上机械制图期末成绩.xlsx"
workbook = xlrd.open_workbook(excel_address)
sheet1 = workbook.sheet_by_name("Sheet1")
jun=[]
sum1=0
for i in col1[1:62]:
sum1+=i
jun1=round(sum1/(len(col1[1:62])*col1[63]),2)
jun.append(jun1)
sum2 = 0
sum11 = 0
for i in col11[1:62]:
sum11 += i
jun11 = round(sum11 / (len(col11[1:62]) * col11[63]), 2)
jun.append(jun11)
sum12 = 0
for i in col12[1:62]:
sum12 += i
jun12 = round(sum12 / (len(col12[1:62]) * col12[63]), 2)
jun.append(jun12)
sum13 = 0
for i in col13[1:62]:
sum13 += i
jun13 = round(sum13 / (len(col13[1:62]) * col13[63]), 2)
jun.append(jun13)
score=jun1*4+jun2*8+jun3*5+jun4*8+jun5*8+jun6*10+jun7*8+jun8*5+jun9*6+jun10*4+jun11*6+jun12*9+jun13*19
score=round(score,1
)
如下图可见,其为计算出的数据:
Word自动排版生成
(1)表格绘制:
在计算好数据之后,需要将数据建立表格放到其中,其中同时也涉及到了字体加粗、行高布局等设置,具体代码有注释,部分代码如下图可见:
#第一个表的绘制
def table1():
# 背景色设计
def tabBgColor(table, cols, colorStr):
shading_list = locals()
for i in range(cols):
# shading_list['shading_elm_'+str(i)]= parse_xml(r'<w:shd {}w:fill="{bgColor}"/>'.format(nsdecls('w'),bgColor = colorStr))
table.rows[0].cells[i]._tc.get_or_add_tcPr().append(
parse_xml(r'<w:shd {} w:fill="{bgColor}"/>'.format(nsdecls('w'), bgColor=colorStr)))
table.rows[1].cells[i]._tc.get_or_add_tcPr().append(
parse_xml(r'<w:shd {} w:fill="{bgColor}"/>'.format(nsdecls('w'), bgColor=colorStr)))
document = Document()
document.styles['Normal'].font.name = u'等线 (中文正文)'
# 背景色,根据需要调整,可参考站长之家选色http://tool.chinaz.com/Tools/PageColor.aspx
colorStr = '#D3D3D3 '
paragraph =document.add_paragraph()
paragraph.paragraph_format.alignment= WD_ALIGN_PARAGRAPH.CENTER
document.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'等线 (中文正文)')
run = paragraph.add_run('表1 课程评价考核基本信息表 ')
# 加粗
run.font.bold = True
run.font.size =Pt(10.5)
table = document.add_table(rows=4, cols=11, style='Table Grid')
table.alignment =WD_TABLE_ALIGNMENT.CENTER # 设置表格为居中对齐
table.autofit = False
# 背景颜色设计
tabBgColor(table, 11, colorStr)
# 行高
table.rows[0].height = Cm(0.82)
table.rows[1].height = Cm(0.82)
table.rows[2].height = Cm(0.82)
table.rows[3].height = Cm(2)
'''填写单元格'''
table.cell(0, 0).merge(table.cell(1, 0)) # 合并单元格
table.cell(0, 0).width = Cm(1.8)
table.cell(0, 0).text = "课程目标评价内容"
table.cell(0, 0).paragraphs[0].runs[0].font.bold = True # 加粗
table.cell(0, 0).paragraphs[0].runs[0].font.size = Pt(9) # 字号大小
table.cell(0, 0).vertical_alignment = WD_ALIGN_VERTICAL.CENTER # 垂直居中
生成的表格如下图可见:
(2)可视化图形插入:
我们需要分别绘制柱状图和饼状图等插入到word中,部分代码如下:
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import numpy as np
font = FontProperties(fname=r"C:\Windows\Fonts\simhei.ttf", size=14)
jun,score=dels2()
x=[1, 2,3,4,5,6,7,8,9,10,11,12,13]
y=jun
# 定义函数来显示柱状上的数值
def autolabel(rects):
for rect in rects:
height = rect.get_height()
plt.text(rect.get_x() + rect.get_width() / 2. - 0.25, 1.01 * height, '%s' % float(height))
plt.xticks(np.arange(len(x)), x)
color=[]
for i in jun:
if i*100<score:
color.append('cornflowerblue')
else:
color.append('olivedrab')
color[jun.index(min(jun))]='r'
a = plt.bar(np.arange(len(x)), y, color=color)
autolabel(a)
plt.hlines(score/100, 0, 13, linestyles='--', colors='#4472C4')
plt.legend()
plt.xlabel('题号',FontProperties=font)
plt.ylabel('得分率',FontProperties=font)
plt.savefig("1.jpg")
plt.show()
document = Document('test.docx')
document.styles['Normal'].font.name = u'宋体'
document.add_picture('1.jpg', width=Inches(6.0), height=Inches(4.0))
paragraph = document.add_paragraph()
paragraph.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER # 居中
document.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
run = paragraph.add_run('图1 各试题得分率情况\n从上面图和表可以看出,有4道题低于平均分,分别是第6、9、10、12和13题。')
run.font.size = Pt(11)
run.font.color.rgb = red # 数字部分标红
document.save('test.docx')
源码地址:
https://pan.baidu.com/s/1kQhDX61CmHytw9YygBKwOw
提取码:iq5u
作者简介
更多精彩推荐