简体   繁体   English

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

[英]Serving Excel(xlsx) file to the user for download in Django(Python)

I'm trying create and serve excel files using Django.我正在尝试使用 Django 创建和提供 excel 文件。 I have a jar file which gets parameters and produces an excel file according to parameters and it works with no problem.我有一个 jar 文件,它获取参数并根据参数生成一个 excel 文件,它可以正常工作。 But when i'm trying to get the produced file and serve it to the user for download the file comes out broken.但是,当我尝试获取生成的文件并将其提供给用户下载时,该文件已损坏。 It has 0kb size.它的大小为 0kb。 This is the code piece I'm using for excel generation and serving.这是我用于 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"}))

I have searched for possible solutions and tried to use File Wrapper also but the result did not changed.我已经搜索了可能的解决方案并尝试使用 File Wrapper,但结果没有改变。 I assume i have problem with reading the xlsx file into StringIO object.我假设我在将 xlsx 文件读入 StringIO 对象时遇到问题。 But dont have any idea about how to fix it但不知道如何修复它

Why on earth are you passing your file's content to a StringIO just to assign StringIO.get_value() to a local variable ?为什么你将文件内容传递给StringIO只是为了将StringIO.get_value()分配给局部变量? What's wrong with assigning file.read() to your variable directly ?直接将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

Now you may want to check weither you actually had any content in your file - the fact that the file exists doesn't mean it has anything in it.现在您可能想要检查您的文件中是否确实包含任何内容 - 文件存在的事实并不意味着其中包含任何内容。 Remember that you're in a concurrent context, you can have one thread or process trying to read the file while another (=>another request) is trying to write it.请记住,您处于并发上下文中,您可以让一个线程或进程尝试读取文件,而另一个(=> 另一个请求)正在尝试写入文件。

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

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

You can use this library to create excel sheets on the fly.您可以使用此库即时创建 Excel 工作表。 http://xlsxwriter.readthedocs.io/ http://xlsxwriter.readthedocs.io/

For more information see this page.有关更多信息,请参阅此页面。 Thanks to @alexcxe感谢@alexcxe

XlsxWriter object save as http response to create download in Django XlsxWriter 对象另存为 http 响应以在 Django 中创建下载

my answer is:我的回答是:

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

why using "rb"?为什么使用“rb”? because HttpResponse class init parameters is (self, content=b'', *args, **kwargs), so we should using "rb" and using .read() to get the bytes.因为 HttpResponse 类的初始化参数是 (self, content=b'', *args, **kwargs),所以我们应该使用 "rb" 并使用 .read() 来获取字节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM