【问题标题】:Serving Excel(xlsx) file to the user for download in Django(Python)将 Excel(xlsx) 文件提供给用户以在 Django(Python) 中下载
【发布时间】:2015-01-19 16:40:42
【问题描述】:

我正在尝试使用 Django 创建和提供 excel 文件。我有一个 jar 文件,它获取参数并根据参数生成一个 excel 文件,它可以正常工作。但是,当我试图获取生成的文件并将其提供给用户以供下载时,文件会损坏。它的大小为 0kb。这是我用于生成和服务的代码片段。

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 对象时遇到问题。但不知道如何解决它

【问题讨论】:

    标签: python django excel xlsx stringio


    【解决方案1】:

    到底为什么要将文件内容传递给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
    

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

    【讨论】:

    • 感谢您的回答。问题不是以二进制模式读取文件,但我还使用您的反馈更新了我的代码。希望它看起来更好:) pastebin.com/ydzR2uuP
    • SO 不是进行代码审查的地方(您可能想查看 codereview.stackexchange.com),但这里是答案pastebin.com/e4zRAW5U
    【解决方案2】:

    除了布鲁诺说的,你可能还需要以二进制模式打开文件:

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

    【讨论】:

    • 这也解决了由于文件未以二进制模式打开而导致的编码错误。谢谢
    【解决方案3】:

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

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

    XlsxWriter object save as http response to create download in Django

    【讨论】:

      【解决方案4】:

      我的答案是:

      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() 来获取字节。

      【讨论】:

      • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
      • 卡罗尔先生您好,感谢您的更正:)
      猜你喜欢
      • 2017-09-22
      • 2017-10-09
      • 1970-01-01
      • 1970-01-01
      • 2013-03-25
      • 1970-01-01
      • 2021-10-24
      • 2015-09-17
      • 1970-01-01
      相关资源
      最近更新 更多