從零開始搭建django前後端分離專案 系列五(實戰之excel流式匯出)
阿新 • • 發佈:2018-12-11
專案中有一處功能需求是:需要在歷史資料查詢頁面進行查詢欄位的選擇,然後由後臺資料庫動態生成對應的excel表格並下載到本地。
如果檔案較小,解決辦法是先將要傳送的內容全生成在記憶體中,然後再一次性傳入Response物件中;
如果檔案較大時,我們可以考慮向HttpResponse傳遞一個迭代器,流式的向客戶端傳遞資料。
view.py檢視
@csrf_exempt def exportData(request): format = request.GET.get('format') pk = request.GET.get('pk') export_sql=SqlModel.objects.get(pk=pk).export_sqlif format=='csv': response = StreamingHttpResponse((row for row in FileHandle.csv_stream_response_generator(export_sql)),content_type="text/csv;charset=utf-8") response['Content-Disposition'] = 'attachment; filename="query_result.csv"' return response
迭代生成器
def csv_stream_response_generator(export_sql): db= MySQLdb.connect("10.39.211.198", "root", "password", "busycell", charset='utf8') chunk_size = 30000 offset = 0 yield codecs.BOM_UTF8 while True: isHeader = False print(offset) if offset == 0: isHeader = True sql=export_sql + " limit {1} offset {0}".format(offset, chunk_size) df = pd.read_sql(sql, db) f = StringIO() df.to_csv(f, index=False, header=isHeader, encoding="utf_8_sig") yield f.getvalue() offset += chunk_size if df.shape[0] < chunk_size: break
最終實現分塊向前端傳遞資料