Search code examples
pythonexcelpandasformatxlsxwriter

pandas xlsxwriter, format table header - not sheet 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.


Solution

  • 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.