Reportlab: header with data from the page

I use the on page function and page template to create headings for a subset of the pages in my document:

templates.append(PageTemplate(id='Overview', frames=frame, onPage=HeaderOverview)) 

The header function for this template:

 ################################ # Function HeaderOverview - header for overview page def HeaderOverview(canvas,doc): canvas.saveState() headboxh = 15 headboxx = 20 headboxy = 730 headboxw = 570 canvas.rect(headboxx, headboxy, headboxw, headboxh, fill=1) canvas.setFillColor(colors.black) canvas.setFont("Helvetica", 14) canvas.setFillColor(colors.white) canvas.drawString(headboxx + 15,headboxy+.25*headboxh,"Mathematics") textWidth = stringWidth("Mathematics", "Helvetica", 12) canvas.setFont("Helvetica", 12) canvas.drawString(headboxw - 15 - textWidth,headboxy+.25*headboxh,course) canvas.restoreState() 

This works fine, except that the passed course variable (which changes with each page in the section) is the last in the sequence, since this function does not really get called until the final build (I think it works), I need to do this, so that the value is the value that is on the page. If I could draw it when I wrote the page myself, that would be nice too. Here is my attempt:

 #################################################################################### # Function makeGradeOverview(course): makes Overview chart for grade # def makeGradeOverview(canvas, course): report.append(NextPageTemplate("Overview")) report.append(PageBreak()) headboxh = 50 headboxx = 20 headboxy = 600#730 headboxw = 540 canvas.saveState() canvas.setFont("Helvetica", 12) textWidth = stringWidth(course, "Helvetica", 12) canvas.drawString(headboxw - 15 - textWidth,headboxy+.25*headboxh,course) canvas.restoreState() # put course name as title if len(course)<=2: headerrow = ''.join(['Grade ', course, ' Overview']) else: headerrow = ''.join([course, ' Overview']) report.append(Paragraph(headerrow, styles["Overview Title"])) report.append(Spacer(1, 16)) GridInfo = [] topics = topiclist(course) for topic in topics: report.append(Paragraph(topic, styles["Overview Sub"])) report.append(Spacer(1, 8)) subtopics = subtopiclist(course, topic) sublist = [] for subtopic in subtopics: report.append(Paragraph(''.join([r'<bullet>&bull</bullet>',subtopic]), styles["Overview Table"])) 

This does not cause an error or anything else, but actually does not draw anything.

Thanks for the help!

+4
source share
1 answer

Here is another idea ...

It might be useful to use certain streams that can be identified to update the course. You can add custom attributes to current resources, if necessary, to help identify them (see this post.).

For example, you can do something like this:

 ... report.append(some_content) report.append(PageBreak()) report[-1].new_course = True # gives that PageBreak flowable a custom attribute report.append(some_more_content) ... 

And configure some variables:

 course_list = [...] course_iter = iter(course_list) current_course = next(course_iter) 

You can then check each stream after rendering it, to see if it has this attribute and updates the current course if it does.

 def afterFlowable(flowable): global current_course if hasattr(flowable, 'new_course'): current_course = next(course_iter) doc.afterFlowable = afterFlowable 

HeaderOverview will be able to use the current_course variable to get the correct course, since both HeaderOverview and afterFlowable called at different points during the final build.

+3
source

All Articles