Well, for task one, I figured out a way. I'm not sure if it's the right way, but here it goes:
import pandas as pd
from openpyxl import Workbook
# Additional imports:
from openpyxl.utils import get_column_letter
from openpyxl.utils.dataframe import dataframe_to_rows
df = pd.DataFrame({
'name': ['Lorem', 'Ipsum', 'Dolor', 'Sit', 'Amet'],
'value_1': [4, 7, 2, 4, 6],
'value_2': [1.23, 4.56, 7.13, 0.12, 0.]
})
wb = Workbook()
ws = wb.active
for r in dataframe_to_rows(df, index=False, header=True):
ws.append(r)
# I don't need to style this as Pandas, so I'll skip it;
# the table will (should) take care of the formatting.
# The reference is needed, so we have to get it somehow.
# Since the data is inserted starting in cell A1, all that remains
# is to get the last column and last row address:
table_ref = 'A1:%s%d' % (get_column_letter(len(df.columns)), len(df.index))
# Add the table to the worksheet:
tab = Table(displayName='tbl_test', ref=table_ref)
ws.add_table(tab)
wb.save('pandas_example.xlsx')
This works like a charm! It adds the table and creates the autofilter and everything I need for task one. As for task two, I still don't know how to address it.
Update
Found a way to style the table. All I need is to style the header, so I can use a default table style and override only the header. The full code:
import pandas as pd
from openpyxl import Workbook
# Additional imports:
from openpyxl.utils import get_column_letter
from openpyxl.utils.dataframe import dataframe_to_rows
df = pd.DataFrame({
'name': ['Lorem', 'Ipsum', 'Dolor', 'Sit', 'Amet'],
'value_1': [4, 7, 2, 4, 6],
'value_2': [1.23, 4.56, 7.13, 0.12, 0.]
})
wb = Workbook()
ws = wb.active
for r in dataframe_to_rows(df, index=False, header=True):
ws.append(r)
# I don't need to style this as Pandas, so I'll skip it;
# the table will (should) take care of the formatting.
# The reference is needed, so we have to get it somehow.
# Since the data is inserted starting in cell A1, all that remains
# is to get the last column and last row address:
table_ref = 'A1:%s%d' % (get_column_letter(len(df.columns)), len(df.index))
# Add a table style
style = TableStyleInfo(name='TableStyleLight8',
showFirstColumn=False, showLastColumn=False,
showRowStripes=False, showColumnStripes=False)
tab.tableStyleInfo = style
# Add the table to the worksheet:
tab = Table(displayName='tbl_test', ref=table_ref)
ws.add_table(tab)
# Customize cells individually
fill = PatternFill(patternType='solid', fgColor=Color("b1005c"))
alignment = Alignment(horizontal='left', vertical='top', indent=1)
border = Border(bottom=Side(border_style='thick', color='000000'))
for cell in ws[1]:
cell.fill = fill
cell.alignment = alignment
cell.border = border
# Save the workbook
wb.save('pandas_example.xlsx')
I don't know if this is the best way to go (iterating over the cells one by one is not what I had in mind), but it works.
If anyone has a better approach, please let me know .