22

嗨,我有一个快速的问题。我在互联网上没有找到答案,也许你们中的某个人可以帮助我。

所以我想将工作簿另存为附件,但我不知道如何让我们看一个例子:

    from openpyxl import Workbook
    from openpyxl.cell import get_column_letter
    wb = Workbook(encoding='utf-8')
    dest_filename = 'file.xlsx'
    ws = wb.worksheets[0]
    ws.title = "range names"
    for col_idx in xrange(1, 40):
        col = get_column_letter(col_idx)
        for row in xrange(1, 600):
            ws.cell('%s%s'%(col, row)).value = '%s%s' % (col, row)
    ws = wb.create_sheet()
    ws.title = 'Pi'
    ws.cell('F5').value = 3.14

然后我尝试了:

response = HttpResponse(wb, content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename="foo.xls"'
return response

它确实返回 xlsx 文件,但在文件中只有对象地址而不是文件的内容:

<openpyxl.workbook.Workbook object at 0x00000000042806D8>

有人可以帮忙吗?

4

3 回答 3

37

试试看:

from openpyxl.writer.excel import save_virtual_workbook
...
response = HttpResponse(save_virtual_workbook(wb), content_type='application/vnd.ms-excel')

save_virtual_workbook专为您的用例而设计。这是一个文档字符串:

"""返回一个内存工作簿,适合 Django 响应。"""

于 2013-04-15T13:50:36.297 回答
4

我通常使用

ws = wb.add_sheet("Pi")

代替

ws = wb.create_sheet()
ws.title = "Pi"

此外,您可以尝试这样做:(请参阅文档

wb.save(stream)

然后在 HttpResponse 中使用流。

于 2013-04-15T13:31:43.820 回答
4

至少在 django/python/openpyxl 的某些版本上,给定的解决方案不起作用。请参阅https://bitbucket.org/openpyxl/openpyxl/issues/657/save_virtual_workbook-generates-junk-data

简单的工作解决方案:

wb = Workbook(write_only=True, encoding='utf-8')
ws = wb.create_sheet()
for row in data:
    ws.append([str(cell) for cell in row])
response = HttpResponse(content_type='application/vnd.ms-excel')
wb.save(response)

这里发生的是 Django 的 HttpResponse 是一个类似文件的对象。Workbook.save()可以采用类似文件的对象。(在内部,它使用zipfile,它采用文件名或类似文件的对象。)

如果您在内存中操作文件,这是最简单且可能最有效的解决方案。流式响应实际上没有意义,因为数据不是使用生成器创建的。即使 save_virtual_workbook 工作,它写入的数据在可读之前作为一个块生成。

另一种选择是创建一个 NamedTemporaryFile (来自tempfile或 Django 的包装器),将其传递给Workbook.save(),然后使用FileResponse从文件系统而不是从内存中流式传输。

于 2016-07-27T19:13:08.640 回答