使用Django下载PDF等文件后,文件无法打开或损坏

1、问题描述

在使用django搭建网站上,有时存在文件下载的操作。但此次在使用windows服务器上搭建django网站,从网站下载pdf文件后,发现pdf文件无法打开,显示“文件无法打开”、“文件已经损坏”等字样。

(1)而使用相同的方法,下载txt文档则可以顺利打开。

(2)之前在linux系统(centos6.5)上使用相同的方法,下载下来的pdf、txt文件均可以顺利打开。

2、解决思路

分析当前环境:使用linux系统下,相同的方法从django下载的pdf、txt均可以打开;使用window系统,相同的方法从django下载的txt文件可以打开,而pdf文件无法打开;

对比差异之处:不同的系统、相同的函数方法、不同的文件类型

进行猜测尝试:windows系统对于不同文件类型的底层读取机制不同,可能不同格式文件需要使用不同的方法,而不能使用相同的方法。

3、解决办法

django下载文件共有三种方式,即“使用HttpResponse”、“使用StreamingHttpResponse”、“使用FileResponse”。

(1)之前使用的都是StreamingHttpResponse对象进行数据的读取、保存,代码如下:

[code]
from django.http import StreamingHttpResponse
def download(request):
file=open(‘crm/models.pdf’,’rb’)
response =StreamingHttpResponse(file)
response[‘Content-Type’]=’application/octet-stream’
response[‘Content-Disposition’]=’attachment;filename=”models.pdf”‘
return response
[/code]

(2)现使用FileResponse对象进行数据的读取、保存,代码如下:

[code]
from django.http import FileResponse
def download(request):
file=open(‘crm/models.pdf’,’rb’)
response =FileResponse(file)
response[‘Content-Type’]=’application/octet-stream’
response[‘Content-Disposition’]=’attachment;filename=”models.pdf”‘
return response
[/code]

(3)结果下载下来的pdf可以顺利打开,问题解决。

4、结论

windows和linux系统底层对于pdf的读取方式不同,导致需要使用不同的对象(函数方法)进行读取、保存。

5、回顾django三种下载文件的方法

(1)使用HttpResponse

[code]
<pre>from django.shortcuts import HttpResponse
def download(request):
file = open(‘crm/models.py’, ‘rb’)
response = HttpResponse(file)
response[‘Content-Type’] = ‘application/octet-stream’ #设置头信息,告诉浏览器这是个文件
response[‘Content-Disposition’] = ‘attachment;filename=”models.py”‘
return response</pre>
[/code]

(2)使用StreamingHttpResponse

[code]
<pre>from django.http import StreamingHttpResponse
def download(request):
file=open(‘crm/models.py’,’rb’)
response =StreamingHttpResponse(file)
response[‘Content-Type’]=’application/octet-stream’
response[‘Content-Disposition’]=’attachment;filename=”models.py”‘
return response</pre>
[/code]

(3)使用FileResponse

[code]
<pre>from django.http import FileResponse
def download(request):
file=open(‘crm/models.py’,’rb’)
response =FileResponse(file)
response[‘Content-Type’]=’application/octet-stream’
response[‘Content-Disposition’]=’attachment;filename=”models.py”‘
return response</pre>
[/code]

暂无评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注