Reputation: 1717
I've created a simple Flask app that turns a Pandas Dataframe into an excel file. The file gets downloaded when I go to the link, however, I'm just getting the following error once I try and open the file:
Excel cannot open the file 'df.xlsx' because the file format or file extension is not valid. Verify that the files has not been corrupted and that the file extension matches the format of the file.
Am I missing something here?
@app.route('/download', methods=["GET"])
def download_excel():
df = pd.DataFrame({'Name': ['Tesla','Tesla','Toyota','Ford','Ford','Ford'],
'Type': ['Model X','Model Y','Corolla','Bronco','Fiesta','Mustang']})
#create an output stream
output = BytesIO()
writer = pd.ExcelWriter(df, engine='xlsxwriter')
df.to_excel(writer, sheet_name='Sheet1')
#the writer has done its job
writer.close
#go back to the beginning of the stream
output.seek(0)
#finally return the file
return send_file(output, attachment_filename="df.xlsx", as_attachment=True)
Upvotes: 0
Views: 1630
Reputation: 15722
The problem is that you're passing the dataframe to ExcelWriter
's path
parameter instead of the BytesIO
object (output
).
writer = pd.ExcelWriter(df, engine='xlsxwriter')
The ExcelWriter
documentation says the following on the path
parameter:
path: str or typing.BinaryIO Path to xls or xlsx or ods file.
So you could do something like this instead:
from flask import Flask, send_file
import pandas as pd
from io import BytesIO
app = Flask(__name__)
@app.route("/download", methods=["GET"])
def download_excel():
df = pd.DataFrame(
{
"Name": ["Tesla", "Tesla", "Toyota", "Ford", "Ford", "Ford"],
"Type": ["Model X", "Model Y", "Corolla", "Bronco", "Fiesta", "Mustang"],
}
)
output = BytesIO()
with pd.ExcelWriter(output, engine="xlsxwriter") as writer:
df.to_excel(writer, sheet_name="Sheet1")
output.seek(0)
return send_file(output, attachment_filename="df.xlsx", as_attachment=True)
Upvotes: 2