There's a table containing a list of 3 employees and 3-4 courses they are supposed to take respectively. I want to create individual PDFs for every employee in this table. First PDF will have list of 3 courses to be taken by Emp1, 2nd PDF will have list of 3 courses to be taken by Emp2 and so on.
The below code is creating just 1 PDF and contains list of all courses for all employees together.
My idea is to initially split/ group the data based on EmpNo and then create individual PDF and to do this I need to create a For Loop for iterating. However, I am unable to figure this...
DataFrame Code
pip install fpdf #To generate PDF
import pandas as pd
data = {'EmpNo': ['123','123','123','456','456', '456','456','789','789','789'],
'First Name': ['John', 'John', 'John', 'Jane', 'Jane', 'Jane', 'Jane', 'Danny', 'Danny', 'Danny'],
'Last Name': ['Doe', 'Doe' ,'Doe', 'Doe' ,'Doe', 'Doe', 'Doe', 'Roberts', 'Roberts', 'Roberts'],
'Activity Code': ['HR-CONF-1', 'HR-Field-NH-ONB','COEATT-2021','HR-HBK-CA-1','HR-WD-EMP','HR-LIST-1','HS-Guide-3','HR-WD-EMP','HR-LIST-1','HS-Guide-3'],
'RegistrationDate': ['11/22/2021', '11/22/2021', '11/22/2021', '11/22/2021', '11/22/2021', '11/22/2021','11/22/2021', '11/22/2021', '11/22/2021','11/22/2021']}
df = pd.DataFrame(data = data, columns = ['EmpNo','First Name', 'Last Name', 'Activity Code', 'RegistrationDate'])
employees = data['EmpNo']
employees = data.drop_duplicates(subset=['EmpNo'])
print(df)
Input looks like this,
PDF Generation Code
from fpdf import FPDF
class PDF(FPDF):
def header(self):
# Arial bold 15
self.set_font('Helvetica', 'B', 15)
# Move to the right
self.cell(80)
# Title
self.cell(42, 2, 'Plan', 0, 0, 'C')
# Line break
self.ln(20)
# Page footer
def footer(self):
# Position at 1.5 cm from bottom
self.set_y(-15)
# Arial italic 8
self.set_font('Helvetica', 'I', 8)
# Page number
self.cell(0, 10, 'Page ' + str(self.page_no()) + '/{nb}', 0, 0, 'C')
# Footer image First is horizontal, second is vertical, third is size
for EmpNo in employees['EmpNo']:
print (EmpNo)
# Instantiation of inherited class
pdf = PDF()
pdf.alias_nb_pages()
pdf.add_page()
pdf.set_font('Helvetica', '', 11)
pdf.cell(80, 6, 'Employee ID: ' + str(data.loc[0]['EmpNo']), 0, 1, 'L')
pdf.ln(2.5)
pdf.multi_cell(160, 5, 'Dear ' + str(data.loc[0]['First Name']) + ' ' + str(data.loc[0]['Last Name']) + ', Please find below your Plan.', 0, 1, 'L')
pdf.cell(80, 6, '', 0, 1, 'C')
pdf.set_font('Helvetica', 'B', 13)
pdf.cell(80, 6, 'Name', 0, 0, 'L')
pdf.cell(40, 6, 'Date', 0, 0, 'L')
pdf.cell(40, 6, 'Link', 0, 1, 'L')
pdf.cell(80, 6, '', 0, 1, 'C')
pdf.set_font('Helvetica', '', 8)
for i in range (len(data)):
pdf.set_font('Helvetica', '', 8)
pdf.cell(80, 6, data.loc[0+i]['Activity Code'], 0, 0, 'L')
#pdf.cell(40, 6, data.loc[0+i]['Activity Link'], 0, 1, 'L')
pdf.cell(40, 6, data.loc[0+i]['RegistrationDate'], 0, 0, 'L')
pdf.set_font('Helvetica', 'U', 8)
pdf.cell(40, 6, 'Click Here', 0, 1, 'L', link = 'www.google.com')
pdf.set_font('Helvetica', 'B', 10)
pdf.cell(80, 6, '', 0, 1, 'C')
pdf.cell(80, 6, 'IF YOU REQUIRE ANY HELP, PLEASE CONTACT US', 0, 0, 'L')
pdf.output(str(data.loc[0]['First Name']) + ' ' + str(data.loc[0]['Last Name'])+ '.pdf', 'F')
Here's a snap of PDF generated.
I can split the data using below code, but I am stuck at how to call out individual splits and then further create multiple PDF
splits = list(data.groupby('EmpNo'))
Any help would be greatly appreciated. Thanks.
I would write the groupby like this:
for EmpNo, data in df.groupby("EmpNo"):
For each group, the groupby will return the variable it groups on, and the dataframe which matches that variable.
Next, I would extract the first row of that dataframe. This is to make it easier to get the name and similar attributes.
first_row = data.iloc[0]
(What's the difference between iloc and loc?)
Since we have the employee ID already, we can skip looking it up in the dataframe. For other attributes, we can look it up like first_row['First Name'].
pdf.cell(80, 6, 'Employee ID: ' + str(EmpNo), 0, 1, 'L')
# ...
pdf.multi_cell(160, 5, 'Dear ' + str(first_row['First Name']) + ' ' + str(first_row['Last Name']) + ', Please find below your Plan.', 0, 1, 'L')
Next, in this loop which loops over the subset, I would use .iterrows() to do the loop instead of using range() and .loc. This is easier and won't break if the index of your dataframe doesn't start with zero. (After grouping, the second group's index won't start with zero anymore.)
Here is the final source code after the changes:
import pandas as pd
data = {'EmpNo': ['123','123','123','456','456', '456','456','789','789','789'],
'First Name': ['John', 'John', 'John', 'Jane', 'Jane', 'Jane', 'Jane', 'Danny', 'Danny', 'Danny'],
'Last Name': ['Doe', 'Doe' ,'Doe', 'Doe' ,'Doe', 'Doe', 'Doe', 'Roberts', 'Roberts', 'Roberts'],
'Activity Code': ['HR-CONF-1', 'HR-Field-NH-ONB','COEATT-2021','HR-HBK-CA-1','HR-WD-EMP','HR-LIST-1','HS-Guide-3','HR-WD-EMP','HR-LIST-1','HS-Guide-3'],
'RegistrationDate': ['11/22/2021', '11/22/2021', '11/22/2021', '11/22/2021', '11/22/2021', '11/22/2021','11/22/2021', '11/22/2021', '11/22/2021','11/22/2021']}
df = pd.DataFrame(data = data, columns = ['EmpNo','First Name', 'Last Name', 'Activity Code', 'RegistrationDate'])
from fpdf import FPDF
class PDF(FPDF):
def header(self):
# Arial bold 15
self.set_font('Helvetica', 'B', 15)
# Move to the right
self.cell(80)
# Title
self.cell(42, 2, 'Plan', 0, 0, 'C')
# Line break
self.ln(20)
# Page footer
def footer(self):
# Position at 1.5 cm from bottom
self.set_y(-15)
# Arial italic 8
self.set_font('Helvetica', 'I', 8)
# Page number
self.cell(0, 10, 'Page ' + str(self.page_no()) + '/{nb}', 0, 0, 'C')
# Footer image First is horizontal, second is vertical, third is size
for EmpNo, data in df.groupby("EmpNo"):
# Get first row of grouped dataframe
first_row = data.iloc[0]
# Instantiation of inherited class
pdf = PDF()
pdf.alias_nb_pages()
pdf.add_page()
pdf.set_font('Helvetica', '', 11)
pdf.cell(80, 6, 'Employee ID: ' + str(EmpNo), 0, 1, 'L')
pdf.ln(2.5)
pdf.multi_cell(160, 5, 'Dear ' + str(first_row['First Name']) + ' ' + str(first_row['Last Name']) + ', Please find below your Plan.', 0, 1, 'L')
pdf.cell(80, 6, '', 0, 1, 'C')
pdf.set_font('Helvetica', 'B', 13)
pdf.cell(80, 6, 'Name', 0, 0, 'L')
pdf.cell(40, 6, 'Date', 0, 0, 'L')
pdf.cell(40, 6, 'Link', 0, 1, 'L')
pdf.cell(80, 6, '', 0, 1, 'C')
pdf.set_font('Helvetica', '', 8)
for _, row in data.iterrows():
pdf.set_font('Helvetica', '', 8)
pdf.cell(80, 6, row['Activity Code'], 0, 0, 'L')
#pdf.cell(40, 6, row['Activity Link'], 0, 1, 'L')
pdf.cell(40, 6, row['RegistrationDate'], 0, 0, 'L')
pdf.set_font('Helvetica', 'U', 8)
pdf.cell(40, 6, 'Click Here', 0, 1, 'L', link = 'www.google.com')
pdf.set_font('Helvetica', 'B', 10)
pdf.cell(80, 6, '', 0, 1, 'C')
pdf.cell(80, 6, 'IF YOU REQUIRE ANY HELP, PLEASE CONTACT US', 0, 0, 'L')
pdf.output(str(first_row['First Name']) + ' ' + str(first_row['Last Name'])+ '.pdf', 'F')
Tested, and it works.
Related
I am constructing a class to produce automated pdf reports. (Using FPDF) In my class I have so far defined two functions. One that renders the first page(front) and one that renders a second page(page_two). These two functions produces each what I want. But when I try to combine the two in the function join the second page gets all white.
I don't understand why. Any help would be much appreciated.
from fpdf import FPDF
class MY_PDF(FPDF):
def _init_(self, **kwargs):
super(MY_PDF, self)-__init__(**kwargs)
pdf.add_font('Arial', '', r"c:\WINDOWS\Fonts\ARIAL.ttf", uni=True)
pdf.add_font('Arial_Bold', '', r"c:\WINDOWS\Fonts\ARIALBD.ttf", uni=True)
pdf.add_font('Georgia', '', r"c:\WINDOWS\Fonts\GEORGIA.ttf", uni=True)
pdf.add_font('Calibri', '', r"c:\WINDOWS\Fonts\CALIBRI.ttf", uni=True)
# A4.
WIDTH = 210
HEIGHT = 297
def front(self, title, second_title):
self.set_fill_color(0,0,90)
self.rect(0.5, 50, WIDTH-1, 75, 'F')
self.set_fill_color(149,194,61)
pdf.rect(14, 12, 5, 280, 'F')
self.set_font('Arial', 'B', 38)
self.set_text_color(255, 255, 255)
self.cell(15)
self.cell(150, 135, txt=f'{title}')
self.ln(10)
self.set_font('Arial', '', 28)
self.set_text_color(255, 255, 255)
self.cell(15)
self.cell(150, 150, txt=f'{second_title}')
#self.image('logga.png', 25, 12, 50)
self.ln()
def page_two(self, name, date, nr):
self.set_font('Arial', '', 9)
self.ln(250)
self.cell(20)
self.cell(0, 0, txt="©", align='L', ln=0)
self.cell(-160)
self.cell(0, 0, txt='Company name', align='L', ln=2)
self.ln(4)
self.cell(30)
self.cell(0, 0, txt=f'Author: {name}', align='L', ln=2)
self.ln(4)
self.cell(30)
self.cell(0, 0, txt=f'Date: {date}', align='L', ln=2)
self.ln(4)
self.cell(30)
self.cell(0, 0, txt=f'Number: {nr}', align='L', ln=2)
self.ln()
def join(self, title, second_title, name, date, nr):
self.add_page()
self.front(title, second_title)
self.add_page()
self.page_two(name, date, nr)
pdf= MY_PDF()
pdf.join('TITLE!', 'some other title', 'Name Name', '2021-11-30', '21262')
pdf.output('output.pdf')
I have to create multiple radio buttons. Each has its own name and location on grid. There are also several variables involved.
I stored all the data to create these radio buttons in a tuple
(I know that FONTS does not cause a problem, its stored above this but isn't shown here):
self.unitType = IntVar()
self.matPropSel = IntVar()
self.secProfSel = IntVar()
self.endSupSel = IntVar()
self.loadTypeSel = IntVar()
self.RADIOLABELS = ( # Text, Font, Variable, Value, Row, Column
('English', self.FONTS[3], self.unitType, 1, 3, 1),
('metric', self.FONTS[3], self.unitType, 2, 4, 1),
('select preset', self.FONTS[3], self.matPropSel, 1, 6, 1),
('manual entry', self.FONTS[3], self.matPropSel, 2, 7, 1),
('select preset', self.FONTS[3], self.secProfSel, 1, 10, 1),
('manual entry', self.FONTS[3], self.secProfSel, 2, 11, 1),
('one end', self.FONTS[3], self.endSupSel, 1, 15, 1),
('both ends', self.FONTS[3], self.endSupSel, 2, 16, 1),
('point', self.FONTS[3], self.loadTypeSel, 1, 18, 1),
('uniform distribution', self.FONTS[3], self.loadTypeSel, 2, 19, 1),
('uniform variation', self.FONTS[3], self.loadTypeSel, 3, 20, 1)
)
So, how would I use a for loop to go through this tuple and generate a radio button from each line? Do all of the variables have to be the same? I am having problems with them.
Here is my attempt at a loop:
outerIndexer = 0
for labels in self.RADIOLABELS:
Radiobutton(self, text=self.RADIOLABELS[outerIndexer][0], font=self.RADIOLABELS[outerIndexer][1],
variable=self.RADIOLABELS[outerIndexer][2], value=self.RADIOLABELS[outerIndexer][3])\
.grid(row=self.RADIOLABELS[outerIndexer][4], column=self.RADIOLABELS[outerIndexer][5])
outerIndexer += 1
You can do it like this by looping through the RADIOLABELS. Note: it is also recommended to save the button to a list so it doesn't get lost.
self.RADIOLABELS = ( # Text, Font, Variable, Value, Row, Column
('English', self.FONTS[3], self.unitType, 1, 3, 1),
('metric', self.FONTS[3], self.unitType, 2, 4, 1),
('select preset', self.FONTS[3], self.matPropSel, 1, 6, 1),
('manual entry', self.FONTS[3], self.matPropSel, 2, 7, 1),
('select preset', self.FONTS[3], self.secProfSel, 1, 10, 1),
('manual entry', self.FONTS[3], self.secProfSel, 2, 11, 1),
('one end', self.FONTS[3], self.endSupSel, 1, 15, 1),
('both ends', self.FONTS[3], self.endSupSel, 2, 16, 1),
('point', self.FONTS[3], self.loadTypeSel, 1, 18, 1),
('uniform distribution', self.FONTS[3], self.loadTypeSel, 2, 19, 1),
('uniform variation', self.FONTS[3], self.loadTypeSel, 3, 20, 1)
)
radiobuttons = []
for _Text, _Font, _Variable, _Value, _Row, _Column in self.RADIOLABELS: # it will unpack the values during each iteration
_Radio = tk.Radiobutton(root, text = _Text, font = _Font, variable = _Variable, value = _Value)
# ^ root should be the frame/Tk you're trying to place it on, it will be self if this is a direct subclass of a Frame or Tk
# ^ or Radiobutton(.....) if you did from tkinter import *
_Radio.grid(row = _Row, column = _Column)
radiobuttons.append(_Radio)
I have created some fictitious, though representative, clinical trial type data using Pandas, and now come to some test reporting in ReportLab.
The data has a block (~50 rows) where the treatment column is 'Placebo' and the same amount where the treatment is 'Active'. I simply want to list the data using a sub-heading of 'Treatment Group: Placebo' for the first set and 'Treatment Group: Active' for the second.
There are some hits on a similar topic, and, indeed I've used one of the suggested techniques, namely to extend the arguments of a header functions using partial from functools.
title1 = "ACME Corp CONFIDENTIAL"
title2 = "XYZ123 / Anti-Hypertensive Draft"
title3 = "Protocol XYZ123"
title4 = "Study XYZ123"
title5 = "Listing of Demographic Data by Treatment Arm"
title6 = "All subjects"
def title(canvas, doc, bytext):
canvas.saveState()
canvas.setFont(styleN.fontName, styleN.fontSize)
canvas.drawString(DOCMARGIN, PAGE_HEIGHT*.975, title1)
canvas.drawString(DOCMARGIN, PAGE_HEIGHT*.950, title2)
canvas.drawString(DOCMARGIN, PAGE_HEIGHT*.925, title3)
canvas.drawCentredString(PAGE_WIDTH/2.0, PAGE_HEIGHT*.900, title4)
canvas.drawCentredString(PAGE_WIDTH/2.0, PAGE_HEIGHT*.875, title5)
canvas.drawCentredString(PAGE_WIDTH/2.0, PAGE_HEIGHT*.850, title6)
canvas.drawString(DOCMARGIN, PAGE_HEIGHT*.825, "Treatment Group:" + bytext)
canvas.restoreState()
This is then called as follows. n_groups has the value of 2 from a summary query and 0 maps to 'Placebo' and 1 maps to active.
def build_pdf(doc):
ptemplates = []
for armcd in range(n_groups):
ptemplates.append(PageTemplate(id = 'PT' + str(armcd), frames = [dataFrame,],
onPage = partial(title, bytext=t_dict[armcd]),
onPageEnd = foot))
doc.addPageTemplates(ptemplates)
elements = []
for armcd in range(n_groups):
elements.append(NextPageTemplate('PT' + str(armcd)))
sublist = [t for t in lista if t[0] == (armcd+1)]
sublist.insert(0,colheads)
data_table = Table(sublist, 6*[40*mm], len(sublist)*[DATA_CELL_HEIGHT], repeatRows=1)
data_table.setStyle(styleC)
elements.append(data_table)
elements.append(PageBreak())
doc.build(elements)
The report produces 6 pages. The first 3 pages of placebo data are correct, pages 5 & 6 of active data are correct, but page 4 - which should be the first page of the second 'active' group has the sub-title 'Treatment Group: Placebo'.
I have re-organized the order of the statements multiple times, but can't get Page 4 to sub-title correctly. Any help, suggestions or magic would be much appreciated.
[Edit 1: sample data structure]
The 'top' of the data starts as:
[
[1, 'Placebo', '000001-000015', '1976-09-20', 33, 'F', 'Black'],
[1, 'Placebo', '000001-000030', '1959-04-26', 50, 'M', 'Asian'],
[1, 'Placebo', '000001-000031', '1946-02-07', 64, 'F', 'Asian'],
[1, 'Placebo', '000001-000046', '1947-11-08', 62, 'M', 'Asian'],
etc for 50 rows, then continues with
[2, 'Active', '000001-000002', '1962-02-28', 48, 'F', 'Black'],
[2, 'Active', '000001-000008', '1975-10-20', 34, 'M', 'Black'],
[2, 'Active', '000001-000013', '1959-01-19', 51, 'M', 'White'],
[2, 'Active', '000001-000022', '1962-01-12', 48, 'F', 'Black'],
[2, 'Active', '000001-000036', '1976-10-17', 33, 'F', 'Asian'],
[2, 'Active', '000001-000045', '1980-12-31', 29, 'F', 'White'],
for another 50.
The column header inserted is:
['Treatment Arm Code',
'Treatment Arm',
'Site ID - Subject ID',
'Date of Birth',
'Age (Years)',
'Gender',
'Ethnicity'],
[Edit 2: A solution - move the PageBreak() and make it conditional:]
def build_pdf(doc):
ptemplates = []
for armcd in range(n_groups):
ptemplates.append(PageTemplate(id = 'PT' + str(armcd), frames = [dataFrame,],
onPage = partial(title, bytext=t_dict[armcd]),
onPageEnd = foot))
doc.addPageTemplates(ptemplates)
elements = []
for armcd in range(n_groups):
elements.append(NextPageTemplate('PT' + str(armcd)))
if armcd > 0:
elements.append(PageBreak())
sublist = [t for t in lista if t[0] == (armcd+1)]
sublist.insert(0,colheads)
data_table = Table(sublist, 6*[40*mm], len(sublist)*[DATA_CELL_HEIGHT], repeatRows=1)
data_table.setStyle(styleC)
elements.append(data_table)
doc.build(elements)
Say I have a dictionary of:
lst = {'adore': 10, 'hate': 10, 'hello': 10, 'pigeon': 1, 'would': 5, 'elections': 5}
And I have a list of:
mylist = [['a new', 'party'], ['to', 'lol'], ['compete'], ['in', 'adore', 'the 2013'], ['federal', 'elections'], ['The Free', 'Voters'], ['leadership', 'declined to'], ['join forces', 'according to', 'a leaked'], ['email from', 'Bernd Lucke'], ['Advocating', 'adore'] ]
I want to be able to search the list for the keys in the dictionary. If a word in the list is a key, then to take the value of that key and add it to a counter. In the end, to have a total sum of all the values.
Is there a way to do this?
Like this?
lst = {'adore': 10, 'hate': 10, 'hello': 10, 'pigeon': 1, 'would': 5, 'elections': 5}
mylist = [['a new', 'party'], ['to', 'lol'], ['compete'], ['in', 'adore', 'the 2013'], ['federal', 'elections'], ['The Free', 'Voters'], ['leadership', 'declined to'], ['join forces', 'according to', 'a leaked'], ['email from', 'Bernd Lucke'], ['Advocating', 'adore']]
print([lst.get(i) for j in mylist for i in j if lst.get(i) != None])
print(sum([lst.get(i) for j in mylist for i in j if lst.get(i) != None]))
Output:
[10, 5, 10]
25
If you don't like them in one line:
total = []
for i in mylist:
for j in i:
if lst.get(i) != None:
total.append(lst.get(i))
print(sum(total))
Probably you can do this in a more pythonic way.
lst = {'adore': 10, 'hate': 10, 'hello': 10, 'pigeon': 1, 'would': 5}
counter = {'adore': 0, 'hate': 0, 'hello': 0, 'pigeon': 0, 'would': 0}
mylist = [['a new', 'party'], ['to', 'lol'], ['compete'], ['in', 'adore', 'the 2013'], ['federal', 'elections'], ['The Free', 'Voters'], ['leadership', 'declined to'], ['join forces', 'according to', 'a leaked'], ['email from', 'Bernd Lucke'], ['Advocating', 'adore'] ]
def func():
for key in lst.keys():
for item in mylist:
if key in item:
counter[key] = counter[key] + lst[key]
func()
print sum(counter.values())
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()