1. 程式人生 > >從零開始搭建django前後端分離專案 系列五(實戰之excel流式匯出)

從零開始搭建django前後端分離專案 系列五(實戰之excel流式匯出)

專案中有一處功能需求是:需要在歷史資料查詢頁面進行查詢欄位的選擇,然後由後臺資料庫動態生成對應的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_sql
    
if 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

最終實現分塊向前端傳遞資料