2015-09-16 57 views
3

我有這個功能對於流媒體的文本文件:流生成CSV與瓶

def txt_response(filename, iterator): 
    if not filename.endswith('.txt'): 
     filename += '.txt' 
    filename = filename.format(date=str(datetime.date.today()).replace(' ', '_')) 
    response = Response((_.encode('utf-8')+'\r\n' for _ in iterator), mimetype='text/txt') 
    response.headers['Content-Disposition'] = 'attachment; filename={filename}'.format(filename=filename) 
    return response 

我的工作如何以類似的方式流CSV文件。 This page舉了一個例子,但我希望使用CSV模塊。

我可以使用StringIO併爲每行創建一個新的「文件」和CSV編寫器,但它看起來效率很低。有沒有更好的辦法?

回答

2

根據此答案how do I clear a stringio object?爲文件中的每一行創建一個新的StringIO對象比我在下面使用的方法更快。但是,如果你還是不希望創建新StringIO情況下,你可以達到你想要的東西是這樣的:

import csv 
import StringIO 

from flask import Response 


def iter_csv(data): 
    line = StringIO.StringIO() 
    writer = csv.writer(line) 
    for csv_line in data: 
     writer.writerow(csv_line) 
     line.seek(0) 
     yield line.read() 
     line.truncate(0) 


def csv_response(data): 
    response = Response(iter_csv(data), mimetype='text/csv') 
    response.headers['Content-Disposition'] = 'attachment; filename=data.csv' 
    return response 

如果你只是想因爲它們是由csv.writer創建流回的結果,你可以創建一個自定義對象實現作者期望的接口。

import csv 

from flask import Response 


class Line(object): 
    def __init__(self): 
     self._line = None 
    def write(self, line): 
     self._line = line 
    def read(self): 
     return self._line 


def iter_csv(data): 
    line = Line() 
    writer = csv.writer(line) 
    for csv_line in data: 
     writer.writerow(csv_line) 
     yield line.read() 


def csv_response(data): 
    response = Response(iter_csv(data), mimetype='text/csv') 
    response.headers['Content-Disposition'] = 'attachment; filename=data.csv' 
    return response