[英]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.