Python(Django)页面导出Excel表格数据
最近做项目要使用到 导出Excel 的表格,正好有 openpyxl 这个库。
今天给大家分享一下如何使用这个库并在 Django 页面导出Excel表;
首先,安装openpyxl库:
pip install openpyxl
现在,我们可以写我们的代码了。
案例:我们以导出病人到医院的挂号信息为例来讲解 openpyxl 的使用;
导入需要用到的库
首先,在自己的视图函数中导入模块,需要使用到如下的三个模块:
from openpyxl import Workbook # 操作Excel的库
from io import BytesIO # 实现了在内存中读写bytes
from django.utils.http import urlquote # 解决导出Excel文件无法使用中文文件名
openpyxl 库是用来用Python代码操作Excel表的库;
BytesIO 可以实现在内存中读写bytes;
urlquote 该方法为了解决导出Excel文件因无法使用中文文件名的问题;
BytesIO
StringIO 操作的只能是 str ,如果要操作二进制数据,就需要使用 BytesIO ;
BytesIO 实现了在内存中读写 bytes ,我们创建一个 BytesIO ,然后写入一些 bytes :
>>> from io import BytesIO
>>> f = BytesIO()
>>> f.write('中文'.encode('utf-8'))
6
>>> print(f.getvalue())
b'\xe4\xb8\xad\xe6\x96\x87'
请注意,写入的不是 str,而是经过 UTF-8 编码的 bytes;
和 StringIO 类似,可以用一个 bytes 初始化 BytesIO ,然后,像读文件一样读取:
>>> from io import BytesIO
>>> f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
>>> f.read()
b'\xe4\xb8\xad\xe6\x96\x87'
小结
StringIO 和 BytesIO 是在内存中操作 str 和 bytes 的方法, 使得和读写文件具有一致的接口。
定义导出函数export_excel
def export_excel(request):
import datetime
from django.http import HttpResponse
from openpyxl import Workbook
from io import BytesIO
from django.utils.http import urlquote
wb = Workbook() # 生成一个工作簿(即一个Excel文件)
wb.encoding = 'utf-8'
sheet1 = wb.active # 获取第一个工作表(sheet1)
sheet1.title = '挂号信息' # 给工作表1设置标题
row_one = ['门诊编号', '主治医生', '挂号时间', '挂号科室', '状态',
'姓名', '身份证号', '挂号费', '社保号', '联系电话', '是否自费',
'性别', '年龄', '职业', '初复诊', '备注']
for i in range(1, len(row_one)+1): # 从第一行开始写,因为Excel文件的行号是从1开始,列号也是从1开始
# 从row=1,column=1开始写,即将row_one的数据依次写入第一行
sheet1.cell(row=1, column=i).value=row_one[i-1]
all_obj = Registration.objects.all()
for obj in all_obj:
max_row = sheet1.max_row + 1 # 获取到工作表的最大行数并加1
obj_info = [obj.id,obj.doctor.real_name,obj.regist_date,obj.department.department_name,
obj.status,obj.name,obj.id_number,obj.cost,obj.social_num,
obj.phone, obj.is_paying, obj.sex, obj.age, obj.occupation,
obj.is_first, obj.remark]
for x in range(1, len(obj_info)+1): # 将每一个对象的所有字段的信息写入一行内
sheet.cell(row=max_row, column=x).value = obj_info[x-1]
# 准备写入到IO中
output = BytesIO()
wb.save(output) # 将Excel文件内容保存到IO中
output.seek(0) # 重新定位到开始
# 设置HttpResponse的类型
response = HttpResponse(output.getvalue(), content_type='application/vnd.ms-excel')
ctime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
file_name = '挂号信息%s.xls' % ctime # 给文件名中添加日期时间
file_name = urlquote(file_name) # 使用urlquote()方法解决中文无法使用的问题
response['Content-Disposition'] = 'attachment; filename=%s' % file_name
# response.write(output.getvalue()) # 在设置HttpResponse的类型时,如果给了值,可以不写这句
return response
补充一下我们的 model :
注意:我们的模型里有两个关联的字段:department、doctor;
class Registration(models.Model):
"""
患者挂号信息
"""
name = models.CharField(max_length=20, verbose_name='患者姓名')
id_number = models.CharField(max_length=18, verbose_name='患者身份证')
cost = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='挂号费')
social_num = models.CharField(max_length=10, null=True, verbose_name='社保号')
phone = models.CharField(max_length=11, verbose_name='联系电话')
is_paying = models.BooleanField(default=True, verbose_name='是否自费')
sex = models.BooleanField(default=1, verbose_name='性别')
age = models.PositiveSmallIntegerField(null=True, verbose_name='年龄')
occupation = models.CharField(max_length=20, null=True, verbose_name='职业')
is_first = models.BooleanField(default=1, verbose_name='是否是初诊')
regist_date = models.DateTimeField(auto_now_add=True, verbose_name='挂号时间')
status_choice = ((1, '已住院'), (2, '已出院'), (3, '已结算'), (4, '未结算'), (5, '已挂号'), (6, '已退号'))
status = models.PositiveSmallIntegerField(choices=status_choice, verbose_name='患者挂号状态')
department = models.ForeignKey(Department, related_name='registration', on_delete=models.DO_NOTHING, verbose_name='关联科室')
doctor = models.ForeignKey(DoctorManage, related_name='registration', on_delete=models.DO_NOTHING, verbose_name='关联医生')
remark = models.CharField(max_length=100, null=True, verbose_name='备注')
效果
请求我们的视图URL时,会看到:
现在,我们的导出Excel文件功能已初步完成!
本文学习自:在Django中,导出Excel表格,通过使用自己的方法完成!