Last active
March 30, 2019 13:23
-
-
Save piersstorey/b32583f0cc5cba0a38a11c2b123af687 to your computer and use it in GitHub Desktop.
Flask xlsx writer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from flask import Response | |
import StringIO, mimetypes | |
import xlsxwriter | |
from datetime import datetime | |
from werkzeug.datastructures import Headers | |
def xlsx_export(): | |
try: | |
# Flask response | |
response = Response() | |
response.status_code = 200 | |
# Create an in-memory output file for the new workbook. | |
output = StringIO.StringIO() | |
# Craete workbook | |
workbook = xlsxwriter.Workbook(output, {'in_memory': True}) | |
worksheet = workbook.add_worksheet('hello') | |
# Write some test data. | |
worksheet.write(0, 0, 'Hello, world!') | |
# Close the workbook before streaming the data. | |
workbook.close() | |
# Rewind the buffer. | |
output.seek(0) | |
# Add output to response | |
response.data = output.read() | |
# Set filname and mimetype | |
file_name = 'export_{}_{}.xlsx'.format('this_awesome', datetime.now()) | |
mimetype_tuple = mimetypes.guess_type(file_name) | |
# HTTP headers for forcing file download | |
response_headers = Headers({ | |
'Pragma': "public", # required, | |
'Expires': '0', | |
'Cache-Control': 'must-revalidate, post-check=0, pre-check=0', | |
'Cache-Control': 'private', # required for certain browsers, | |
'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', | |
'Content-Disposition': 'attachment; filename=\"%s\";' % file_name, | |
'Content-Transfer-Encoding': 'binary', | |
'Content-Length': len(response.data) | |
}) | |
if not mimetype_tuple[1] is None: | |
response.update({ | |
'Content-Encoding': mimetype_tuple[1] | |
}) | |
# Add headers | |
response.headers = response_headers | |
#jquery.fileDownload.js requirements | |
response.set_cookie('fileDownload', 'true', path='/') | |
# Return the response | |
return response | |
except Exception as e: | |
print(e) |
i don't think mimetype is needed here when we know what the content-type should be, and the file isn't encoded.
also the Cache-Control header is overwritten here (it's used as a key twice in the dictionary), also according to this post:
https://stackoverflow.com/questions/34663916/are-cache-control-pre-check-and-post-check-headers-still-supported-by-ie
pre-check / post-check headers don't need to be used
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for your gist.
I had to change:
output = StringIO.StringIO()
to
output = BytesIO()
but now always works great.