I'm using the on page function and a page template to make headers 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 great, except that the course variable that's passed (which changes with each page in the section) is the last one in the sequence, since this function's not really called until the final build (I think that's how it works). What I need is to do this so that the value is the value that's on the page. If I could draw it as I write the page itself, that'd be fine, too. Here's my attempt at that:
####################################################################################
# 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 doesn't throw an error or anything, but it doesn't seem to actually draw anything, either.
Thanks for the help!
Here's another idea...
Perhaps it would work to use specific flowables that can be identified to update the course. You can add custom attributes to flowables if necessary to help identify them (see this post).
For example, you might be able to 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 set up some variables:
course_list = [...]
course_iter = iter(course_list)
current_course = next(course_iter)
Then you can check each flowable after it is rendered to see if it has that attribute and update 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 right course, since both HeaderOverview
and afterFlowable
are called at various points during the final build.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With