brsbilgic
brsbilgic

Reputation: 11833

Downloadable docx file in Django

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

Answers (5)

Andrew
Andrew

Reputation: 1490

For Downloading a DOCX file that Already Exists

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

Vitor Freitas
Vitor Freitas

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

luc
luc

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

OBu
OBu

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

fasouto
fasouto

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

Related Questions