Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to do excel's 'format as table' in python

I'm using xlwt to create tables in excel. In excel there is a feature format as table which makes the table have an automatic filters for each column. Is there a way to do it using python?

like image 557
orenma Avatar asked Apr 03 '14 08:04

orenma


People also ask

What is format as table?

When you use Format as Table, Excel automatically converts your data range to a table. If you don't want to work with your data in a table, you can convert the table back to a regular range while keeping the table style formatting that you applied. For more information, see Convert an Excel table to a range of data.


2 Answers

You can do it with Pandas also. Here's an example:

import pandas as pd

df = pd.DataFrame({
    'city': ['New York', 'London', 'Prague'], 
    'population': [19.5, 7.4, 1.3], 
    'date_of_birth': ['1625', '43', 'early 8th century'],
    'status_of_magnetism': ['nice to visit', 'nice to visit', 'definetely MUST visit']
})

# initialize ExcelWriter and set df as output
writer = pd.ExcelWriter(r'D:\temp\sample.xlsx', engine='xlsxwriter') 
df.to_excel(writer, sheet_name='Cities', index=False)

# worksheet is an instance of Excel sheet "Cities" - used for inserting the table
worksheet = writer.sheets['Cities']
# workbook is an instance of the whole book - used i.e. for cell format assignment 
workbook = writer.book

Then define format of a cell (i.e. rotate text, set vertical and horizontal align) via workbook.add_format

header_cell_format = workbook.add_format()
header_cell_format.set_rotation(90)
header_cell_format.set_align('center')
header_cell_format.set_align('vcenter')

Then...

# create list of dicts for header names 
#  (columns property accepts {'header': value} as header name)
col_names = [{'header': col_name} for col_name in df.columns]

# add table with coordinates: first row, first col, last row, last col; 
#  header names or formatting can be inserted into dict 
worksheet.add_table(0, 0, df.shape[0], df.shape[1]-1, {
    'columns': col_names,
    # 'style' = option Format as table value and is case sensitive 
    # (look at the exact name into Excel)
    'style': 'Table Style Medium 10'
})

Alternatively worksheet.add_table('A1:D{}'.format(shape[0]), {...}) can be used, but for df with more columns or shifted start position the AA, AB,... combinations would have to be calculated (instead of "D")

And finally - the following loop rewrites headers and applies header_cell_format. Which we already did in worksheet.add_table(...) and so it looks redundant, but this is a way to use Excel's AutoFit option - without this all header cells would have default width (or cell height if you use the 90degs rotation) and so either not the whole content would be visble, or set_shrink() would have to be applied...and then the content wouldn't be readable :). (tested in Office 365)

# skip the loop completly if AutoFit for header is not needed
for i, col in enumerate(col_names):
    # apply header_cell_format to cell on [row:0, column:i] and write text value from col_names in
    worksheet.write(0, i, col['header'], header_cell_format)

# save writer object and created Excel file with data from DataFrame     
writer.save()
like image 73
Lukas Avatar answered Sep 18 '22 16:09

Lukas


OK, after searching the web, I realized that with xlwt it's not possible to do it, but with XlsxWriter it's possible and very easy and convenient.

like image 25
orenma Avatar answered Sep 21 '22 16:09

orenma