Code snippets are bits of re-usable code submitted by the ReportLab community. We don't promise that they are accurate, up-to-date or correct - use them at your own risk!
We'd love it if you could participate by submitting your own snippets and sharing your experience with others by commenting. You will need to create a user account by filling out our very simple form.
View all snippets
Table of contents
A table of contents can be easily generated by using the TableOfContents flowable. Details can be found in the User Guide in section 9.8. This method requires the multiBuild method. We will post a "single pass" example soon.
from reportlab.lib.styles import ParagraphStyle as PS from reportlab.platypus import PageBreak from reportlab.platypus.paragraph import Paragraph from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate from reportlab.platypus.tableofcontents import TableOfContents from reportlab.platypus.frames import Frame from reportlab.lib.units import cm class MyDocTemplate(BaseDocTemplate): def __init__(self, filename, **kw): self.allowSplitting = 0 apply(BaseDocTemplate.__init__, (self, filename), kw) template = PageTemplate('normal', [Frame(2.5*cm, 2.5*cm, 15*cm, 25*cm, id='F1')]) self.addPageTemplates(template) # Entries to the table of contents can be done either manually by # calling the addEntry method on the TableOfContents object or automatically # by sending a 'TOCEntry' notification in the afterFlowable method of # the DocTemplate you are using. The data to be passed to notify is a list # of three or four items countaining a level number, the entry text, the page # number and an optional destination key which the entry should point to. # This list will usually be created in a document template's method like # afterFlowable(), making notification calls using the notify() method # with appropriate data. def afterFlowable(self, flowable): "Registers TOC entries." if flowable.__class__.__name__ == 'Paragraph': text = flowable.getPlainText() style = flowable.style.name if style == 'Heading1': self.notify('TOCEntry', (0, text, self.page)) if style == 'Heading2': self.notify('TOCEntry', (1, text, self.page)) centered = PS(name = 'centered', fontSize = 30, leading = 16, alignment = 1, spaceAfter = 20) h1 = PS( name = 'Heading1', fontSize = 14, leading = 16) h2 = PS(name = 'Heading2', fontSize = 12, leading = 14) # Build story. story = [] # Create an instance of TableOfContents. Override the level styles (optional) # and add the object to the story toc = TableOfContents() toc.levelStyles = [ PS(fontName='Times-Bold', fontSize=20, name='TOCHeading1', leftIndent=20, firstLineIndent=-20, spaceBefore=10, leading=16), PS(fontSize=18, name='TOCHeading2', leftIndent=40, firstLineIndent=-20, spaceBefore=5, leading=12), ] story.append(toc) story.append(Paragraph('<b>Table of contents</b>', centered)) story.append(PageBreak()) story.append(Paragraph('First heading', h1)) story.append(Paragraph('Text in first heading', PS('body'))) story.append(Paragraph('First sub heading', h2)) story.append(Paragraph('Text in first sub heading', PS('body'))) story.append(PageBreak()) story.append(Paragraph('Second sub heading', h2)) story.append(Paragraph('Text in second sub heading', PS('body'))) story.append(PageBreak()) story.append(Paragraph('Last heading', h1)) doc = MyDocTemplate('mintoc.pdf') doc.multiBuild(story)