Home » excel » python – Flask & Pandas ExcelWriter not changing column format with BytesIO

python – Flask & Pandas ExcelWriter not changing column format with BytesIO

Posted by: admin May 14, 2020 Leave a comment

Questions:

On my Flask page a user can download an excel file with data from a pandas dataframe, weekly_data. I am using BytesIO and pandas ExcelWriter with the xlsxwriter engine.

When I edit the worksheet.set_column values, say the column width or the time format, refresh the server and the page, the Excel sheet is in exactly the same format as it was before.

Here is the section of code within the route that is called when a user clicks the link to download the data:

fn = 'weeklydata_'+(datetime.today().date()).strftime('%d-%b-%y')+'.xlsx'

output = BytesIO()
writer = pd.ExcelWriter(output, engine='xlsxwriter')

weekly_data.to_excel(writer, sheet_name='Sheet1')

workbook = writer.book
worksheet = writer.sheets['Sheet1']

formatTimes = workbook.add_format({'num_format':'hh:mm'})

worksheet.set_column('B:C',None,formatTimes)

worksheet.set_column('A:A',13)
worksheet.set_column('B:C',16)


writer.save()
output.seek(0)

return send_file(output, attachment_filename=fn, as_attachment=True)

Additionally, I added print(weekly_data) before the code just to check the DataFrame was correct, and it does not print when I download the Excel file, so I assume this could be down to BytesIO? I also have another route that downloads an Excel using similar code, if that is relevant.

Is there anyway to see the changes? I appreciate any help.

Not relevant to the current question, but is there any way for the time format to handle hours greater than 24 hours? On the other Excel file I mentioned, all the formats work (I created the code for that Excel a while ago) but any hours greater than 24 revert to something like 02/01/1900 04:31:00 (for 52:31) when I double click it?

How to&Answers:

As for your main problem – if you changed the code, but the downloaded file is the same, that is almost certainly a caching problem.
(BytesIO is deterministic. web applications caching policies not that much).

There is a chance the caching is taking place on the browser side. If that is the case, accessing the same view from an anonymous session, or even forcing a full reload (shift + f5 on google-chrome) should work.

If your system is deployed in something else than the Flask development server, then the caching could be taking place in intermediate layers -you will have to check your configuration to figure it out. A workaround would be to make a different URL for each request -a “noise” parameter that is ignored on the server side, but that would force the caching infrastructure to pass the full request around all times. In other words: insert an unused parameter with random-data on the URL for the request generating this file.

Displaying more than 24 hours

Not sure if Excel will honour it, but the DataFrame column dtype should be set to “timedelta64[ns]”, not “datetime” or “time”.