简体   繁体   中英

create excel file from DataFrame and allow download in flask, error: file format/extension not valid

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)

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM