I am trying to build an application which writes data into an excel file. I am therefore trying to use the pandas library and I use the xlsxwriter engine. I read the documentation about the Styler object from the pandas library, but I can't find out a way to modify the style of table headers (or column headers, the keys of the dictionary I feed to the DataFrame constructor). In fact, I think the set_table_styles method isn't working very well in my case.
Here is the code I run:
import os
import pandas
writer = pandas.ExcelWriter(f"{os.getcwd()}\\Styled_excel.xlsx", engine="xlsxwriter", mode='w')
data_frame = pandas.DataFrame({"Pressure": [10, 20, 30, 50],
"Volume": [10, 8, 5, 2]})
styler = data_frame.style
styler.set_properties(**{'color': 'red', 'border-color': 'black', 'border-width': "1px"})
styler.set_table_styles([{'selector': 'th', 'props': [('font-weight', 'normal')]}])
styler.to_excel(excel_writer=writer, sheet_name="Feuil1", startrow=4, startcol=2, index=False)
writer.save()
Although the set_properties works as expected, set_table_styles doesn't seem to apply the style I want to, which is a normal font weight for the cells containing "Pressure" and "Volume".
On the same topic, I can't find anywhere in the documentation a way to programmatically change the width of a column, is it just not supported?
If you have any clue on what I might be doing wrong or why it isn't working, I thank you in advance for your answer.
Paul
EDIT: I did find an answer to the issues I had but if someone has an explanation as to why my previous code wasn't working as expected, I'll be glad to hear it (but I think it's due to the fact that the set_table_styles method can only be used when rendering an html page or when displaying the table in Jupyter Notebook)
I found a solution to both my issues on the xlsxwriter documentation (which I didn't know existed before I posted this question):
workbook = writer.book
worksheet = writer.sheets['Feuil1']
# Creation of format for the column headers
header_format = workbook.add_format({
'bold': False,
'border': 1
})
# Writing the column headers only and applying the style with the format created
for col_num, value in enumerate(data_frame.columns.values):
worksheet.write_string(0, col_num, value, header_format)
# Widening a column to fully fit a string in it
worksheet.set_column('C:C', 10)
Related
I am using python xlsxwriter library to create excel. I need to apply background color to the cell for that I am using set_column method. All columns getting backgroundcolor except the column containing hyperlink. I tried various ways i can try with but not able to found anything. Cell format is working with write_rows but not with set_column containing hyperlink. Can anybody please help.
Sample Code:
workbook = xlsxwriter.Workbook('hello.xlsx')
worksheet = workbook.add_worksheet()
cell_format = workbook.add_format()
cell_format.set_bg_color('green')
worksheet.write('A1', 'https://google.com')
worksheet.set_column(0, 0, None, cell_format)
workbook.close()
Output:
All columns have green color except having url.
Got the solution for this. There is parameter strings_to_urls which will consider url as string and then bgcolor will get applied.
workbook = Workbook(filename, {'strings_to_urls': False})
We can use this and then we will get bgcolor applied to url as well but it will no more be hyperlink.
xlsxwriter has been pretty powerful and almost everything I want is working, but the following attempt to align left a single row doesn't seem to work.
stats = DataFrame(...)
xl_writer = ExcelWriter(r'U:\temp\test.xlsx')
stats.to_excel(xl_writer, 'Stats')
workbook = xl_writer.book
format_header = workbook.add_format({'align': 'left'})
stats_sheet = xl_writer.sheets['Stats']
stats_sheet.set_row(0, None, format_header)
See the XlsxWriter docs for Formatting of the Dataframe headers:
Pandas writes the dataframe header with a default cell format. Since it is a cell format it cannot be overridden using set_row(). If you wish to use your own format for the headings then the best approach is to turn off the automatic header from Pandas and write your own. For example...
The following piece of code is getting the data from Excel in the 5th row and the 14th row:
import pandas as pd
import pymssql
df=[]
fp = "G:\\Data\\Hotels\\ABZPD - Daily Strategy Tool.xlsm"
data = pd.read_excel(fp,sheet_name ="CRM View" )
row_date = data.loc[2, :]
row_sita = "ABZPD"
row_event = data.iloc[11, :]
df = pd.DataFrame({'date': row_date,
'sita': row_sita,
'event': row_event
})
print(df)
However, it is not actually using the worksheet I need it to. Instead of using "CRM View" (like I told it to!) it is using the worksheet "Previous CRM View". I assume this is because both worksheets have similar names.
So the question is, how do I get it to use the one that is called "CRM View"?
I was able to reproduce your problem. It didn't seem like it was about that the supplied sheet name is similar, it just read the first sheet in the file no matter what you put sheet_name to.
Anyway, It seemed like a bug so I checked what version of pandas I was running, which was 0.20.3. After updating to 0.22.0 the problem was gone and the right sheet was selected.
Edit: this was apparently a known bug in 0.20.3.
I didn't find anything that enable me to write comments on some specific cell while writing excel sheet using panadas.to_excel . Any help is appreciated.
After searching for some time, I think the best way to handle comments or other such properties like color and size of text at cell or sheet level is to use XlsxWriter with pandas.
Here is the link to the some nice examples of using XlsxWriter with pandas:
http://xlsxwriter.readthedocs.org/working_with_pandas.html
My reputation is too low to write a comment...
The given link by Randhawa does not provide any information about how to add comments. You can refer to this link https://xlsxwriter.readthedocs.io/working_with_cell_comments.html, which specifies how you can add comments with XlsxWriter.
worksheet.write('A1', 'Hello')
worksheet.write_comment('A1', 'This is a comment')
This is a working example based on the useful web pages linked to by Randhawa and Carsten:
import pandas as pd
# Create a Pandas dataframe
df = pd.DataFrame({"Data": [10, 20, 30, 20, 15, 30, 45]})
# Create a Pandas Excel writer using XlsxWriter as the engine
writer = pd.ExcelWriter("pandas_simple.xlsx", engine="xlsxwriter")
# Convert the dataframe to an XlsxWriter Excel object (sheet)
df.to_excel(writer, sheet_name="Sheet1")
# Get the xlsxwriter object for the sheet where you will write a comment
workbook = writer.book
worksheet = writer.sheets["Sheet1"]
# Add comment to cell A1 in worksheet ("Sheet1"), set to visible
worksheet.write_comment("A1", "This is a comment", {"visible": True})
# Write the data (sheets) to the workbook
writer.close()
this is the code that i'm trying. but its not working.
import xlsxwriter
....
sheet.merge_range.write_formula('F16:H16', """IF('Original data'!B4<>"",'Original data'!B4,"")""", center)
Is there another code that can put both of them become one? i'm already doing some research and don't get any. thanks in advance
From the docs on merge_range():
The merge_range() method writes its data argument using write(). Therefore it will handle numbers, strings and formulas as usual. If this doesn’t handle your data correctly then you can overwrite the first cell with a call to one of the other write_*() methods using the same Format as in the merged cells. See Example: Merging Cells with a Rich String.
Here is a small working example based on yours:
import xlsxwriter
workbook = xlsxwriter.Workbook('example.xlsx')
worksheet1 = workbook.add_worksheet()
worksheet2 = workbook.add_worksheet('Original data')
center = workbook.add_format({'align': 'center', 'fg_color': 'yellow'})
worksheet1.merge_range('F16:H16',
"""=IF('Original data'!B4<>"",'Original data'!B4,"")""",
center)
worksheet2.write('B4', 'Hello')
workbook.close()
Output: