Python:在内存中生成xlsx并流式文件下载?

时间:2014-12-10 04:04:44

标签: python

例如,以下代码首先创建xlsx文件,然后将其作为下载流式传输,但我想知道是否可以在创建时发送xlsx数据。例如,假设如果需要生成非常大的xlsx文件,则用户必须等到它完成然后接收下载,我想要的是在用户浏览器中启动xlsx文件下载,并且然后在生成数据时发送数据。使用.csv文件似乎微不足道,但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

2 个答案:

答案 0 :(得分:5)

您是否可以在生成XLSX时将tempfile写入磁盘?

如果您能够使用tempfile,那么您将不会受到内存限制,这很不错,但下载仍将仅在XLSX编写器组装文档时开始。

如果您不能写tempfile,那么您必须遵循此示例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

答案 1 :(得分:3)

xlsx格式是一个包含多个单独文件的zip文件,因此您无法动态创建它并在创建时将其发送出去。