After working on this for far to long.
How do I set the format of a cell that I either have written a formula to or will be writing a formula to?
Every other write_(), except write_formula(), includes a format parameter.
for example:
ws.write_number(1,1,quantity, fmt)
ws.write_number(1,2,price, fmt)
# ws.write_formula("C1","=A1*B1",fmt) <-- doesn't exists
ws.write_formula("C1","=A1*B1")
This works:
extendedprice = (quantity*price)
ws.write_formula("C1", "=A1*B1", extendedprice, fmt)
I even figured out I can:
ws.write_number(1,1,quantity, fmt)
if (<price has an error>):
ws.write_number(1,2,"n/a",fmt)
ws.write_formula("C1", "=A1*B1", "n/a", fmt)
else:
ws.write_number(1,2,price,fmt)
ws.write_formula("C1", "=A1*B1", (quantity*price), fmt)
A format can be applied to a formula with XlsxWriter in the same way as any other data type:
import xlsxwriter
workbook = xlsxwriter.Workbook('test.xlsx')
worksheet = workbook.add_worksheet()
my_format = workbook.add_format({'bold': True, 'color': 'red'})
worksheet.write(0, 0, 'Hello', my_format)
worksheet.write(1, 0, 123, my_format)
worksheet.write(2, 0, '=1+1', my_format)
worksheet.write('A4', 'World', my_format)
worksheet.write('A5', 456, my_format)
worksheet.write('A6', '=2+2', my_format)
workbook.close()
Output:
Related
I've been trying to edit a dataframe into a formated Excel spreadsheet for work, and though most issues were solved elsewhere (Formatting an Excel file with XlsxWriter - Locale settings appear not to be applied to the output file) some remained.
The problem now is with the header and border formatting passed to date columns:
[]
I expected to have borders on all sides of each cell, but colmuns J, L and M, which receive information in datetime type, present border formatting issues (no borders actually). Also, there is an extra colmun (R) which is formated.
Keep in mind that columns B, C and F were also formated using xlsxwriter and have no border formatting problems.
Below is the code I have so far:
# Importar bibliotecas
import os
from typing import Self
import pandas as pd
import pandas.io.formats.excel
import pandas.io.excel
import numpy as np
import time
import xlsxwriter
template_excel_file = r"C:\CriarTabelaOpme\Modelo Material Alto Custo - Intranet.xlsx"
depara_nome_espec_file = r"C:\CriarTabelaOpme\Especialidade_Dicionario.csv"
report_csv_file = r"C:\CriarTabelaOpme\ReportServiceIntranet.csv"
csv_dataframe = pd.read_csv(report_csv_file, sep = ',', encoding = "ISO-8859-1", engine = 'python', index_col = None, names = ['TIPO', 'CODIGO', 'PTU',
'DESCRICAO', 'FORNECEDOR', 'VALOR', 'COD_PRINCP_ATIVO', 'PRINCIPIO_ATIVO', 'ANVISA', 'VALIDADE_RMS', 'FABRICANTE', 'DT_ATUALIZACAO', 'PTU_LIMITE', 'COD_ESP', 'NOME_ESPEC', 'REFERENCIA', 'OBSERVACAO'])
csv_dataframe.insert(16, "", "")
csv_dataframe["VALOR"] = csv_dataframe["VALOR"].apply(lambda x: x.replace(",", "")).astype('float')
csv_dataframe["VALIDADE_RMS"] = pd.to_datetime(csv_dataframe["VALIDADE_RMS"])
csv_dataframe["DT_ATUALIZACAO"] = pd.to_datetime(csv_dataframe["DT_ATUALIZACAO"])
csv_dataframe["PTU_LIMITE"] = pd.to_datetime(csv_dataframe["PTU_LIMITE"])
#print(csv_dataframe.dtypes)
csv_depara_espec = pd.read_csv(depara_nome_espec_file, sep = ',', header = None, encoding = "ISO-8859-1", engine = 'python')
#print(csv_depara_espec)
csv_dataframe = csv_dataframe.iloc[:, [0,1,2,3,4,5,6,7,8,9,10,11,12,13,16,14,15]]
#print(csv_dataframe)
dict = {'TIPO' : 'TIPO', 'CODIGO' : 'CODIGO', 'PTU': 'PTU',
'DESCRICAO' : 'DESCRICAO', 'FORNECEDOR' : 'FORNECEDOR', 'VALOR' : 'VALOR', 'COD_PRINCP_ATIVO' : 'COD_PRINCP_ATIVO',
'PRINCIPIO_ATIVO' : 'PRINCIPIO_ATIVO', 'ANVISA' : 'ANVISA', 'VALIDADE_RMS' : 'VALIDADE_RMS', 'FABRICANTE' : 'FABRICANTE',
'DT_ATUALIZACAO' : 'DT_ATUALIZACAO', 'PTU_LIMITE' : 'PTU_LIMITE', 'COD_ESP' : 'COD_ESP', '' : 'NOME_ESPEC',
'NOME_ESPEC' : 'REFERENCIA', 'REFERENCIA' : 'OBSERVACAO'}
csv_dataframe.rename(columns = dict, inplace = True)
for row in range(len(csv_dataframe)):
cod_esp_row = (csv_dataframe.iloc[row, 13])
csv_dataframe.iloc[row,14] = csv_depara_espec.iloc[cod_esp_row, 1]
pandas.io.formats.excel.header_style = None
writer = pd.ExcelWriter(template_excel_file, engine = 'xlsxwriter', date_format = 'dd/mm/yyyy', datetime_format = 'dd/mm/yyyy')
excel_dataframe = csv_dataframe.to_excel(writer, sheet_name = 'Material Alto Custo', index = False, header = ['TIPO', 'CODIGO', 'PTU',
'DESCRICAO', 'FORNECEDOR', 'VALOR', 'COD_PRINCP_ATIVO', 'PRINCIPIO_ATIVO', 'ANVISA', 'VALIDADE_RMS', 'FABRICANTE', 'DT_ATUALIZACAO',
'PTU_LIMITE', 'COD_ESP', 'NOME_ESPEC', 'REFERENCIA', 'OBSERVACAO'])
(max_row, max_col) = csv_dataframe.shape
workbook = writer.book
worksheet = writer.sheets['Material Alto Custo']
header_format = workbook.add_format({'bold' : True,
'font' : 'Arial',
'size' : 10,
'border' : 1})
font_size_and_border = workbook.add_format({'font' : 'Arial', 'size' : 10, 'border' : 1})
column_valor_format_and_border = workbook.add_format({'num_format': '[$R$-pt-BR] #,##0.00','font' : 'Arial', 'size' : 10, 'border' : 1})
column_date_format_and_border = workbook.add_format({'num_format' : 'dd/mm/yyyy','font' : 'Arial', 'size' : 10, 'border' : 1})
column_left_zeroes_format_and_border = workbook.add_format({'num_format' : '00000000','font' : 'Arial', 'size' : 10, 'border' : 1})
worksheet.set_row(0, None, header_format)
worksheet.set_column(0,max_col, 20.0, font_size_and_border)
worksheet.set_column(1, 1, 20.0, column_left_zeroes_format_and_border)
worksheet.set_column(2, 2, 20.0, column_left_zeroes_format_and_border)
worksheet.set_column(5, 5, 20.0, column_valor_format_and_border)
worksheet.set_column(9, 9, 20.0, column_date_format_and_border)
worksheet.set_column(11, 11, 20.0, column_date_format_and_border)
worksheet.set_column(12, 12, 20.0, column_date_format_and_border)
worksheet.set_row(0, None, header_format)
writer.close()
I've been trying to spot the error, but I have failed. Could someone help me out?
Thanks in advance for any help you can provide!
I can't text wrap the cells on my excel table, only in the header, anyone can help me. Im trying to use set_columns for use text_wrap_: True but that doesn't work. :(
**def call():
url=filedialog.asksaveasfilename(defaultextension='.xlsx', parent=ventana)
indexing=listbox_S.get_children()
newlist=[]
for index in indexing:
content=listbox_S.item(index)
datalist=content['values']
newlist.append(datalist)
def align_center(x):
return ['text-align: center' for x in x]
df = pd.DataFrame(newlist,columns=['Id',' SERVICIO ',' FECHA ',' DESCRIPCIÓN '])
with pd.ExcelWriter(url, engine='xlsxwriter') as writer:
df.style.apply(align_center, axis=0).to_excel(
writer,
index=False,
header=True,
encoding="ISO-8859-1",
sheet_name = 'sheetName1'
)
workbook = writer.book
worksheet = writer.sheets['sheetName1']
header_format = workbook.add_format({
'bold': True,
'text_wrap': True,
'valign': 'center',
'fg_color': '#D7E4BC',
'border': 1})
text_format = workbook.add_format({'text_wrap' : True})
for col_num, value in enumerate(df.columns.values):
worksheet.write(0, col_num, value, header_format)
for column in df:
column_width = max(df[column].astype(str).map(len).max(), len(column)+1)
col_idx = df.columns.get_loc(column)
writer.sheets['sheetName1'].set_column(col_idx, col_idx, column_width)
messagebox.showinfo('Success','Data is saved succesfully', parent=ventana)**
I get this:
I want something like this:
I have a multi sheet excel file like the one pictured below. I want to highlight with the condition:
if value 'app' in column 'Kind' matches with value 'v6.0' in column 'NetFrameworkVersion'
then highlight it yellow
if value 'functionapp' in column 'Kind' matches with value 'v4.0' in column 'NetFrameworkVersion'
then highlight it green
else highlight it blue
import pandas as pd
import pathlib
import xlsxwriter
with pd.ExcelWriter('*/environment.xlsx' , engine='xlsxwriter') as writer:
for filename in pathlib.Path('*/FD').glob('*.csv'):
df = pd.read_csv(filename)
df_custom = df.filter(['Kind', 'NetFrameworkVersion', 'Use32BitWorkerProcess', 'AlwaysOn' ]) #Select column and arrange custom
sheetname = filename.stem.split('-')[3] #Set sheet name save as short name
df_custom.style.to_excel(writer, sheet_name=sheetname,index=True, header = True) #write out file excel after read all data from csv files
#set border#
workbook = writer.book
worksheet = writer.sheets[sheetname]
border_fmt = workbook.add_format({'bottom':1, 'top':1, 'left':1, 'right':1})
worksheet.conditional_format(xlsxwriter.utility.xl_range(0, 0, len(df), len(df_custom.columns)), {'type': 'no_errors', 'format': border_fmt})
worksheet.set_column('C1:Z200', 25) #set range column width
worksheet.set_column('B:B', 35) #set 1 column width
red_format = workbook.add_format({'bg_color': '#FFC7CE',
'font_color': '#9C0006'})
worksheet.conditional_format('F1:F1000', {'type': 'text',
'criteria': 'containing',
'value': 'True',
'format': red_format})
worksheet.conditional_format('G1:G100', {'type': 'text',
'criteria': 'containing',
'value': 'False',
'format': red_format})
writer.save()
Example Picture:
Let df be the DataFrame from your picture.
Something like this should work:
import pandas as pd # Jinja2 must be installed
def styler(series):
color_attr = ''
if series['Kind'] == 'app' and series['NetFrameworkVersion'] == 'v6.0':
color_attr = 'background-color: yello'
elif series['Kind'] == 'functionapp' and series['NetFrameworkVersion'] == 'v4.0':
color_attr = 'background-color: green'
else:
color_attr = 'background-color: blue'
return pd.Series(color_attr, series.index)
left_df_p = df[['Kind', 'NetFrameworkVersion']]
left_df_p.style.apply(styler, axis=1) # iterates over every row
colored_df = left_df_p.join(df[['Use32BitWorkerProcess', 'AlwaysOn']])
Next time, please provide a Minimal, Reproducible Example, so that people can actually test the code. Instead of posting a picture, it is better to call and post the output of df.to_dict.
I am trying to apply conditional formatting to a column using xlsxwriter.
I keep getting AttributeError: 'str' object has no attribute '_get_dxf_index' using the following code:
import xlsxwriter
xlsx_file = REPORTS + "\\" + project + report_date + '_inventory_init.xlsx'
writer = pd.ExcelWriter(xlsx_file, engine='xlsxwriter')
wb = writer.book
df.to_excel(writer, sheet_name='Not Supported', startrow = 1, header=False, index=False)
ws = writer.sheets['Not Supported']
ws.conditional_format('G1:G1048576', {'type': 'cell',
'criteria': '==',
'value': 'FALSE',
'format': 'Bad'})
(max_row, max_col) = df.shape
column_settings = [{'header': column} for column in df.columns]
ws.add_table(0,0,max_row,max_col-1,{'columns': column_settings,
'style': 'Table Style Medium 8'})
ws.set_column(0, max_col-1,15)
Full error message below:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-124-b1f6e2d0bdf4> in <module>
47 df.to_excel(writer, sheet_name='Not Supported', startrow = 1, header=False, index=False)
48 ws = writer.sheets['Not Supported']
---> 49 ws.conditional_format('G1:G1048576', {'type': 'cell',
50 'criteria': '==',
51 'value': 'FALSE',
~\anaconda3\lib\site-packages\xlsxwriter\worksheet.py in cell_wrapper(self, *args, **kwargs)
98 args = new_args
99
--> 100 return method(self, *args, **kwargs)
101
102 return cell_wrapper
~\anaconda3\lib\site-packages\xlsxwriter\worksheet.py in conditional_format(self, first_row, first_col, last_row, last_col, options)
2280 # Get the dxf format index.
2281 if 'format' in options and options['format']:
-> 2282 options['format'] = options['format']._get_dxf_index()
2283
2284 # Set the priority based on the order of adding.
AttributeError: 'str' object has no attribute '_get_dxf_index'
From reading the docs, you need to pass format=[format object] instead of format=[str] as an option to ws.conditional_format.
For more info about how to create a format object, see the format docs.
For what it's worth: In a brief search, I wasn't able to find anything about using already-existing-in-Excel-template formatting; it looks like you'll need to create/define your own formatting.
I have a list to be exported to an Excel file keeping the appropriate format, I resorted to a library named xlsxwriter,
here is an example :
xlsxwriter
and here is my list :
{'FirstName': u'Forence','LastName': u'Bidorst', 'Salary': -6775000.0, 'BirthDate': datetime.datetime(2013, 6, 20, 0, 0)}
{'FirstName': u'Oliver','LastName': u'Bidorst', 'Salary': -6775000.0, 'BirthDate': datetime.datetime(2013, 6, 20, 0, 0)}
{'FirstName': u'Mathew','LastName': u'Stark', 'Salary': -6775000.0, 'BirthDate': datetime.datetime(2013, 6, 20, 0, 0)}
{'FirstName': u'Sphed','LastName': u'liomst', 'Salary': -6775000.0, 'BirthDate': datetime.datetime(2013, 6, 20, 0, 0)}
I modified the code to browse a list and insert it into the file,
def export_result_XL():
list=get_list()
...
# Write some data headers.
worksheet.write('A1', 'First Name', bold)
worksheet.write('B1', 'Last Name', bold)
worksheet.write('C1', 'Salary', bold)
worksheet.write('D1', 'Birth Date', bold)
# Some data we want to write to the worksheet.
for entry in list:
x = str(entry['FirstName'])
y = str(entry['LastName'])
z = str(entry['Salary'])
e = str(entry['BirthDate'])
v = BirthDate[:10] # because the date format is like yyyy-mm-dd 00:00:00
expenses = (
[x,y ,z ,v]
)
# Start from the first cell below the headers.
row = 1
col = 0
for item ,str1,str2,str3,date_str in (expenses):
# Convert the date string into a datetime object.
date = datetime.strptime(date_str, "%Y-%m-%d")
worksheet.write_string (row, col, str1 )
worksheet.write_string (row, col + 1, str2 )
worksheet.write_string(row, col + 2, str3 )
worksheet.write_datetime(row, col + 3, date, date_format )
row += 1
# Write a total using a formula.
#worksheet.write(row, 0, 'Total', bold)
#worksheet.write(row, 2, '=SUM(C2:C5)', money_format)
workbook.close()
return ''
I had two problems here :
1 -
for item, date_str in (frais)
ValueError: too many values to unpack
2-
if I avoid to convert to date format the file will be genreated but columns and rows are flipped
Is there any Idea how to do it , I hope I was clear in the description
Finally I found a Solution :
row = 1
col = 0
for entry in list:
print entry
strdate=str(entry['BirthDate'])
formatdate=strdate[:10]
date = datetime.strptime(str(formatdate), "%Y-%m-%d")
worksheet.write_string (row, col, entry['FirstName'] )
worksheet.write_string (row, col+1, entry['LastName'] )
worksheet.write_number (row, col+6, entry['Salary'],number_format )
worksheet.write_datetime(row, col+10, date, date_format )
row += 1
workbook.close()