Reportlab:带有页面数据的页眉
我正在使用页面功能和页面模板,为文档中的一部分页面制作标题:
templates.append(PageTemplate(id='Overview', frames=frame, onPage=HeaderOverview))
这个模板的标题功能:
################################
# 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()
这个方法很好用,除了一个问题,就是传入的课程变量(在这个部分的每个页面上都会变化)总是最后一个,因为这个函数实际上是在最终构建时才被调用的(我觉得是这样的)。我需要的是让这个值能够对应到当前页面上的值。如果我能在写页面的时候就能绘制出来,那也可以。以下是我尝试的:
####################################################################################
# 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"]))
这个方法没有报错,但似乎也没有实际绘制出任何东西。
谢谢你的帮助!
1 个回答
7
这里有另一个想法...
也许可以使用一些特定的可流动元素(flowables),这样就能识别它们来更新课程。如果需要的话,你可以给这些可流动元素添加自定义属性,以帮助识别它们(可以参考这篇帖子)。
举个例子,你可能可以这样做:
...
report.append(some_content)
report.append(PageBreak())
report[-1].new_course = True # gives that PageBreak flowable a custom attribute
report.append(some_more_content)
...
然后设置一些变量:
course_list = [...]
course_iter = iter(course_list)
current_course = next(course_iter)
接着,你可以在每个可流动元素渲染后检查它们,看看是否有那个属性,如果有的话就更新当前的课程。
def afterFlowable(flowable):
global current_course
if hasattr(flowable, 'new_course'):
current_course = next(course_iter)
doc.afterFlowable = afterFlowable
HeaderOverview
可以使用 current_course
变量来获取正确的课程,因为 HeaderOverview
和 afterFlowable
在最终构建的不同阶段都会被调用。