Django: openpyxl saving workbook as attachment

后端 未结 3 493
既然无缘
既然无缘 2020-12-31 02:02

Hi I have a quick question. I didn\'t find answer in internet maybe someone of you can help me.

So i want to save workbook as attachment but I don\'t know how lets s

相关标签:
3条回答
  • 2020-12-31 02:03

    On at least some versions of django/python/openpyxl, the given solution does not work. See https://bitbucket.org/openpyxl/openpyxl/issues/657/save_virtual_workbook-generates-junk-data

    Simple working solution:

    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)
    

    What's happening here is that Django's HttpResponse is a file-like object. Workbook.save() can take a file-like object. (Internally, it uses zipfile, which takes either a filename or a file-like object.)

    If you're manipulating the file in memory, this is the simplest and probably most efficient solution. A streaming response doesn't really make sense since the data is not being created with a generator. Even if save_virtual_workbook works, the data it writes is generated as a block before it's readable.

    The other option would be to create a NamedTemporaryFile (from tempfile or Django's wrapper), pass that into Workbook.save(), then use FileResponse to stream that from the filesystem instead of from memory.

    0 讨论(0)
  • 2020-12-31 02:11

    I usually use

    ws = wb.add_sheet("Pi")
    

    instead of

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

    Moreover, you can try to do: (see documentation)

    wb.save(stream)
    

    and then use stream in HttpResponse.

    0 讨论(0)
  • 2020-12-31 02:24

    Give it a try:

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

    save_virtual_workbook was specially designed for your use case. Here's a docstring:

    """Return an in-memory workbook, suitable for a Django response."""

    0 讨论(0)
提交回复
热议问题