IOError: [Errno 13] Permission denied: 'Test.xlsx' - python
the goal of my program is to read the sheet SNR_COPY1 from the Test.xlsx file, using the data to do some computations and then write those to a new sheet within Test.xlsx... Now yesterday my code worked perfectly, but then when I reran it, I got the above mentioned error.. Both the python script and the xlsx file are placed within Documents (Not sure how much it matters, but I'm working on Windows). My code:
import numpy as np
from numpy import pi, r_
import matplotlib.pyplot as plt
from scipy import optimize
from scipy.optimize import curve_fit
import pandas as pd
from pandas import DataFrame
import copy
#version in which all data will be read from the excelfile. The resulting fitparameters will be written into the excisting excelfile.
def snr_fitting_excel(number_of_altitude_points, row_begin_position_of_data, number_of_wavelengths):
# (0,0) in python = (2,1) in excel
n_alt = number_of_altitude_points
n_lambda = number_of_wavelengths
begin = row_begin_position_of_data
end = begin + n_alt
xlsx = pd.ExcelFile('Test.xlsx')
df = pd.read_excel(xlsx, 'SNR-COPY1')
xlsx_copy = copy.deepcopy(xlsx)
#print the beginning point of your data. This ensures that you are working at the correct position in the excel file
print(df.iat[11,2])
d = (n_alt, n_lambda)
#each row of height will represent the data for a given alltitude (height[0] = 5km data,...)
height = np.zeros(d, dtype=int)
# print(height)
for j in range(begin, end):
for i in range(2,10):
height[j-begin][i-2] = (np.around(df.iat[j,i], decimals =0))
height = np.array(height)
#array with the different wavelengths at which the data was taken
wavelengths = np.array([400, 450, 500, 550, 600, 650, 700, 800])
parameter_values = []
#fit the points with the desired function from above
for i in range(0, len(height)):
popt, pcov = curve_fit(fitfunc_polynome_OP_BL, wavelengths, height[i])
fig = plt.figure()
plt.plot(wavelengths, height[i], 'o')
plt.plot(wavelengths, fitfunc_polynome_OP_BL(wavelengths, *popt), 'r-', label ='fit: a=%5.3f, b=%5.3f, c=%5.3f, d=%5.3f, e=%5.3f, g=%5.3f, h=%5.3f, i=%5.3f' % tuple(popt))
plt.xlabel("Wavelength (nm)")
plt.ylabel("SNR")
plt.title("OP-BL-SNR fitting without data cut-off alltitude: " + str((i+1)*5) + "km")
fig.savefig("snr_op_fit_bl" + str((i+1)*5) +".pdf")
parameter_values.append(popt)
print(str((i+1)*5))
print(popt)
parameter_values_to_export = {'a': [parameter_values[0][0], parameter_values[1][0], parameter_values[2][0], parameter_values[3][0], parameter_values[4][0], parameter_values[5][0], parameter_values[6][0], parameter_values[7][0], parameter_values[8][0], parameter_values[9][0], parameter_values[10][0], parameter_values[11][0], parameter_values[12][0], parameter_values[13][0], parameter_values[14][0], parameter_values[15][0], parameter_values[16][0], parameter_values[17][0]],
'b': [parameter_values[0][1], parameter_values[1][1], parameter_values[2][1], parameter_values[3][1], parameter_values[4][1], parameter_values[5][1], parameter_values[6][1], parameter_values[7][1], parameter_values[8][1], parameter_values[9][1], parameter_values[10][1], parameter_values[11][1], parameter_values[12][1], parameter_values[13][1], parameter_values[14][1], parameter_values[15][1], parameter_values[16][1], parameter_values[17][1]],
'c': [parameter_values[0][2], parameter_values[1][2], parameter_values[2][2], parameter_values[3][2], parameter_values[4][2], parameter_values[5][2], parameter_values[6][2], parameter_values[7][2], parameter_values[8][2], parameter_values[9][2], parameter_values[10][2], parameter_values[11][2], parameter_values[12][2], parameter_values[13][2], parameter_values[14][2], parameter_values[15][2], parameter_values[16][2], parameter_values[17][2]],
'd': [parameter_values[0][3], parameter_values[1][3], parameter_values[2][3], parameter_values[3][3], parameter_values[4][3], parameter_values[5][3], parameter_values[6][3], parameter_values[7][3], parameter_values[8][3], parameter_values[9][3], parameter_values[10][3], parameter_values[11][3], parameter_values[12][3], parameter_values[13][3], parameter_values[14][3], parameter_values[15][3], parameter_values[16][3], parameter_values[17][3]],
'e': [parameter_values[0][4], parameter_values[1][4], parameter_values[2][4], parameter_values[3][4], parameter_values[4][4], parameter_values[5][4], parameter_values[6][4], parameter_values[7][4], parameter_values[8][4], parameter_values[9][4], parameter_values[10][4], parameter_values[11][4], parameter_values[12][4], parameter_values[13][4], parameter_values[14][4], parameter_values[15][4], parameter_values[16][4], parameter_values[17][4]],
'g': [parameter_values[0][5], parameter_values[1][5], parameter_values[2][5], parameter_values[3][5], parameter_values[4][5], parameter_values[5][5], parameter_values[6][5], parameter_values[7][5], parameter_values[8][5], parameter_values[9][5], parameter_values[10][5], parameter_values[11][5], parameter_values[12][5], parameter_values[13][5], parameter_values[14][5], parameter_values[15][5], parameter_values[16][5], parameter_values[17][5]],
'h': [parameter_values[0][6], parameter_values[1][6], parameter_values[2][6], parameter_values[3][6], parameter_values[4][6], parameter_values[5][6], parameter_values[6][6], parameter_values[7][6], parameter_values[8][6], parameter_values[9][6], parameter_values[10][6], parameter_values[11][6], parameter_values[12][6], parameter_values[13][6], parameter_values[14][6], parameter_values[15][6], parameter_values[16][6], parameter_values[17][6]],
'i': [parameter_values[0][7], parameter_values[1][7], parameter_values[2][7], parameter_values[3][7], parameter_values[4][7], parameter_values[5][7], parameter_values[6][7], parameter_values[7][7], parameter_values[8][7], parameter_values[9][7], parameter_values[10][7], parameter_values[11][7], parameter_values[12][7], parameter_values[13][7], parameter_values[14][7], parameter_values[15][7], parameter_values[16][7], parameter_values[17][7]],
}
dataframe = DataFrame(parameter_values_to_export, columns= ['a', 'b', 'c', 'd', 'e', 'g', 'h', 'i'])
append_df_to_excel('Test.xlsx', dataframe, 'SNR OP BL Parameters')
print(dataframe)
def append_df_to_excel(filename, df, sheet_name='Sheet1', startrow=None,
truncate_sheet=False,
**to_excel_kwargs):
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')
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 IOError:
# 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()
def fitfunc_polynome_OP_BL(x ,a, b, c, d, e, g, h, i):
return a*(np.power(x,7)) + b*(np.power(x,6))+ c*(np.power(x,5)) + d*(np.power(x,4)) + e*(np.power(x,3)) + g*(np.power(x,2)) + h*x +i
if __name__ == '__main__':
print("\nFitting SNR_UV---------------------------------------------\n")
snr_fitting_excel(18,11,8)
Any tips/remarks/solutions to this error?
This problem comes when we want to update our xlsx file (i.e data.xlsx) using updated dataframe and simultenously that file (i.e data.xlsx) is already opened in background that time.
To solve this problem first close xlsx file (i.e data.xlsx) and perform this task again.
Related
Pandas change font color based on condition in Excel and save to the same excel python
New to Pandas as of now. My Problem statement is I am trying to open an existing excel sheet, Traverse through the values present in that, add an if condition and change the font colour of text if the condition is true. This is the sample excel where I am trying to change the color: Below is my code which I have tried: def highlight_cells(val): color = 'red' if val =='DATA' else '#C6E2E9' return 'color: %s' % color ddf = pd.read_excel(PathToTheExcelFile) ddf.style.applymap(highlight_cells) ddf.to_excel(PathToTheExcelFile,index=False) What I am currently getting is this: What I want is this:
.style.applymap produces a Styler object, which has a to_excel method to conveniently export it: def highlight_cells(val): color = 'red' if val == 'DATA' else '#C6E2E9' return 'color: %s' % color ddf.style.applymap(highlight_cells).to_excel("data.xlsx", index=False) # If you want to stylize only the Comments column ddf.style.applymap(highlight_cells, subset="Comments").to_excel("data.xlsx", index=False) Result:
The style.applymap is for showing output of dataframes in HTML, not updating excel sheets. You can change the code thus to update the font in excel. I am reading the excel input.xlsx, updating the contents using openpyxl and writing it to output.xlsx. You can change other things like size, bold, fontname, etc. as well. Note: Color used is HEX color, but without the # symbol in front import openpyxl wb = openpyxl.load_workbook(filename="input.xlsx") ws = wb.active for row in range(2,ws.max_row+1): #Skipping first row as I assume it is header if ws.cell(row=row, column=3).value == 'DATA': ws.cell(row=row, column=3).font = openpyxl.styles.Font(color='FF0000') #, size=16, bold=True, name='Calibri') else: ws.cell(row=row, column=3).font = openpyxl.styles.Font(color='C6E2E9') wb.save("output.xlsx") USING pandas.ExcelWriter instead of openpyxl You can use the below code pandas.ExcelWriter to change the font to RED for DATA and GREEN for others. Note: you can edit the colors to anything you want using # followed by the 6 char hexcode in case you want to change the font color import pandas as pd import numpy as np df = pd.read_excel('output.xlsx') df.fillna('NA', inplace = True) writer = pd.ExcelWriter('output1.xlsx') df.to_excel(writer, sheet_name= 'sheet1', index=False) worksheet = writer.sheets['sheet1'] workbook = writer.book cell_format_red = workbook.add_format({'font_color': 'red'}) cell_format_green = workbook.add_format({'font_color': 'green'}) start_row = 1 start_col = 2 end_row = len(df) end_col = start_col worksheet.conditional_format(start_row, start_col, end_row, end_col, {'type': 'cell', 'criteria': '==', 'value': '"DATA"', 'format': cell_format_red}) worksheet.conditional_format(start_row, start_col, end_row, end_col, {'type': 'cell', 'criteria': '!=', 'value': '"DATA"', 'format': cell_format_green}) writer.save()
xlsxwriter: protection unhiding
UPDATE: Fixed. Sheet protected, selected column is possible to unhide. Is it possible to lock all visible cells (protection from editing), but still allow the users to unhide certain columns? I would like to export a pandas dataframe via pd.excel_writer(). worksheet.protect() doesn't allow for any arguments? I apply column-wise formatting and tried 'lock': False on the hidden columns, but that didn't work. # init import pandas as pd import random as rd import string random.seed(10) S = 10 string_col = [] number_col1 = [] # protect number_col2 = [] # hide # create testdata for i in range(0, 20): ran_str = ''.join(rd.choices(string.ascii_uppercase + string.digits, k = S)) ran_num1 = ''.join(str(rd.randrange(S))) ran_num2 = ''.join(str(rd.randrange(S))) string_col.append(ran_str) number_col1.append(ran_num1) number_col2.append(ran_num2) testframe = pd.DataFrame( {'String_col': string_col, 'Hide': number_col1, 'Protect': number_col2 }) # helperfunction for selecting columns def getColnameByPosition(pos): from string import ascii_uppercase colnames = list(ascii_uppercase) for col in ascii_uppercase: for col2 in ascii_uppercase: colnames.append(col+col2) return colnames[pos] # export writer = pd.ExcelWriter("./FormatTest.xlsx", engine='xlsxwriter') testframe.to_excel(writer, sheet_name="Sheet0", startrow=0, header=True, index=False) workbook = writer.book worksheet = writer.sheets["Sheet0"] # protect and hide format format_protect = workbook.add_format({'bg_color': '#ADD8E6','font_name': 'Calibri', 'font_size': 9, 'num_format': '#,##0', "locked": True}) format_hide = workbook.add_format({'bg_color': '#FFFFFF', 'font_name': 'Calibri', 'font_size': 9, 'num_format': '#,##0', "locked": False}) prot_col = getColnameByPosition(testframe.columns.get_loc("Protect")) hide_col = getColnameByPosition(testframe.columns.get_loc("Hide")) worksheet.set_column(prot_col+':'+prot_col, 10, format_protect) worksheet.set_column(hide_col+':'+hide_col, 10, format_hide, {'hidden': True}) # FIX: allow for unhiding. worksheet.protect('', {'format_columns': True}) writer.save()
You just need to set protect() to turn on worksheet protection but turn on the exceptions that you want. In this case turning on "Format Columns" should get you what you want: # ... worksheet.set_column(prot_col+':'+prot_col, 10, format_protect) worksheet.set_column(hide_col+':'+hide_col, 10, format_hide, {'hidden': True}) worksheet.protect('', {'format_columns': True}) writer.save() Also, set_column() can take (col, col) notation so you could drop the getColnameByPosition() code and just do this: # ... prot_col = testframe.columns.get_loc("Protect") hide_col = testframe.columns.get_loc("Hide") worksheet.set_column(prot_col, prot_col, 10, format_protect) worksheet.set_column(hide_col, hide_col, 10, format_hide, {'hidden': True}) worksheet.protect('', {'format_columns': True}) writer.save()
Openpyxl - Error after convert an image to excel spreadsheet possible problem with styles.xml
I'm trying to use a python script to convert an image (*.jpg) to the background color of an Excel's spreadsheet. According to the following photo: Full Python script: import openpyxl from PIL import Image def image_to_excel(file, output, percentage): # Open picture and create a workbook instance im = Image.open(file) wb = openpyxl.Workbook() sheet = wb.active # Resize image with spreadsheet's columns width, height = im.size cols = width * percentage/100 print('Old image size: ' + str(im.size)) imgScale = cols/width newSize = (int(width*imgScale), int(height*imgScale)) im = im.resize(newSize) # Get new picture's dimensions cols, rows = im.size print('New image size: ' + str(im.size)) # Spreadsheet's cell: height = 6 and width = 1 for i in range(1, rows): sheet.row_dimensions[i].height = 0.6 for j in range(1, cols): column_letter = openpyxl.utils.get_column_letter(j) sheet.column_dimensions[column_letter].width = 0.0625 # Convert image to RGB rgb_im = im.convert('RGB') # Formatting cell's color for i in range(1, rows): for j in range(1, cols): c = rgb_im.getpixel((j, i)) rgb2hex = lambda r,g,b: f"ff{r:02x}{g:02x}{b:02x}" c = rgb2hex(*c) sheet.cell(row = i, column = j).value = " " customFill = openpyxl.styles.PatternFill(start_color=c, end_color=c, fill_type='solid') sheet.cell(row = i, column = j).fill = customFill # Save workbook #im.close() #rgb_im.close() wb.save(output) wb.close() # Export image_to_excel('jangada.jpg', 'final.xlsx', 100) The problem is when I tried to change the images, like this one: https://www.planetware.com/wpimages/2019/09/croatia-in-pictures-most-beautiful-places-to-visit-plitvice-lakes.jpg and after run the code I got the error: The translation is something like that: Excel was able to open teh file by repairing or removing the unreadable content. Removed Records: Style from /xl/styles.xml part (Styles) Repaired Records: Informations about the cell part of /xl/worksheets/sheet1.xml I'm using excel 2013. Anyone knows how to solve it ?
Your rgb2hex isn't working as you intended, remove the ff from it, I think that's whats breaking your code. Your func: >>>rgb2hex = lambda r,g,b: f"ff{r:02x}{g:02x}{b:02x}" >>>rgb2hex(120,120,120) ff787878 The output should be 787878. >>>rgb2hex = lambda r,g,b: f"{r:02x}{g:02x}{b:02x}" >>>rgb2hex(120,120,120) 787878
Can't create a new sheet in GoogleColab and make calculcation
I have an xlsx file on my computer with initial data (value) - two sheets were created. I decide to calculate some value in sheet1 and in sheet2. After this I try to save the result, but when I download a file from GoogleColab and get my start file with initial values. And I don't know how to creat a new Sheet3 and make this calcuation in it: copy one column from Sheet1 and another column Sheet2 and make P_roz = P_nav + P-osvit the result in a new column in Sheet3. How to download the xlsx file with the result in picture 2 and picture 4? from google.colab import drive drive.mount('/content/gdrive') !pip install -q xlrd import pandas as pd import numpy as np # Works with Sheet1 df_1 = pd.read_excel('my_path', name_sheet = 'Sheet1') df_1['T_potyz'] = round((((1 / df_1['K_potyz']**2) - 1))**(1/2.0),3) df_1['P_nav, кВт'] = df_1['P_ust, кВт']\ * df_1['K_poputy1'] df_1['Q_nav, кВАр'] = round(df_1['P_ust, кВт']\ * df_1['T_potyz'],3) df_1['S_nav, кВА'] = round((df_1['P_nav, кВт']**2\ + df_1['Q_nav, кВАр']**2)\ **(1/2.0),3) df_1['P_nav, кВт'].sum(), df_1['Q_nav, кВАр'].sum(), df_1['S_nav, кВА'].sum() sum_row1 = df_1[['P_nav, кВт', 'Q_nav, кВАр', 'S_nav, кВА']].sum() sum_row1 # transpose the data and convert the Series to a DataFrame so that it is easier to concat onto our existing data. #The T function allows us to switch the data from being row-based to column-based. df_sum1 = pd.DataFrame(data = sum_row1).T df_sum1 # to add the missing columns. df_sum1 = df_sum1.reindex(columns = df_1.columns) df_sum1 # add it to our existing one using append. df_final_1 = df_1.append(df_sum1, ignore_index = True) df_final_1.tail() # Works with Sheet2 df_2 = pd.read_excel('my_path', sheet_name='Sheet2') K_po = float(input("Коефіцієнт попиту загально освітлення: ")) df_2['P_ust'] = (round(df_2['k'] * df_2['P_put'] * 10**-3 * df_2['A, м'] * df_2['B, м'],3)) df_2['P_osvit'] = round(K_po * df_2['P_ust'],3) df_2['T_potyz2'] = round((((1 / df_2['K_poputy2']**2) - 1))**(1/2.0),3) df_2['Q_osvit'] = round(df_2['P_osvit'] * df_2['T_potyz2'],3) df_2['S_osvit'] = round((df_2['P_osvit']**2\ + df_2['Q_osvit']**2)\ **(1/2.0),3) df_2['P_osvit'].sum(), df_2['Q_osvit'].sum(), df_2['S_osvit'].sum() sum_row2 = df_2[['P_osvit', 'Q_osvit', 'S_osvit']].sum() sum_row2 df_sum2 = pd.DataFrame(data = sum_row2).T df_sum2 df_sum2 = df_sum2.reindex(columns = df_2.columns) df_sum2 df_final2 = df_2.append(df_sum2, ignore_index = True) df_final2.tail() # Here I want create a new Sheet3 and make some calculation P_roz = df_1['P_nav, кВт'] + df_2['P_osvit'] Q_roz = df_1['Q_nav, кВАр'] + df_2['Q_osvit'] S_roz = (P_roz**2 + Q_roz**2)**(1 / 2.0) frame_data3 = {'P_roz' : [P_roz], 'Q_roz' : [Q_roz], 'S_roz' : [S_roz]} df_4 = pd.DataFrame(frame_data3) df_4 Sheet 1 Sheet 1 + sum Sheet 2 Sheet 2 + sum
Python: Pandas style background color not visible in excel file
I am creating an excel file with multiple sheets using xlsxwriter as engine. In each sheet the row color is based on value of column named colour But the color is not visible in my excel file. import pandas as pd def row_colour(row): return ['background-color:'+row.colour.lower()for i in row] writer = pd.ExcelWriter('try.xlsx', engine='xlsxwriter') cols = ['subject','colour'] df1 = pd.DataFrame([['Math','DarkRed'],['Science','Yellow']],columns=cols) df2 = pd.DataFrame([['English','Orange'],['History','Green']],columns=cols) df3 = pd.DataFrame([['Geography','DarkRed'],['Civic','Yellow']],columns=cols) df1.style.apply(row_colour,axis=1) df2.style.apply(row_colour,axis=1) df3.style.apply(row_colour,axis=1) df1.to_excel(writer, sheet_name='Sheet 1') df2.to_excel(writer, sheet_name='Sheet 2') df3.to_excel(writer, sheet_name='Sheet 3') writer.save() In output no color is visible: The accepted answer is right for the above question. I have improved the task by deleting the color column since it's only use was to color the rows. Code for it: import pandas as pd def row_colour(table,color): print("table: \n "+str(table)) print("table shape : "+str(table.shape)) color_data = [] for index,row in table.iterrows(): color.iloc[index] if str(color.iloc[index]['colour']) == "DarkRed": c= 'background-color:red' else: c= 'background-color:'+str(color.iloc[index]['colour']) color_data.append([c for i in range(len(row))]) return pd.DataFrame(color_data,index=table.index, columns=table.columns) writer = pd.ExcelWriter('try.xlsx', engine='xlsxwriter') cols = ['subject','colour'] df1 = pd.DataFrame([['Math','DarkRed'],['Science','Yellow']],columns=cols) df2 = pd.DataFrame([['English','Orange'],['History','Green']],columns=cols) df3 = pd.DataFrame([['Geography','DarkRed'],['Civic','Yellow']],columns=cols) color = pd.DataFrame(columns=['colour']) color['colour']=df1['colour'] df1 = df1.drop(['colour'],axis=1) df1=df1.style.apply(row_colour,axis=None,color=color) color = pd.DataFrame(columns=['colour']) color['colour']=df2['colour'] df2=df2.drop(['colour'],axis=1) df2=df2.style.apply(row_colour,axis=None,color=color) color = pd.DataFrame(columns=['colour']) color['colour']=df3['colour'] df3=df3.drop(['colour'],axis=1) df3=df3.style.apply(row_colour,axis=None,color=color) df1.to_excel(writer, sheet_name='Sheet 1') df2.to_excel(writer, sheet_name='Sheet 2') df3.to_excel(writer, sheet_name='Sheet 3') writer.save()
The function is ok, you just have to reassign df1, df2, df3. This should work: import pandas as pd def row_colour(row): return ['background-color:'+row.colour.lower()for i in row] writer = pd.ExcelWriter('try.xlsx', engine='xlsxwriter') cols = ['subject','colour'] df1 = pd.DataFrame([['Math','DarkRed'],['Science','Yellow']],columns=cols) df2 = pd.DataFrame([['English','Orange'],['History','Green']],columns=cols) df3 = pd.DataFrame([['Geography','DarkRed'],['Civic','Yellow']],columns=cols) df1 = df1.style.apply(row_colour,axis=1) df2 = df2.style.apply(row_colour,axis=1) df3 = df3.style.apply(row_colour,axis=1) df1.to_excel(writer, sheet_name='Sheet 1') df2.to_excel(writer, sheet_name='Sheet 2') df3.to_excel(writer, sheet_name='Sheet 3') writer.save() to_excel here is a method of pandas.io.formats.style.Styler rather than the original dataframe.
As an answer to your comment, I came up with a more complex solution. The colours are now read from the DataFrame before being dropped. Then passed as an argument to a row-colouring function. The key points are my use of zip and pd.IndexSlice for subsetting df.style.apply. I hope this suits your colouring needs. import pandas as pd def colour_row(row, colour): return ['background-color:'+ colour.lower() for i in row] def colour_df(df, colour_col): colours = list(df['colour']) df = df.drop('colour', axis = 1) coloured_df = df.style for i, colour in zip(range(len(df)), colours): coloured_df = coloured_df.apply(colour_row, axis=1, subset=pd.IndexSlice[i,:], colour=colour) return coloured_df writer = pd.ExcelWriter('try.xlsx', engine='xlsxwriter') cols = ['subject','colour'] df1 = pd.DataFrame([['Math','DarkRed'],['Science','Yellow']],columns=cols) df2 = pd.DataFrame([['English','Orange'],['History','Green']],columns=cols) df3 = pd.DataFrame([['Geography','DarkRed'],['Civic','Yellow']],columns=cols) sheet_num = 1 for df in [df1, df2, df3]: sheet_name = 'Sheet ' + str(sheet_num) df = colour_df(df, 'colour') df.to_excel(writer, sheet_name = sheet_name) sheet_num += 1 writer.save()