django 动态生成 csv、xls 文件下载

2019-03-12 17:23:33   最后更新: 2019-03-12 17:23:33   访问数量:1467




有的时候,我们的网站需要为使用者提供 CSV 或 EXCEL 文件的下载

最简单的方法是后台生成文件,放在服务器固定的路径下,然后生成链接指向静态文件,这样做有以下好处:

  1. 实现简单
  2. 文件可以提前生成,从而加速页面响应
  3. 网站维护者可以对文件进行统一管理
  4. 文件可以放在固定的静态资源服务器上,这从服务的安全性与可维护性上都有很大的好处

 

但这样的做法也有以下问题:

  1. 占用硬盘资源
  2. 如果必须依赖动态数据,访问页面时先生成文件后下载显然十分耗时
  3. 已生成 URL 不便于管理
  4. 权限不容易控制

 

可见,对于使用动态数据在每次访问实时生成的 CSV、EXCEL,采用动态生成下载响应而不将文件写入磁盘的方式就有着其必要行了

本文,我们就来介绍如何在 django 中动态生成和下载 CSV、EXCEL 文件

 

 

要点

有以下需要注意的地方:

  • http 协议中,header 中包含说明文件类型的字段 Content-Type,默认为 html,对于动态生成的 csv 文件 Content-Type 字段应取值 text/csv
  • http 协议中,header 包含另一个字段 Content-Disposition,默认为 inline,表示浏览器需要渲染页面,我们需要让 Content-Disposition 字段取值为 attachment 从而让浏览器下载文件
  • 在 Content-Disposition 字段取值为 attachment 时,还需要设置 filename 字段,指定下载的文件名称

这样我们就可以来实现 CSV 文件的动态生成了

 

小 CSV 文件生成

def index(request): response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = "attachment;filename='abc.csv'" writer = csv.writer(response) writer.writerow(['username','age','height', 'weight']) writer.writerow(['zhiliao','18','180','100']) # 在这里并不会指定文件名字。 return response

 

 

通过模板的方式生成动态 CSV 文件

我们知道,CSV 文件的本质是逗号分隔的文本文件,因此我们通过模板生成这个文本文件

 

  • views.py
def template_csv_view(request): response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = "attachment;filename='abc.csv'" context = { 'rows':[ ['username', 'age', 'height', 'weight'], ['zhiliao', '18', '180', '100'] ] } template = loader.get_template('abc.txt') csv_template = template.render(context) response.content = csv_template return response

 

 

  • template
{% for row in rows %}{{ row.0 }},{{ row.1 }},{{ row.2 }},{{ row.3 }} {% endfor %}

 

 

  • 注意

  1. 这里for后面不能换行,如果换行了之后那么生成的csv文件就会每写入一行数据,就会空一行
  2. {% endfor %} 必须换行,否则数据将会全部显示在一行

 

通过 StreamingHttpResponse 动态生成 CSV

动态生成文件,最常用的就是流式响应,流式响应最大的优势在于其资源的节省与高效

代码实现也比较简单

def large_csv_view(request): response = StreamingHttpResponse(content_type='text/csv') response['Content-Disposition'] = "attachment;filename='abc.csv'" rows = ("{},{}\n".format(row,row) for row in range(1,100000)) response.streaming_content = rows return response

 

 

excel 文件的构成要比 CSV 文件复杂的多,我们可以用 xlwt 模块来操作 excel

def export_users_xls(request): response = HttpResponse(content_type='application/ms-excel') response['Content-Disposition'] = 'attachment; filename="abc.xls"' wb = xlwt.Workbook(encoding='utf-8') ws = wb.add_sheet('Menu') # Sheet header, first row row_num = 0 font_style = xlwt.XFStyle() font_style.font.bold = True # 表头内容 columns = ['id','Mname'] for col_num in range(len(columns)): ws.write(row_num, col_num, columns[col_num], font_style) # Sheet body, remaining rows font_style = xlwt.XFStyle() # 获取数据库数据 rows = models.Menu.objects.all().values_list('id','Mname') for row in rows: row_num += 1 for col_num in range(len(row)): ws.write(row_num, col_num, row[col_num], font_style) wb.save(response) return response

 

 

欢迎关注微信公众号,以技术为主,涉及历史、人文等多领域的学习与感悟,每周三到七篇推文,全部原创,只有干货没有鸡汤

 

 

https://blog.csdn.net/xujin0/article/details/84027222

https://blog.csdn.net/bbwangj/article/details/86526245

 






python      http      django      csv      xls      excel      下载     


京ICP备2021035038号