向用户提供Excel(xlsx)文件以便在Django(Python)中下载

时间:2014-11-21 13:55:59

标签: python django excel xlsx stringio

我尝试使用Django创建和提供excel文件。我有一个jar文件,它获取参数并根据参数生成一个excel文件,它没有问题。但是,当我试图获取生成的文件并将其提供给用户下载时,文件就会破碎。它的大小为0kb。这是我用于excel生成和服务的代码片段。

def generateExcel(request,id):
    if os.path.exists('./%s_Report.xlsx' % id):
        excel = open("%s_Report.xlsx" % id, "r")
        output = StringIO.StringIO(excel.read())
        out_content = output.getvalue()
        output.close()
        response = HttpResponse(out_content,content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = 'attachment; filename=%s_Report.xlsx' % id
        return response
    else:
        args = ['ServerExcel.jar', id]
        result = jarWrapper(*args) # this creates the excel file with no problem
        if result:
            excel = open("%s_Report.xlsx" % id, "r")
            output = StringIO.StringIO(excel.read())
            out_content = output.getvalue()
            output.close()
            response = HttpResponse(out_content,content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
            response['Content-Disposition'] = 'attachment; filename=%s_Report.xlsx' % id
            return response
        else:
            return HttpResponse(json.dumps({"no":"excel","no one": "cries"}))

我搜索了可能的解决方案并尝试使用File Wrapper,但结果没有改变。我假设我在将xlsx文件读入StringIO对象时遇到问题。但是对于如何解决它没有任何想法

4 个答案:

答案 0 :(得分:8)

为什么您要将文件的内容传递给StringIO,只是为了将StringIO.get_value()分配给本地变量?将file.read()直接分配给变量有什么问题?

def generateExcel(request,id):
    path = './%s_Report.xlsx' % id # this should live elsewhere, definitely
    if os.path.exists(path):
        with open(path, "r") as excel:
            data = excel.read()

        response = HttpResponse(data,content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = 'attachment; filename=%s_Report.xlsx' % id
        return response
    else:
        # quite some duplication to fix down there

现在您可能想要检查文件中是否存在任何内容 - 文件存在的事实并不意味着文件中包含任何内容。请记住,您处于并发上下文中,您可以让一个线程或进程尝试读取该文件,而另一个(=>另一个请求)正在尝试写入该文件。

答案 1 :(得分:4)

除了Bruno所说的,您可能需要以二进制模式打开文件:

excel = open("%s_Report.xlsx" % id, "rb")

答案 2 :(得分:4)

您可以使用此库动态创建Excel工作表。 http://xlsxwriter.readthedocs.io/

有关详细信息,请参阅此页面。感谢@alexcxe

XlsxWriter object save as http response to create download in Django

答案 3 :(得分:0)

我的回答是:

def generateExcel(request,id):
  if os.path.exists('./%s_Report.xlsx' % id):
    file = open('./%s_Report.xlsx' % id, "rb")

    response = HttpResponse(file.read(),content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    response['Content-Disposition'] = 'attachment; filename=%s_Report.xlsx' % id
    return response
  else:
    # quite some duplication to fix down there

为什么使用“rb”?因为 HttpResponse 类的初始化参数是 (self, content=b'', *args, **kwargs),所以我们应该使用 "rb" 并使用 .read() 来获取字节。