4

I'm trying to spin up a single page flask application that allows users to download a word document. I've already figured out how to make/save the document using python-docx, but now I need to make the document available in the response. Any ideas?

Here's what I have so far:

from flask import Flask, render_template
from docx import Document
from cStringIO import StringIO

@app.route('/')
def index():
    document = Document()
    document.add_heading("Sample Press Release", 0)
    f = StringIO()
    document.save(f)
    length = f.tell()
    f.seek(0)
    return render_template('index.html')
BarFooBar
  • 1,086
  • 2
  • 13
  • 32

4 Answers4

5

instead of render_template('index.html') you can just:

from flask import Flask, render_template, send_file
from docx import Document
from cStringIO import StringIO

@app.route('/')
def index():
    document = Document()
    document.add_heading("Sample Press Release", 0)
    f = StringIO()
    document.save(f)
    length = f.tell()
    f.seek(0)
    return send_file(f, as_attachment=True, attachment_filename='report.doc')
Doobeh
  • 9,280
  • 39
  • 32
2

For those who pass after me...

referring to these two links:

io.StringIO now replaces cStringIO.StringIO

also it will raise an error as document.save(f) should receive a pass or binary file

code should be like this:

from flask import Flask, render_template, send_file
from docx import Document
from io import BytesIO

@app.route('/')
def index():
    document = Document()
    f = BytesIO()
    # do staff with document
    document.save(f)
    f.seek(0)

    return send_file(
        f,
        as_attachment=True,
        # Use attachment_name for Flask version < 2.2.0
        download_name='report.docx'
    )

Bobby
  • 97
  • 7
1

You could use the send_from_directory as in this answer.

If you are sending text, you could also use the make_response helper as in this answer.

Community
  • 1
  • 1
vikramls
  • 1,802
  • 1
  • 11
  • 15
0

Use

return Response(generate(), mimetype='text/docx')

Generate() should be replaced with f in your case For more information look at streaming in flask http://flask.pocoo.org/docs/1.0/patterns/streaming/

Patrick Mutuku
  • 1,095
  • 15
  • 13