2

Im trying to take user input from a form and then using that data to create a document using python docx module. But the downloaded file is not opening in MS word. It says the file is corrupt. Can someone help me with this?

def resume_form(request):
form = forms.resume()

if request.method == 'POST':
    form = forms.resume(request.POST)
    if form.is_valid():
        document = Document()
        document.add_heading(str(form.cleaned_data['full_name']),0)
        document.add_heading('Summary', 1)
        document.add_paragraph(str(form.cleaned_data['summary']))

        f = io.BytesIO()
        document.save(f)
        length = f.tell()
        f.seek(0)
        response = HttpResponse(document, content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document')
        response['Content-Disposition'] = 'attachment; filename=download.docx'
        response['Content-Length'] = length
        #document.save(response)
        return response

return render(request, 'sample_app/index.html', {'form' : form})
  • 2
    you are corrupting the file in this line check the correct extension in this line for document . response = HttpResponse(document, content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document') – Indrajit Swain Feb 10 '18 at 13:30
  • I tried for .doc from this website: https://blogs.msdn.microsoft.com/vsofficedeveloper/2008/05/08/office-2007-file-format-mime-types-for-http-content-streaming-2/ Its still corrupt – Audhoot Chavan Feb 10 '18 at 13:36
  • check if this link can help you https://stackoverflow.com/questions/19400089/downloadable-docx-file-in-django – Indrajit Swain Feb 10 '18 at 13:47
  • `if form.is_valid(): document = Document() document.add_heading(str(form.cleaned_data['full_name']),0) document.add_heading('Summary', 1) document.add_paragraph(str(form.cleaned_data['summary'])) response = HttpResponse(document, content_type='application/vnd.ms-word') response['Content-Disposition'] = 'attachment; filename=download.docx' document.save(response) return response` – Audhoot Chavan Feb 10 '18 at 13:57
  • I tried changing the extension and a few other changes. But its still not working. I opened the file in notepad, It looks something like this: ‰–ÄaLÎ^ÓØ« ƒrálv®ZOâèÞ[1Û¶ – Audhoot Chavan Feb 10 '18 at 13:59

2 Answers2

3

I think you have the answer already in your code: you can (and should) write your document directly to the response, rather than use an intermediary BytesIO.

...
response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document')
response['Content-Disposition'] = 'attachment; filename = "download.docx"'
document.save(response)
return response
paleolimbot
  • 331
  • 1
  • 3
  • Thank you :) I was trying to solve the warning sign for 'corrupt file' that I forgot to actually open(force) the word file. Can you tell me why the prompt/sign appears? – Audhoot Chavan Feb 10 '18 at 15:49
  • You mean the prompt to download the file? I think that is a a Content-Disposition/attachment thing, but I'm new to this, so not sure if there's a way to disable it (particularly for a word document). – paleolimbot Feb 11 '18 at 18:34
1

You must read from io in the response with getvalue(), since you're writing document to io.

response = HttpResponse(f.getvalue(), content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document')

Or you can write directly to response as @paleolimbot pointed out.

Borut
  • 2,749
  • 2
  • 11
  • 16