2014-12-10 1 views
1

, например, следующий код сначала создает файл xlsx, а затем передает его в виде загрузки, но мне интересно, можно ли отправлять данные xlsx по мере его создания. Например, представьте себе, нужно ли генерировать очень большой файл xlsx, пользователю нужно подождать, пока он не будет завершен, а затем получить загрузку, то, что я хочу, - это запустить загрузку файла xlsx в браузере пользователя, а затем отправить над данными по мере их создания. Это кажется тривиальным с CSV-файлом, но не с файлом xlsx.Python: сгенерировать xlsx в памяти и загрузить файл потока?

try: 
    import cStringIO as StringIO 
except ImportError: 
    import StringIO 

from django.http import HttpResponse 

from xlsxwriter.workbook import Workbook 


def your_view(request): 
    # your view logic here 

    # create a workbook in memory 
    output = StringIO.StringIO() 

    book = Workbook(output) 
    sheet = book.add_worksheet('test')  
    sheet.write(0, 0, 'Hello, world!') 
    book.close() 

    # construct response 
    output.seek(0) 
    response = HttpResponse(output.read(), mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") 
    response['Content-Disposition'] = "attachment; filename=test.xlsx" 

    return response 

ответ

4

Можете ли вы написать tempfile s на диск при создании XLSX?

Если вы в состоянии использовать tempfile, вы не будете привязаны к памяти, что приятно, но загрузка будет продолжаться только тогда, когда писатель XLSX будет готов к сборке документа.

Если вы не можете написать tempfile s, вам необходимо следовать этому примеру http://xlsxwriter.readthedocs.org/en/latest/example_http_server.html, и ваш код, к сожалению, полностью связан с памятью.

Потоковая передача CSV очень проста, с другой стороны. Вот код, который мы используем, чтобы поток любого итератора строк в ответ CSV:

import csv 
import io 


def csv_generator(data_generator): 
    csvfile = io.BytesIO() 
    csvwriter = csv.writer(csvfile) 

    def read_and_flush(): 
     csvfile.seek(0) 
     data = csvfile.read() 
     csvfile.seek(0) 
     csvfile.truncate() 
     return data 

    for row in data_generator: 
     csvwriter.writerow(row) 
     yield read_and_flush() 


def csv_stream_response(response, iterator, file_name="xxxx.csv"): 

    response.content_type = 'text/csv' 
    response.content_disposition = 'attachment;filename="' + file_name + '"' 
    response.charset = 'utf8' 
    response.content_encoding = 'utf8' 
    response.app_iter = csv_generator(iterator) 

    return response 
+0

если один открывает файл CSV в Excel, он будет автоматически обновлять с новыми строками, как они будут добавлены? или они должны обновить или повторно открыть файл, чтобы увидеть обновление? – user299709

+0

Поток CSV будет выглядеть так, как будто он загружается в браузере, но поскольку вначале нет размера файла, у него просто есть счетчик прогресса. Пользователи могут открыть CSV до того, как он загрузится, но я думаю, что большинство пользователей увидит, что загрузка все еще продолжается. – rdrey

2

формат XLSX является почтовый файл, который содержит несколько отдельных файлов, так что вы не можете создать его на лету и отправить его, как она создается.