Using Python and ReportLab to create a facebook

Here’s a program that we use to generate our facebooks for incoming classes. It parses a CSV file with information about the students and combines that with jpg images to create a nice booklet in PDF form.

The book looks like this:

  • Cover page
  • JD students in alphabetical order (already sorted in the input file)
  • LLM students
  • Transfer students
  • Visiting students
  • Exchange students

Each page has a header, footer and 16 photos, along with information about each student. The program relies upon the ReportLab library and the Python Imaging Library. Let me know if you have questions or comments about the code. I do not hold this out as any kind of example of great Python code!


makephoto.pyBen ChapmanSept., 2007Released under the GPLversion .6

The program processes a CSV file that looks like this:

 First Name 0 * MI 1 * Last Name 2 * City 3 * State 4 * Degree Sought 5 Undergraduate School 6 * Undergrad Major 7 * Second Undergrad Major 8 * Grad school 9 * Photo file name ending in jpg 10 *

 * = will appear in output


from reportlab.pdfgen import canvasfrom reportlab.lib.pagesizes import letterfrom reportlab.lib.units import inchimport stringimport timeimport sys# Depends on 2.4?import csv

debug = 0

# Global data inputdatafile = "./facebook10.csv"# list of data items extracted from filemyoutput = []

# modify name as appropriate for this class yearoutputpdf = "./facebook10.pdf"studentinfo = []

# footer text - remove DRAFT when you go to productionfootertext = "Emory Law Students - Fall, 2007"myCanvas = canvas.Canvas(outputpdf, pagesize=letter,pageCompression=1)myCanvas.setAuthor("Emory Law IT Department")myCanvas.setSubject("Emory Law Student Photo Directory")myCanvas.setTitle("Emory Law Student Photo Directory")width, height = lettervert=[8*inch,5.5*inch,3*inch,.5*inch]horiz=(0*inch,2*inch,4*inch,6*inch)myCanvas.translate(.75*inch,1*inch)itemnumber = 0

def dataloader(datafile):    myfile = csv.reader(open(datafile))    # discard the header row    # iterate through the list of lines    for i in myfile:        photo = ''        try:            if (len(i[10])>0):                   photo = i[10]        except:            photo = "nophoto.jpg"        for j in range(len(i)):            i[j] = i[j].strip()        myoutput.append([i[0]+' ' + i[1] + ' ' +i[2],                         i[3]+', '+i[4],                         i[5],                         i[6],                         i[7],                         i[8],                         i[9],                         photo])    return myoutput

def getdata(degree='JD'):    students = []    for i in myoutput:        if debug: print "Getdata:",i        if i[2].lower() == degree.lower():            students.append(i)    return students

def pagebody(itemnumber):    myCanvas.translate(.75*inch,1*inch)    for j in vert:        for i in horiz:            if (itemnumber < len(studentinfo)):                if debug: print "Item number: ",itemnumber," len(student info) ",len(studentinfo)                textobject = myCanvas.beginText()                textobject.setFont('Times-Roman',6)                textobject.setTextOrigin(i,j-(.1*inch))                for line in [0,1,3,4,5,6]:                                   if (len(studentinfo[itemnumber][line])>0):                        textobject.textLine(studentinfo[itemnumber][line])                myCanvas.drawText(textobject)                if debug: print "IMAGE NAME",studentinfo[itemnumber][7]                try:                    myCanvas.drawImage("./photos10/"+studentinfo[itemnumber][7],x=i,y=j,width=1.5*inch,height=1.7*inch)                    if debug: print "/photos10/"+studentinfo[itemnumber][7]                except:                    myCanvas.drawImage("./photos10/nophoto.jpg",x=i,y=j,width=1.5*inch,height=1.7*inch)                    if debug: print "./photos10/"+studentinfo[itemnumber][7]                myCanvas.rect(x=i,y=j,width=1.5*inch,height=1.7*inch)                itemnumber = itemnumber + 1    return itemnumber

def footer():    myfooter = myCanvas.beginText()    #myfooter.setTextOrigin(4.5*inch,-.75*inch)    myfooter.setTextOrigin(1*inch,-.75*inch)    myfooter.setFont('Times-Italic',10)    curpage = int(myCanvas.getPageNumber()) - 1    myfooter.textLine(footertext + " DRAFT - NOT FOR DISTRIBUTION - Page %d" % curpage)    myCanvas.drawText(myfooter)

def header(degree="JD"):    myCanvas.drawCentredString(4.25*inch, 10.75*inch,degree + " Students")

def coverpage():    mytitle = myCanvas.beginText()    # comment out the following lines when you go to production    mytitle.setFont('Times-Roman',64)    mytitle.setTextOrigin(.5*inch,3*inch)    mytitle.textLine('DRAFT')    mytitle.textLine('INTERNAL ONLY')    # end draft lines    mytitle.setFont('Times-Roman',32)    mytitle.setTextOrigin(2*inch,6*inch)    mytitle.textLine("Emory Law School")    mytitle.setFont('Times-Roman',16)    mytitle.textLine("Student Photo Book")    mytitle.textLine("Fall - 2007")       myCanvas.drawText(mytitle)    # Generate a time stamp    mytimestamp = myCanvas.beginText()    mytimestamp.setFont('Times-Roman',8)    mytimestamp.setTextOrigin(.5*inch,.5*inch)    mytimestamp.textLine(timestamp())    myCanvas.drawText(mytimestamp)

def sectionpage(degree):    mytitle = myCanvas.beginText()    mytitle.setFont('Times-Roman',16)    mytitle.setTextOrigin(4*inch,8*inch)    mytitle.textLine(degree+" Students")    myCanvas.drawText(mytitle)

def bodypage(studentinfo,degree):    itemnumber=0    pages = len(studentinfo) / 16    for page in range(0,pages+1):        header(degree)        itemnumber = pagebody(itemnumber)        footer()        myCanvas.showPage()

def timestamp():    curtime = time.localtime()    return "Generated %02d-%02d-%02d at %02d:%02d" % (curtime[1],curtime[2],curtime[0],curtime[3],curtime[4])

## # Main Program##

if __name__ == '__main__':    # load data array from csv file    mydata = dataloader(datafile)    # draw cover page    coverpage()    myCanvas.showPage()    # create a separate section for each group at the law school    for degree in ("JD","LLM","Transfer","Visiting","Exchange"):        studentinfo = getdata(degree)        bodypage(studentinfo,degree)    # save the PDF file

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s