Reputation: 11833
My django web app makes and save docx and I need to make it downloadable.
I use simple render_to_response
as below.
return render_to_response("test.docx", mimetype='application/vnd.ms-word')
However, it raises error like 'utf8' codec can't decode byte 0xeb in position 15: invalid continuation byte
I couldn't serve this file as static so I need to find a way to serve it as this. Really appreciate for any help.
Upvotes: 4
Views: 13423
Reputation: 1490
I slightly modified @luc's answer. His post got me 98% of the way. I made changes because I did not need to create a Word file. My usage was simply to pass one that existed on the fileserver and then ready it for downloading.
Because the doc for downloading already exists.
def download(request):
filepath = os.path.abspath(r"path\to\file.docx")
print('SLA FILE: ', filepath)
if os.path.exists(filepath):
with open(filepath, 'rb') as worddoc: # read as binary
content = worddoc.read() # Read the file
response = HttpResponse(
content,
content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document'
)
response['Content-Disposition'] = 'attachment; filename=download_filename.docx'
response['Content-Length'] = len(content) #calculate length of content
return response
else:
return HttpResponse("Failed to Download SLA")
Upvotes: 2
Reputation: 3610
Yep, a cleaner options, as stated by wardk would be, using https://python-docx.readthedocs.org/:
from docx import Document
from django.http import HttpResponse
def download_docx(request):
document = Document()
document.add_heading('Document Title', 0)
response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document')
response['Content-Disposition'] = 'attachment; filename=download.docx'
document.save(response)
return response
Upvotes: 17
Reputation: 43096
I managed to generate a docx document from a django view thanks to python-docx.
Here is an example. I hope it helps
from django.http import HttpResponse
from docx import Document
from cStringIO import StringIO
def your_view(request):
document = Document()
document.add_heading(u"My title", 0)
# add more things to your document with python-docx
f = StringIO()
document.save(f)
length = f.tell()
f.seek(0)
response = HttpResponse(
f.getvalue(),
content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document'
)
response['Content-Disposition'] = 'attachment; filename=example.docx'
response['Content-Length'] = length
return response
Upvotes: 7
Reputation: 5187
Is it possible, that your path to 'test.docx' contains non-ascii-characters? Did you check all local variables on the django debug page?
What I did to download an xml file was not to create the file on disc but to use a memory file (saves me from dealing with file systems, path, ...):
memory_file = StringIO.StringIO()
memory_file.writelines(out) #out is an XMLSerializer object in m case
response = HttpResponse(memory_file.getvalue(), content_type='application/xml')
response['Content-Disposition'] = 'attachment; filename="my_file.xml"'
response['Content-Length'] = memory_file.tell()
return response
Maybe you can adapt this to your docx-situation.
Upvotes: 1
Reputation: 4511
Try with this response:
response = HttpResponse(mydata, mimetype='application/vnd.ms-word')
response['Content-Disposition'] = 'attachment; filename=example.doc'
return response
Upvotes: 1