Newer
Older
"""
Contains utility class for writing to xlsx
"""
from openpyxl import Workbook, load_workbook
from openpyxl.utils import get_column_letter
from openpyxl.styles import Font
from openpyxl.styles.fills import PatternFill
from openpyxl.chart import PieChart, Reference
class ExcelWriter:
"""
Utility class which writes `TestEntry` objects to an excel file.
Creates file if it does not exist.
"""
PASS_COL = "00FF00"
FAIL_COL = "FF0000"
def __init__(self, output_file):
self.work_book = self.get_workbook()
self.work_sheet = self.work_book.active
def get_entry_with_id(self, test_id):
"""
When inserting an entry, it might be a test being re-run. In that case,
the row containing that test needs to be updated, as opposed to appending
the entry to the end of the file.
This method finds that row, returning the row number,
or -1 in the case where that test is not in the report yet.
"""
for cell in self.work_sheet["A"]:
if cell.value is None:
return -1
if cell.value == test_id:
print("MATCH with id {} at row {}".format(test_id, cell.row))
return cell.row
return -1
def get_last_row(self):
"""
return index of first empty row
"""
for cell in self.work_sheet["A"]:
if cell.value is None:
return cell.row
def write_test_entry(self, test_entry):
"""
Write a test entry to the work_sheet
"""
existing_entry_row = self.get_entry_with_id(test_entry.test_id)
last_row = self.get_last_row()
# Use the above two values to pick a row
entry_row = existing_entry_row if existing_entry_row != -1 else last_row
# Pick a cell color based on test outcome
cell_col = ExcelWriter.PASS_COL if test_entry.result == "PASS" else ExcelWriter.FAIL_COL
# Test entry as a list
entry_vals = test_entry.as_list()
for col, cell_vale in zip(self.work_sheet.iter_cols(min_row=entry_row,
max_col=len(entry_vals),
max_row=entry_row), entry_vals):
for cell in col:
cell.value = cell_vale
cell.fill = PatternFill("solid", fgColor=cell_col)# cellCol
def get_workbook(self):
"""
Returns workbook at output_file/.
Creates and initialises it (adds headers) if it doesn't exist yet.
"""
try:
work_book = load_workbook(filename=self.output_file)
return work_book
except FileNotFoundError:
work_book = Workbook()
init_workbook(work_book)
return work_book
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
def get_chart_work_sheet(self):
"""
Returns work sheet where charts will be drawn to.
Creates if does not exist
"""
try:
chart_work_sheet = self.work_book["charts"]
return chart_work_sheet
except KeyError:
return self.work_book.create_sheet("charts")
def write_pie_chart_data(self):
"""
Writes pie chart data (the charts sheet) required to construct the pie chart later
"""
chart_work_sheet = self.get_chart_work_sheet()
# Get data from main work sheet
last_row = self.get_last_row()
data = Reference(self.work_sheet, min_col=3, max_col=3, min_row=2, max_row=last_row)
# Construct pie chart
pie = PieChart()
pie.add_data(data, titles_from_data=True)
#pie.set_categories(labels)
pie.title = "PASS/FAIL Distribution"
chart_work_sheet.add_chart(pie, "A1")
def write_pie_chart(self):
"""
Writes a pie chart showing PASS/FAIL stats.
Writes the chart to a separate work sheet.
"""
chart_work_sheet = self.get_chart_work_sheet()
# Get data from main work sheet
last_row = self.get_last_row()
data = Reference(self.work_sheet, min_col=3, max_col=3, min_row=2, max_row=last_row)
# Construct pie chart
pie = PieChart()
pie.add_data(data, titles_from_data=True)
#pie.set_categories(labels)
pie.title = "PASS/FAIL Distribution"
chart_work_sheet.add_chart(pie, "A1")
def save(self):
"""
Save workbook to disk.
"""
self.work_book.save(filename=self.output_file)
def init_workbook(work_book):
"""
Writes column headers to ws.
"""
headers = [("Test ID", 10), ("Test name", 80), ("Result", 6), ("Error Message", 100),
("NFV API", 25), ("Robot Test File", 25)]
header_font = Font(bold=True)
work_sheet = work_book.active
for col, header in zip(work_sheet.iter_cols(min_row=1, max_col=len(headers),
max_row=1), headers):
for cell in col:
header_name = header[0]
colsize = header[1]
work_sheet.column_dimensions[get_column_letter(cell.column)].width = colsize
cell.value = header_name
cell.font = header_font