如果想用python做一个Excel模板,类似于出货单之类的模板,而且个别单元格里面的值是根据MySQL数据库里字段的值改变而改变的,并且要生成的模板不止一个,那么就可以用这种方式来帮你实现了。好了,废话不多说,直接来看实现方法。
先展示一下效果图:
首先,有一些地方得注意:
1.单元格的坐标是从最左上开始算的,所以最左上的坐标是(0,0),也就是A1单元格的坐标是(0,0),所以后面使用代码定义单元格的时候一定要注意你所填充值得单元格的坐标,不能重复;
2.如果你的模板里有的单元格要空置,一定不能什么都不写,一定要用"单元格=''
"来表示,不然后期会报错:大概意思就是后面的值会覆盖前面的值,及时当前单元格里面没有值,也一定要用“ ’ ’ ”来表示;
3.一定要连接数据库。博主此次是在Django项目里面追加了这个功能,具体做法就是在setting文件中配置好自己的数据库连接,然后在views里面引入想要填充的数据的模板,之后就可以对数据操作了。
然后至于其他问题,来看代码吧!代码也挺详细的。
@uthor:xiaozhi
@Date: 2020-06-02
def export_excel(request):
# 设置HTTPResponse的类型
response = HttpResponse(content_type='application/vnd.ms-excel')
response['Content-Disposition'] = "attachment;filename=product.xlsx"
# 创建一个文件对象
wb = xlwt.Workbook(encoding='utf-8')
# 创建一个sheet对象
sheet = wb.add_sheet('shop1')
# 设置列宽
col = sheet.col(0)
col1 = sheet.col(1)
col2 = sheet.col(2)
col3 = sheet.col(3)
col.width = 256*28
col1.width = 256*20
col2.width = 256*25
col3.width = 256*32
# 设置字体样式
style_heading = xlwt.easyxf("""
font:
name Arial,
colour_index black,
bold on,
height 340;
align:
wrap off,
vert center,
horiz center;
pattern:
pattern solid,
fore-colour 0x37;
borders:
left THIN,
right THIN,
top THIN,
bottom THIN;
""")
style_heading1 = xlwt.easyxf("""
font:
name Arial,
height 340;
pattern: pattern solid;
borders:
left THIN,
right THIN,
top THIN,
bottom THIN;
""")
data_row1 = 1
data_row2 = 2
data_row4 = 4
# Product为模型类
data = Product.objects.filter().values('此处为数据库字段1','此处为数据库字段2','此处为数据库字段3',
'此处为数据库字段4','此处为数据库字段5','此处为数据库字段6','此处为数据库字段7')
testData = data.filter().values('此处为数据库字段1','此处为数据库字段2','此处为数据库字段3',
'此处为数据库字段4','此处为数据库字段5','此处为数据库字段6','此处为数据库字段7')
for i,j in zip(testData,range(len(testData))): # 这里理解i, j的含义很重要
# 写入文件标题,下面"单元格坐标 + 7 * j"是因为这7个字段要不断重复填充到模板内的相应位置,如果不考虑这一步,就会一直报错:后面的值会覆盖前面的值。
sheet.write(0 + 7 * j, 0, '', style_heading1)
sheet.write(0 + 7 * j, 1, '信息单', style_heading)
sheet.write(0 + 7 * j, 2, '', style_heading1)
sheet.write(0 + 7 * j, 3, '', style_heading1)
sheet.write(1 + 7 * j, 0, '忍者归属:', style_heading)
sheet.write(2 + 7 * j, 0, '忍者:', style_heading)
sheet.write(2 + 7 * j, 2, '查克拉属性:', style_heading)
sheet.write(3 + 7 * j, 0, '生日', style_heading)
sheet.write(3 + 7 * j, 1, '代表', style_heading)
sheet.write(3 + 7 * j, 2, '忍者登记号码', style_heading)
sheet.write(3 + 7 * j, 3, '所属家族', style_heading)
sheet.write(data_row1 + 7 * j, 1, i['此处为数据库字段1'],style_heading1) # 1,1
sheet.write(data_row1 + 7 * j, 2, '', style_heading1)
sheet.write(data_row1 + 7 * j, 3, '', style_heading1)
sheet.write(data_row2 + 7 * j, 1, i['此处为数据库字段2'], style_heading1) # 2,1
sheet.write(data_row2 + 7 * j, 3, i['此处为数据库字段3'], style_heading1) # 2,3
sheet.write(data_row4 + 7 * j, 0, i['此处为数据库字段4'], style_heading1) # 4,0
sheet.write(data_row4 + 7 * j, 1, i['此处为数据库字段5'], style_heading1) # 4,1
sheet.write(data_row4 + 7 * j, 2, i['此处为数据库字段6'], style_heading1) # 4,2
sheet.write(data_row4 + 7 * j, 3, i['此处为数据库字段7']), style_heading1)
# 写出到IO
output = BytesIO()
wb.save(output)
# 重新定位到开始
output.seek(0)
response.write(output.getvalue())
return response
其实还有很多功能需要完善,比如样式的美化,每个模板占用一页纸的话还需要考虑加入分页符等等,如果你觉得这篇文章对你还有点帮助,请转发分享并点赞吧!!!(转载请保留作者署名和文章出处)