Python 2.7 xlsxwriter isn't formatting data properly with valign - python-2.7

I have horizontal and vertical alignment set to center, but only the first two columns are centering the data.
The third column appears to be setting the data with a 'top' vertical alignment:
#!/usr/bin/env python
import xlsxwriter
# Create our spreadsheet.
workbook = xlsxwriter.Workbook('stats.xlsx')
worksheet = []
# Open our data file to extract data.
data = open('server_results','r')
# Create a bold centered font for our column headers.
format = workbook.add_format()
format.set_bold()
format.set_align('center')
format.set_align('vcenter')
format.set_text_wrap()
# Non-headers will be centered.
format1 = workbook.add_format()
format1.set_align('center')
format1.set_align('vcenter')
format1.set_text_wrap()
# Provider label/name for worksheet.
worksheet.append(workbook.add_worksheet('Stats'))
# Adjust column widths for data.
worksheet[0].set_column(0,2,25)
#worksheet[0].set_column(1,1,25)
#worksheet[0].set_column(1,2,25)
#worksheet[0].set_row(0,40)
# Start from the first cell. Rows and columns are zero indexed.
worksheet[0].write('A1', 'Column 1', format)
worksheet[0].write('B1', 'Column 2', format)
worksheet[0].write('C1', 'Column 3', format)
row = 1
col = 0
# Count lines
linelist = data.readlines()
count = len(linelist)
# Populate spreadsheet.
for num in range (0, count):
line = linelist[num]
splitline = line.split("\t")
worksheet[0].write(row, col, splitline[0], format1)
worksheet[0].write(row, col + 1, splitline[1], format1)
worksheet[0].write(row, col + 2, splitline[2], format1)
row += 1
#close workbook
workbook.close()
EOF
I've tried modifying how I format the data with following code:
format = workbook.add_format({'bold': True, 'bg_color': 'yellow', 'border': 5, 'align': 'center', 'valign': 'middle', 'text_wrap': True})
but when I do this, then NONE of the columns are centered -- with this format the first two columns are bottom aligned and third column is top aligned

The third column appears to be setting the data with a 'top' vertical alignment
I ran a version of your program with some sample data and I don't see that behaviour:
import xlsxwriter
# Create our spreadsheet.
workbook = xlsxwriter.Workbook('stats.xlsx')
worksheet = []
# Create a bold centered font for our column headers.
format = workbook.add_format()
format.set_bold()
format.set_align('center')
format.set_align('vcenter')
format.set_text_wrap()
# Non-headers will be centered.
format1 = workbook.add_format()
format1.set_align('center')
format1.set_align('vcenter')
format1.set_text_wrap()
# Provider label/name for worksheet.
worksheet.append(workbook.add_worksheet('Stats'))
# Adjust column widths for data.
worksheet[0].set_column(0,2,25)
# Start from the first cell. Rows and columns are zero indexed.
worksheet[0].write('A1', 'Column 1', format)
worksheet[0].write('B1', 'Column 2', format)
worksheet[0].write('C1', 'Column 3', format)
row = 1
col = 0
# Count lines
linelist = ['foo\tbar\tbaz\tbing'] * 5
count = len(linelist)
# Populate spreadsheet.
for num in range (0, count):
line = linelist[num]
splitline = line.split("\t")
worksheet[0].write(row, col, splitline[0], format1)
worksheet[0].write(row, col + 1, splitline[1], format1)
worksheet[0].write(row, col + 2, splitline[2], format1)
row += 1
#close workbook
workbook.close()
The output shows horizontal and vertical centering as expected:
Could you clarify what the issue is.

Using the following:
splitline = [l.rstrip() for l in line.split("\t")]
resolved the issue.

Related

XLSXWriter can one use xl_rowcol_to_cell as the cell to act on in conditional formating using type formula?

and thanks in advance for any assistance.
Based on the code snippet below, I'm trying to take the information from SUMMARY_LIST and add it to an xlsx worksheet. I'm then trying to colorize the cells based on 3 conditional formats,
green, text in cell in column A is equal to PASS
yellow, text in cell in column A contains the word PARTIAL and the value in column B of the same row is greater or equal to 6; or the text in cell in column B is equal to CRITICAL
red, text in cell in column A contains the word FAIL and the value in column B if the same row is greater than or equal to 6; or the text in cell in column B is equal to EMERGENCY.
If I hard code the cell in the condition to either $A1 or $B1, I get the desired result, which is that the if my condition passes, then both cells in the row that match either condition will get the appropriate background color.
If I substitute xl_rowcol_to_cell(0,0,col_abs=True) for $A1 and/or xl_rowcol_to_cell(0,1,col_abs=True) for $B1, the cells in my row doesn't get colorized.
In the snippet, I'm trying to colorize the background red if either my cell in column A contains the word "FAIL" and the value in column B is >= 6; OR the cell in column B contains the word "EMERGENCY".
When I run the script, neither the cells in the row containing the word FAIL or the row containing the word EMERGENCY are changed to a red background.
Is there an error in my conditional formatting statement for formatting in red or is it not possible to use the xl_rowcol_to_cell as an input to the condition?
import xlsxwriter
from xlsxwriter.utility import xl_range
from xlsxwriter.utility import xl_range_abs
from xlsxwriter.utility import xl_rowcol_to_cell
SUMMARY_LIST = [{'Item': 'Date', 'Value': '2023-01-11 14:09:16'}, {'Item': 'O/S Version', 'Value': '18.04.6 LTS (Bionic Beaver)'}, {'Item': 'CRITICAL EXPIRY THRESHOLD', 'Value': '6700'}, {'Item': 'EMERGENCY EXPIRY THRESHOLD', 'Value': '720'}, {'Item': 'TOTAL', 'Value': 6}, {'Item': 'PASS', 'Value': 6}, {'Item': 'PARTIAL PASS', 'Value': 6}, {'Item': 'FAIL', 'Value': 6}, {'Item': 'cert1', 'Value': 'EMERGENCY'}, {'Item': 'cert2', 'Value': 'CRITICAL'}]
wb = xlsxwriter.Workbook('myTest.xlsx')
ws = wb.add_worksheet()
row = 0
col = 0
inc = 0
formatEmerg = wb.add_format({'bg_color': 'red'})
formatCrit = wb.add_format({'bg_color': 'yellow'})
formatOk = wb.add_format({'bg_color': 'green'})
for item in SUMMARY_LIST:
inc = 0
for x in item.values():
ws.write(row,col + inc,x )
inc += 1
last_row = row
row += 1
col = 0
ws.conditional_format(xl_range(0,0,last_row,1),
{
'type':'formula',
'criteria':'=OR(and(left(xl_rowcol_to_cell(0,0,col_abs=True),4)="FAIL",(xl_rowcol_to_cell(0,1,col_abs=True)>=6)),left(xl_rowcol_to_cell(0,1,col_abs=True),9)="EMERGENCY")',
'format': formatEmerg
})
ws.conditional_format(xl_range(0,0,last_row,1),
{
'type':'formula',
'criteria':'=OR(and(left($A1,7)="PARTIAL",($B1>=6)),left($B1,8)="CRITICAL")',
'format': formatCrit
})
ws.conditional_format(xl_range(0,0,last_row,1),
{
'type':'formula',
'criteria':'=OR(and(left($A1,4)="PASS",($B1>=6)),left($B1,8)="CRITICAL")',
'format': formatOk
})
wb.close()
I haven't tried anything other than hardcoding the cell, or using the xl_rowcol_to_cell function.
My expectation is that the absolute column, represented by $A1, generated by xl_rowcol_to_cell(0,1,col_abs=True) would be substituted and the condition would evaluate the same as hardcoding the column as $A1. Same for column $B1.

Python-docx: cell edges disappear when merging outer cells

I am using python-docx to create a table with borders on all cells. When I merge cells involving outer cells some outer borders disappear. I use a function from other stackoverflow question -link shown as comment in code below- to set cell borders. How to fix that so outer borders are shown in merged cells?
Wrong borders:
Good borders:
Working example:
from docx import Document
from docx.oxml.shared import OxmlElement, qn
# from https://stackoverflow.com/questions/33069697/how-to-setup-cell-borders-with-python-docx
def set_cell_edges(cell, edges, color, style, width):
"""
Parameter Type Definition
=========== ==================== ==========================================================================================
cell Cell Cell to apply edges
edges str, list, None Cell edges, options are 'top', 'bottom', 'start' and 'end'
color str Edge color
style str Edge style, options are 'single', 'dotted', 'dashed', 'dashdotted' and 'double',
width int, float Edge width in points
"""
kwargs = dict()
for edge in edges:
kwargs[edge] = {'sz': width, 'val': style, 'color': color}
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
# check for tag existance, if none found then create one
tcBorders = tcPr.first_child_found_in("w:tcBorders")
if tcBorders is None:
tcBorders = OxmlElement('w:tcBorders')
tcPr.append(tcBorders)
# list over all available tags
for edge in ('start', 'top', 'end', 'bottom', 'insideH', 'insideV'):
edge_data = kwargs.get(edge)
if edge_data:
tag = 'w:{}'.format(edge)
# check for tag existance, if none found, then create one
element = tcBorders.find(qn(tag))
if element is None:
element = OxmlElement(tag)
tcBorders.append(element)
# looks like order of attributes is important
for key in ["sz", "val", "color", "space", "shadow"]:
if key in edge_data:
element.set(qn('w:{}'.format(key)), str(edge_data[key]))
if __name__ == '__main__':
rows = 3
columns = 3
document = Document()
# create table
table = document.add_table(rows=rows, cols=columns)
# merge cells
scell = table.rows[1].cells[1]
ecell = table.rows[2].cells[2]
scell.merge(ecell)
# set 4 borders in all cells
for row in table.rows:
for cell in row.cells:
set_cell_edges(cell, ['top', 'bottom', 'start', 'end'], '#ff0000', 'single', 1)
document.save('test.docx')
Of course, I can set an extra column and row to set the specific borders. But it would be nice to fix it without that trick. Example with the trick.
Good borders with trick:
if __name__ == '__main__':
rows = 3
columns = 3
document = Document()
# create table
table = document.add_table(rows=rows+1, cols=columns+1)
# merge cells
scell = table.rows[1].cells[1]
ecell = table.rows[2].cells[2]
scell.merge(ecell)
# set 4 borders in all cells
for row in table.rows[:-1]:
for cell in row.cells[:-1]:
set_cell_edges(cell, ['top', 'bottom', 'start', 'end'], '#ff0000', 'single', 1)
# set top border in last row
for cell in table.rows[-1].cells[:-1]:
set_cell_edges(cell, ['top'], '#ff0000', 'single', 1)
# set left border in last column
for cell in table.columns[-1].cells[:-1]:
set_cell_edges(cell, ['start'], '#ff0000', 'single', 1)
document.save('test.docx')

Creating excell file with Django workbook and worksheet

I am trying to create excell report with django workbook and workseet as below.
def print_assistant_notes(request):
if request.method == 'GET':
notes = AssistantNotes.objects.filter(notedate=datetime.today().date()).order_by("time")
workbook = load_workbook(os.path.join(settings.BASE_DIR, "export_templates", "assistant_notes.xlsx"))
worksheet = workbook.active
title_cell = worksheet["A%d" % (1,)]
title_cell.value = "Assistant Notes [ "+str(datetime.today().date())+" ] "
row = 3
for note in notes:
time_cell = worksheet["A%d" % (row,)]
category_cell = worksheet["B%d" % (row,)]
note_cell = worksheet["C%d" % (row,)]
time_cell.value = note.time
category_cell.value = note.categories
note_cell.value = note.dailynote
row = row + 1
tmp_file = tempfile.NamedTemporaryFile()
workbook.save(tmp_file.name)
response = HttpResponse(smart_str(tmp_file.read()), content_type='application/vnd.ms-excel')
response["Content-Disposition"] = 'attachment; filename="assistant_notes.xlsx"'
return response
When i print report i get excell report as below in red color data. But i want it to be formatted as blue colored format. Because notes colum does not fit in print area as i mentioned it with blue arrow.
So i can say that my codes are generating report as the red part.
But i want it to fit in the printable area in blue part. So i want to be able to set cell sizes. And text will fit in that cell size left to right. Up to down cell size will be dynamic as text size may change.
If you're using openpyxl, you can actually change the styles of your cells, as outlined in the documentation:
from openpyxl.styles import Alignment
note_cell.alignment = Alignment(wrap_text=True)
Or create an alignment object before your for... loop and reuse it:
al = Alignment(wrap_text=True)
for note in notes:
...
note_cell = worksheet["C%d" % (row,)]
note_cell.alignment = al
which will be more memory-efficient.

Creating tables using plotly

I am using plotly offline to create a table.But the output is displayed as a single row,not as shown in the output format given in the following link(i.e not as a table)
https://plot.ly/python/table/#changing-row-and-column-size(“Changing Row and column size”)
Here is the code,
import plotly
import plotly.graph_objs as go
#plotly.offline.init_notebook_mode()
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
values = [[['geneNames', 'uniprotIDs', 'ec-code', 'subcellularLocation', 'tissueSpecificity',
'proteinName', 'subunit', 'species']], [[' G6PC', ' P35575', ' 3.1.3.9',
' Endoplasmic reticulum membrane', 'No Data', ' Glucose-6-phosphatase alpha',
'No Data', ' Homo sapiens']]]
trace0 = go.Table(
type = 'table',
columnorder = [1,2],
columnwidth = [80,400],
header = dict(
values = [['<b>PARAMETERS</b>'],
['<b>VALUES</b>']],
line = dict(color = '#506784'),
fill = dict(color = '#119DFF'),
align = ['left','center'],
font = dict(color = 'white', size = 12),
height = 40
),
cells = dict(
values = values,
line = dict(color = '#506784'),
fill = dict(color = ['#25FEFD', 'white']),
align = ['left', 'center'],
font = dict(color = '#506784', size = 12),
height = 30
))
data = [trace0]
plot(data)
I would like to ask for some help
EDIT:
Would it be possible to save the table in png/txt format?I tried replacing 'uniprot.html' with 'uniprot.png'. But the file gets saved as uniprot.png.html.
Looks like as if the document and the current version of Plotly are out of sync. Try using a simple of list of two lists (column 1 and column 2).
values = [['geneNames', 'uniprotIDs', 'ec-code', 'subcellularLocation', 'tissueSpecificity', 'proteinName', 'subunit', 'species'],
[' G6PC', ' P35575', ' 3.1.3.9', ' Endoplasmic reticulum membrane', 'No Data', ' Glucose-6-phosphatase alpha', 'No Data', ' Homo sapiens']
]
Regarding your question about saving (figures) as PNG, check out orca. This is the graphing engine which sits behind plotly.
To be honest, it's a little fiddly at first, but easy once you get going, and it provides PNG support!

Python - reading text file delimited by semicolon, ploting chart using openpyxl

I have copied the text file to excel sheet separating cells by ; delimiter.
I need to plot a chart using the same file which I achieved. Since all the values copied are type=str my chart gives me wrong points.
Please suggest to overcome this. Plot is should be made of int values
from datetime import date
from openpyxl import Workbook,load_workbook
from openpyxl.chart import (
LineChart,
Reference,
Series,
)
from openpyxl.chart.axis import DateAxis
excelfile = "C:\Users\lenovo\Desktop\how\openpychart.xlsx"
wb = Workbook()
ws = wb.active
f = open("C:\Users\lenovo\Desktop\sample.txt")
data = []
num = f.readlines()
for line in num:
line = line.split(";")
ws.append(line)
f.close()
wb.save(excelfile)
wb.close()
wb = load_workbook(excelfile, data_only=True)
ws = wb.active
c1 = LineChart()
c1.title = "Line Chart"
##c1.style = 13
c1.y_axis.title = 'Size'
c1.x_axis.title = 'Test Number'
data = Reference(ws, min_col=6, min_row=2, max_col=6, max_row=31)
series = Series(data, title='4th average')
c1.append(series)
data = Reference(ws, min_col=7, min_row=2, max_col=7, max_row=31)
series = Series(data, title='Defined Capacity')
c1.append(series)
##c1.add_data(data, titles_from_data=True)
# Style the lines
s1 = c1.series[0]
s1.marker.symbol = "triangle"
s1.marker.graphicalProperties.solidFill = "FF0000" # Marker filling
s1.marker.graphicalProperties.line.solidFill = "FF0000" # Marker outline
s1.graphicalProperties.line.noFill = True
s2 = c1.series[1]
s2.graphicalProperties.line.solidFill = "00AAAA"
s2.graphicalProperties.line.dashStyle = "sysDot"
s2.graphicalProperties.line.width = 100050 # width in EMUs
##s2 = c1.series[2]
##s2.smooth = True # Make the line smooth
ws.add_chart(c1, "A10")
##
##from copy import deepcopy
##stacked = deepcopy(c1)
##stacked.grouping = "stacked"
##stacked.title = "Stacked Line Chart"
##ws.add_chart(stacked, "A27")
##
##percent_stacked = deepcopy(c1)
##percent_stacked.grouping = "percentStacked"
##percent_stacked.title = "Percent Stacked Line Chart"
##ws.add_chart(percent_stacked, "A44")
##
### Chart with date axis
##c2 = LineChart()
##c2.title = "Date Axis"
##c2.style = 12
##c2.y_axis.title = "Size"
##c2.y_axis.crossAx = 500
##c2.x_axis = DateAxis(crossAx=100)
##c2.x_axis.number_format = 'd-mmm'
##c2.x_axis.majorTimeUnit = "days"
##c2.x_axis.title = "Date"
##
##c2.add_data(data, titles_from_data=True)
##dates = Reference(ws, min_col=1, min_row=2, max_row=7)
##c2.set_categories(dates)
##
##ws.add_chart(c2, "A61")
### setup and append the first series
##values = Reference(ws, (1, 1), (9, 1))
##series = Series(values, title="First series of values")
##chart.append(series)
##
### setup and append the second series
##values = Reference(ws, (1, 2), (9, 2))
##series = Series(values, title="Second series of values")
##chart.append(series)
##
##ws.add_chart(chart)
wb.save(excelfile)
wb.close()
I have modified below code in for loop and it worked.
f = open("C:\Users\lenovo\Desktop\sample.txt")
data = []
num = f.readlines()
for line in num:
line = line.split(";")
new_line=[]
for x in line:
if x.isdigit():
x=int(x)
new_line.append(x)
else:
new_line.append(x)
ws.append(new_line)
f.close()
wb.save(excelfile)
wb.close()
For each list,for each value check if its a digit, if yes converts to integer and store in another list.
Using x=map(int,x) didnt work since I have character values too.
I felt above is much more easy than using x=map(int,x) with try and Except
Thanks
Basha