pandas xlsxwriter, format header

I’m saving pandas DataFrame to_excel using xlsxwriter. I’ve managed to format all of my data (set column width, font size etc) except for changing header’s font and I can’t find the way to do it. Here’s my example:

import pandas as pd
data = pd.DataFrame({'test_data': [1,2,3,4,5]})
writer = pd.ExcelWriter('test.xlsx', engine='xlsxwriter')

data.to_excel(writer, sheet_name='test', index=False)

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

font_fmt = workbook.add_format({'font_name': 'Arial', 'font_size': 10})
header_fmt = workbook.add_format({'font_name': 'Arial', 'font_size': 10, 'bold': True})

worksheet.set_column('A:A', None, font_fmt)
worksheet.set_row(0, None, header_fmt)

writer.save()

The penultimate line that tries to set format for the header does nothing.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I think you need first reset default header style, then you can change it:

pd.core.format.header_style = None

All together:

import pandas as pd

data = pd.DataFrame({'test_data': [1,2,3,4,5]})
writer = pd.ExcelWriter('test.xlsx', engine='xlsxwriter')

pd.core.format.header_style = None

data.to_excel(writer, sheet_name='test', index=False)

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

font_fmt = workbook.add_format({'font_name': 'Arial', 'font_size': 10})
header_fmt = workbook.add_format({'font_name': 'Arial', 'font_size': 10, 'bold': True})

worksheet.set_column('A:A', None, font_fmt)
worksheet.set_row(0, None, header_fmt)

writer.save()

Explaining by jmcnamara, thank you:

In Excel a cell format overrides a row format overrides a column format.The pd.core.format.header_style is converted to a format and is applied to each cell in the header. As such the default cannot be overridden by set_row(). Setting pd.core.format.header_style to None means that the header cells don’t have a user defined format and thus it can be overridden by set_row().

EDIT: In version 0.18.1 you have to change

pd.core.format.header_style = None

to:

pd.formats.format.header_style = None

EDIT: from version 0.20 this changed again

import pandas.io.formats.excel
pandas.io.formats.excel.header_style = None

thanks krvkir.

EDIT: from version 0.24 this is now required

import pandas.io.formats.excel
pandas.io.formats.excel.ExcelFormatter.header_style = None

thanks Chris Vecchio.

Method 2

An update for anyone who comes across this post and is using Pandas 0.20.1.

It seems the required code is now

import pandas.io.formats.excel
pandas.io.formats.excel.header_style = None

Apparently the excel submodule isn’t imported automatically, so simply trying pandas.io.formats.excel.header_style = None alone will raise an AttributeError.

Method 3

Another option for Pandas 0.25 (probably also 0.24). Likely not the best way to do it, but it worked for me.

import pandas.io.formats.excel
pandas.io.formats.excel.ExcelFormatter.header_style = None

Method 4

for pandas 0.24:

The below doesn’t work anymore:

import pandas.io.formats.excel
pandas.io.formats.excel.header_style = None

Instead, create a cell formatting object, and re-write the first row’s content (your header) one cell at a time with the new cell formatting object.
Now, you are future proof.

Use the following pseudo code:

# [1] write df to excel as usual
writer = pd.ExcelWriter(path_output, engine='xlsxwriter')
df.to_excel(writer, sheet_name, index=False)

# [2] do formats for other rows and columns first

# [3] create a format object with your desired formatting for the header, let's name it: headercellformat

# [4] write to the 0th (header) row **one cell at a time**, with columnname and format
for columnnum, columnname in enumerate(list(df.columns)):
    worksheet.write(0, columnnum, columnname, headercellformat)

Method 5

In pandas 0.20 the solution of the accepted answer changed again.

The format that should be set to None can be found at:

pandas.io.formats.excel.header_style

Method 6

If you do not want to set the header style for pandas entirely, you can alternatively also pass a header=False to ExcelWriter:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.rand(3, 5), 
                  columns=pd.date_range('2019-01-01', periods=5, freq='M'))

file_path='output.xlsx'
writer = pd.ExcelWriter(file_path, engine='xlsxwriter')
df.to_excel(writer, sheet_name='Sheet1', header=False, index=False )
workbook = writer.book
fmt = workbook.add_format({'num_format': 'mm/yyyy', 'bold': True})
worksheet = writer.sheets['Sheet1']
worksheet.set_row(0, None, fmt)
writer.save()

Method 7

unfortunately add_format is in not avaiable anymore


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x