-
Notifications
You must be signed in to change notification settings - Fork 0
/
report.py
197 lines (175 loc) · 8.68 KB
/
report.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
from fpdf import FPDF
class PDF(FPDF):
def footer(self):
# Set position of the footer
self.set_y(-15)
# set font
self.set_font('helvetica', 'I', 8)
# Page number
self.cell(0, 10, f'Page {self.page_no()}', align='C')
def create_table(self, table_data, title='', data_size = 10, title_size=12, align_data='L', align_header='L', cell_width='even', x_start='x_default',emphasize_data=[], emphasize_style=None,emphasize_color=(0,0,0)):
"""
table_data:
list of lists with first element being list of headers
title:
(Optional) title of table (optional)
data_size:
the font size of table data
title_size:
the font size fo the title of the table
align_data:
align table data
L = left align
C = center align
R = right align
align_header:
align table data
L = left align
C = center align
R = right align
cell_width:
even: evenly distribute cell/column width
uneven: base cell size on lenght of cell/column items
int: int value for width of each cell/column
list of ints: list equal to number of columns with the widht of each cell / column
x_start:
where the left edge of table should start
emphasize_data:
which data elements are to be emphasized - pass as list
emphasize_style: the font style you want emphaized data to take
emphasize_color: emphasize color (if other than black)
"""
default_style = self.font_style
if emphasize_style == None:
emphasize_style = default_style
# default_font = self.font_family
# default_size = self.font_size_pt
# default_style = self.font_style
# default_color = self.color # This does not work
# Get Width of Columns
def get_col_widths():
col_width = cell_width
if col_width == 'even':
col_width = self.epw / len(data[0]) - 1 # distribute content evenly # epw = effective page width (width of page not including margins)
elif col_width == 'uneven':
col_widths = []
# searching through columns for largest sized cell (not rows but cols)
for col in range(len(table_data[0])): # for every row
longest = 0
for row in range(len(table_data)):
cell_value = str(table_data[row][col])
value_length = self.get_string_width(cell_value)
if value_length > longest:
longest = value_length
col_widths.append(longest + 4) # add 4 for padding
col_width = col_widths
### compare columns
elif isinstance(cell_width, list):
col_width = cell_width # TODO: convert all items in list to int
else:
# TODO: Add try catch
col_width = int(col_width)
return col_width
# Convert dict to lol
# Why? because i built it with lol first and added dict func after
# Is there performance differences?
if isinstance(table_data, dict):
header = [key for key in table_data]
data = []
for key in table_data:
value = table_data[key]
data.append(value)
# need to zip so data is in correct format (first, second, third --> not first, first, first)
data = [list(a) for a in zip(*data)]
else:
header = table_data[0]
data = table_data[1:]
line_height = self.font_size * 2.5
col_width = get_col_widths()
self.set_font(size=title_size)
# Get starting position of x
# Determin width of table to get x starting point for centred table
if x_start == 'C':
table_width = 0
if isinstance(col_width, list):
for width in col_width:
table_width += width
else: # need to multiply cell width by number of cells to get table width
table_width = col_width * len(table_data[0])
# Get x start by subtracting table width from pdf width and divide by 2 (margins)
margin_width = self.w - table_width
# TODO: Check if table_width is larger than pdf width
center_table = margin_width / 2 # only want width of left margin not both
x_start = center_table
self.set_x(x_start)
elif isinstance(x_start, int):
self.set_x(x_start)
elif x_start == 'x_default':
x_start = self.set_x(self.l_margin)
# TABLE CREATION #
# add title
if title != '':
self.multi_cell(0, line_height, title, border=0, align='j', ln=3, max_line_height=self.font_size)
self.ln(line_height) # move cursor back to the left margin
self.set_font(size=data_size)
# add header
y1 = self.get_y()
if x_start:
x_left = x_start
else:
x_left = self.get_x()
x_right = self.epw + x_left
if not isinstance(col_width, list):
if x_start:
self.set_x(x_start)
for datum in header:
self.multi_cell(col_width, line_height, datum, border=0, align=align_header, ln=3, max_line_height=self.font_size)
x_right = self.get_x()
self.ln(line_height) # move cursor back to the left margin
y2 = self.get_y()
self.line(x_left,y1,x_right,y1)
self.line(x_left,y2,x_right,y2)
for row in data:
if x_start: # not sure if I need this
self.set_x(x_start)
for datum in row:
if datum in emphasize_data:
self.set_text_color(*emphasize_color)
self.set_font(style=emphasize_style)
self.multi_cell(col_width, line_height, datum, border=0, align=align_data, ln=3, max_line_height=self.font_size)
self.set_text_color(0,0,0)
self.set_font(style=default_style)
else:
self.multi_cell(col_width, line_height, datum, border=0, align=align_data, ln=3, max_line_height=self.font_size) # ln = 3 - move cursor to right with same vertical offset # this uses an object named self
self.ln(line_height) # move cursor back to the left margin
else:
if x_start:
self.set_x(x_start)
for i in range(len(header)):
datum = header[i]
self.multi_cell(col_width[i], line_height, datum, border=0, align=align_header, ln=3, max_line_height=self.font_size)
x_right = self.get_x()
self.ln(line_height) # move cursor back to the left margin
y2 = self.get_y()
self.line(x_left,y1,x_right,y1)
self.line(x_left,y2,x_right,y2)
for i in range(len(data)):
if x_start:
self.set_x(x_start)
row = data[i]
for i in range(len(row)):
datum = row[i]
if not isinstance(datum, str):
datum = str(datum)
adjusted_col_width = col_width[i]
if datum in emphasize_data:
self.set_text_color(*emphasize_color)
self.set_font(style=emphasize_style)
self.multi_cell(adjusted_col_width, line_height, datum, border=0, align=align_data, ln=3, max_line_height=self.font_size)
self.set_text_color(0,0,0)
self.set_font(style=default_style)
else:
self.multi_cell(adjusted_col_width, line_height, datum, border=0, align=align_data, ln=3, max_line_height=self.font_size) # ln = 3 - move cursor to right with same vertical offset # this uses an object named self
self.ln(line_height) # move cursor back to the left margin
y3 = self.get_y()
self.line(x_left,y3,x_right,y3)