Python - Excel adding custom column headings - python

I am using the Coinmarketcap REST Api for having the latest cryptocurrency categories.
The code prints the JSON response into a DataFrame which is used for the transfer to excel (df.to_excel). Im using the "for column in df" for a bigger width in excel.
Now I would like to know how I can add costum column headings into the excel sheet.
def Cryptocurrencies():
url = 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/categories'
parameters = {
}
headers = {
'Accept': 'application/json',
'X-CMC_PRO_API_KEY': 'mypersonalapikey',
}
session = Session()
session.headers.update(headers)
data = session.get(url, params=parameters)
response = session.get(url, params=parameters)
f = (json.loads(response.text)['data'])
df = pd.DataFrame(f)
writer = pd.ExcelWriter("Workingpaper1D.xlsx",
engine='xlsxwriter',
datetime_format='mmm d yyyy hh:mm:ss',
date_format='mmmm dd yyyy')
df.to_excel(writer, sheet_name='Sheet1',
startrow=1, header=False, index=False, )
(max_row, max_col) = df.shape
worksheet = writer.sheets['Sheet1']
worksheet.autofilter(0, 0, max_row, max_col - 1)
for column in df:
column_length = max(df[column].astype(str).map(len).max(), len(column))
col_idx = df.columns.get_loc(column)
writer.sheets['Sheet1'].set_column(col_idx, col_idx, column_length)
writer.save()
print(df)
return

You can set a custom header like this:
# Convert the dataframe to an XlsxWriter Excel object. Note that we turn off
# the default header and skip one row to allow us to insert a user defined
# header.
df.to_excel(writer, sheet_name='Sheet1', startrow=1, header=False)
# Get the xlsxwriter workbook and worksheet objects.
workbook = writer.book
worksheet = writer.sheets['Sheet1']
# Add a header format.
header_format = workbook.add_format({
'bold': True,
'text_wrap': True,
'valign': 'top',
'fg_color': '#D7E4BC',
'border': 1})
# Write the column headers with the defined format.
for col_num, value in enumerate(df.columns.values):
worksheet.write(0, col_num + 1, value, header_format)
See also this section of the XlsxWriter docs on Formatting of the Dataframe headers.

Related

How align content in every cell to center?

I'm trying to center the table content using df.style.set_properties(**{'text-align': 'center'}). But I couldn't do it. Is there any other way?
Here is the full code:
import pandas as pd
import time
subject = 'demo'
checked_names = ['First','Second']
checked_ID = [64,65]
index =[i+1 for i in range(len(checked_names))]
df = pd.DataFrame(list(zip(index, checked_names, checked_ID)), columns=['Index','Student Name','Student_ID'])
path = (r"C:\Users\heman\Desktop\Attendance_list")
file_name = (path + "/" + subject +"("+time.strftime("%d.%m.%Y_%H.%M")+")"+ "_" + "attendance.xlsx")
sheet_name = "sheet1"
writer = pd.ExcelWriter(file_name, engine='xlsxwriter')
df.to_excel(writer, sheet_name=sheet_name, startrow = 4, index = False)
for column in df:
column_width = max(df[column].astype(str).map(len).max(), len(column))
col_idx = df.columns.get_loc(column)
writer.sheets[sheet_name].set_column(col_idx, col_idx, column_width)
workbook = writer.book
worksheet = writer.sheets[sheet_name]
worksheet.write(0, 0, 'Attendance report of '+subject+' class', workbook.add_format({'bold': True, 'color': '#E26B0A', 'size': 14, 'align': 'left'}))
worksheet.write(2, 0, 'Date: '+time.strftime("%d/%m/%Y"))
worksheet.write(2, 3, 'Time: '+time.strftime("%r"))
df.style.set_properties(**{'text-align': 'center'})
writer.save()
Here is the excel file after executing
I usually use openpyxl for alignments or Excel formatting operations.
You could run something similar to this at the end of your code ( adapting the filename path, sheet name and desired cells you wish to align)
from openpyxl import load_workbook
from openpyxl.styles import Alignment
wb = load_workbook(filename = r'Attendance_list.xlsx')
mysheet = wb['Sheet1']
for row in range(1,mysheet.max_row+1):
for col in range(1,mysheet.max_column+1):
cell=mysheet.cell(row, col)
cell.alignment = Alignment(horizontal='center', vertical='center')
wb.save(r'Aligned.xlsx')

writing data to the same file from different functions

Currently I can write results from within each function to an individual file.
How would I write the results from the 2 functions to the same file?
I think I would need to pull out writer = pd.ExcelWriter('All Results', engine='xlsxwriter') with new file name outside of the function but I dont know how to handle the writing of each df_Final...
Input:
ExcelName='....'
t1=pd.read_excel('.....')
t2=['.......']
def F1(Input_Data):
writer = pd.ExcelWriter('F1_Results', engine='xlsxwriter')
.
.
.
df_Final.to_excel(writer, sheet_name=writeto[3],index=False, header=False)
writer.save()
return
def F2(Input_Data):
writer = pd.ExcelWriter('F2_Results', engine='xlsxwriter')
.
.
.
df_Final.to_excel(writer, sheet_name=writeto[7],index=False, header=False)
writer.save()
return
Solution:
This helper function might help you out:
def append_df_to_excel(filename, df, sheet_name='Sheet1', startrow=None,
truncate_sheet=False,
**to_excel_kwargs):
"""
Append a DataFrame [df] to existing Excel file [filename]
into [sheet_name] Sheet.
If [filename] doesn't exist, then this function will create it.
Parameters:
filename : File path or existing ExcelWriter
(Example: '/path/to/file.xlsx')
df : dataframe to save to workbook
sheet_name : Name of sheet which will contain DataFrame.
(default: 'Sheet1')
startrow : upper left cell row to dump data frame.
Per default (startrow=None) calculate the last row
in the existing DF and write to the next row...
truncate_sheet : truncate (remove and recreate) [sheet_name]
before writing DataFrame to Excel file
to_excel_kwargs : arguments which will be passed to `DataFrame.to_excel()`
[can be dictionary]
Returns: None
"""
from openpyxl import load_workbook
# ignore [engine] parameter if it was passed
if 'engine' in to_excel_kwargs:
to_excel_kwargs.pop('engine')
writer = pd.ExcelWriter(filename, engine='openpyxl')
# Python 2.x: define [FileNotFoundError] exception if it doesn't exist
try:
FileNotFoundError
except NameError:
FileNotFoundError = IOError
try:
# try to open an existing workbook
writer.book = load_workbook(filename)
# get the last row in the existing Excel sheet
# if it was not specified explicitly
if startrow is None and sheet_name in writer.book.sheetnames:
startrow = writer.book[sheet_name].max_row
# truncate sheet
if truncate_sheet and sheet_name in writer.book.sheetnames:
# index of [sheet_name] sheet
idx = writer.book.sheetnames.index(sheet_name)
# remove [sheet_name]
writer.book.remove(writer.book.worksheets[idx])
# create an empty sheet [sheet_name] using old index
writer.book.create_sheet(sheet_name, idx)
# copy existing sheets
writer.sheets = {ws.title:ws for ws in writer.book.worksheets}
except FileNotFoundError:
# file does not exist yet, we will create it
pass
if startrow is None:
startrow = 0
# write out the new sheet
df.to_excel(writer, sheet_name, startrow=startrow, **to_excel_kwargs)
# save the workbook
writer.save()
NOTE: for Pandas < 0.21.0, replace sheet_name with sheetname!
Usage examples:
append_df_to_excel('/home/data/test.xlsx', df)
append_df_to_excel('/home/data/test.xlsx', df, header=None, index=False)
append_df_to_excel('/home/data/test.xlsx', df, sheet_name='Sheet2', index=False)
append_df_to_excel('/home/data/test.xlsx', df, sheet_name='Sheet2', index=False, startrow=25)
You can modify the function to receive filename as a parameter
def write_to_excel(filename, input_data):
writer = pd.ExcelWriter(filename, engine='xlsxwriter')
.
.
.
df_Final.to_excel(writer, sheet_name=writeto[3],index=False, header=False)
writer.save()
return
#Then use like
write_to_excel("F2_Results", input_data)

Create Excel Tables from Dictionary of Dataframes

I have dictionary of dataframes.
dd = {
'table': pd.DataFrame({'Name':['Banana'], 'color':['Yellow'], 'type':'Fruit'}),
'another_table':pd.DataFrame({'city':['Atlanta'],'state':['Georgia'], 'Country':['United States']}),
'and_another_table':pd.DataFrame({'firstname':['John'], 'middlename':['Patrick'], 'lastnme':['Snow']}),
}
I would like to create an Excel file which contains Excel Table objects created from these dataframes. Each Table needs to be on a separate Tab/Sheet and Table names should match dataframe names.
Is this possible to do with Python?
So far I was only able to export data to Excel normally without converting to tables using xlsxwriter
writer = pd.ExcelWriter('Results.xlsx', engine='xlsxwriter')
for sheet, frame in dd.items():
frame.to_excel(writer, sheet_name = sheet)
writer.save()
For writing multiple sheets from Pandas, use the openpyxl library. In addition, to prevent overwriting, set the workbook sheets before each update.
Try this code:
import pandas as pd
import openpyxl
dd = {
'table': pd.DataFrame({'Name':['Banana'], 'color':['Yellow'], 'type':'Fruit'}),
'another_table':pd.DataFrame({'city':['Atlanta'],'state':['Georgia'], 'Country':['United States']}),
'and_another_table':pd.DataFrame({'firstname':['John'], 'middlename':['Patrick'], 'lastnme':['Snow']}),
}
filename = 'Results.xlsx' # must exist
wb = openpyxl.load_workbook(filename)
writer = pd.ExcelWriter(filename, engine='openpyxl')
for sheet, frame in dd.items():
writer.sheets = dict((ws.title, ws) for ws in wb.worksheets) # need this to prevent overwrite
frame.to_excel(writer, index=False, sheet_name = sheet)
writer.save()
# convert data to tables
wb = openpyxl.load_workbook(filename)
for ws in wb.worksheets:
mxrow = ws.max_row
mxcol = ws.max_column
tab = openpyxl.worksheet.table.Table(displayName=ws.title, ref="A1:" + ws.cell(mxrow,mxcol).coordinate)
ws.add_table(tab)
wb.save(filename)
Output

Pandas add data to different sheets xlsxwriter

Hello I have data in list of dicts. I'm using panda DataFrame to parse from dict to excel. Data are fetch 5 different places. I would like to add data into different spreadsheet.
Here is the code I'm trying, but it doesn't add new sheets, it overwrites
def write_xlsx(filename, sheetname, data):
workbook = xlsxwriter.Workbook(filename)
checksheet = workbook.get_worksheet_by_name(sheetname)
if checksheet is None:
worksheet = workbook.add_worksheet(sheetname)
# Store the worksheet objects in a dict indexed by name.
my_worksheets = {}
for worksheet in workbook.worksheets():
my_worksheets[worksheet.get_name()] = worksheet
df = pd.DataFrame(data)
# Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter(filename, engine='xlsxwriter')
df.to_excel(writer, sheet_name=sheetname, index=False, startrow=1, header=False)
# Set the column widths
workbook = writer.book
worksheet = writer.sheets[sheetname]
header_format = workbook.add_format({'text_wrap': True})
columns_format = workbook.add_format({'text_wrap': True})
# Write the column headers with the defined format.
for col_num, value in enumerate(df.columns.values):
worksheet.write(0, col_num + 0, value, header_format)
writer.save()

xlsxwriter intersect row and column formats

I'm saving pandas DataFrame to Excel with xlsxwriter. First I'm adding some format to columns (change font, for instance). Then I want to change background color for some rows. But when I add set_row function, all my column's format is gone. Is there a way to combine it?
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})
worksheet.set_column('A:A', None, font_fmt)
zebra = workbook.add_format({'bg_color': 'green'})
for index in range(5):
if index % 2 == 0:
worksheet.set_row(index+1, None, zebra)
writer.save()
This shall help:
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']
formatdict = {'font_name': 'Calibri', 'font_size': 10, 'font_color':'red'}
font_fmt = workbook.add_format(formatdict)
worksheet.set_column('A:A', None, font_fmt)
zebra = workbook.add_format(formatdict)
zebra.set_bg_color('green')
for index in range(1,6,2):
worksheet.set_row(index, None, zebra)
writer.save()
Shall produce the following output:

Categories