[Python] Python ReportLab Table of Contents Page Numbering Problem

Discussão em 'Python' iniciado por Stack, Dezembro 18, 2024.

  1. Stack

    Stack Membro Participativo

    I need to generate a PDF w/Table of Contents in python (v3.10) using reportlab (v3.6.10) (SimpleDocTemplate). The page numbers need to be dynamically set, but the examples I've been able to find do not allow this. Here is what I have so far.

    (The TOC needed hyperlinks to jump within the document - that's working and shared here, since i didn't find an on-line example)

    from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
    from reportlab.platypus import SimpleDocTemplate, Paragraph, Flowable, Paragraph, PageBreak, Spacer, Table
    from reportlab.platypus import PageBreak
    from reportlab.platypus.tableofcontents import TableOfContents
    from reportlab.lib.units import inch

    class DelayedRef(Flowable):
    _ZEROSIZE = True

    def __init__(self, toc, *args):
    self.args = args
    self.toc = toc

    def wrap(self,w,h):
    return 0,0

    def draw(self,*args,**kwd):
    self.toc.addEntry(*self.args)

    def addPageNumber(canvas, doc):
    """
    Add the page number
    """
    page_num = canvas.getPageNumber()
    text = "- %s -" % page_num
    canvas.drawRightString(4.5*inch,0.5*inch, text)

    def simple_toc():
    docFile = 'test.pdf'
    print(docFile)

    ipsum = '''Lorem ipsum dolor sit amet, consectetur adipiscing elit,
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
    nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
    culpa qui officia deserunt mollit anim id est laborum.'''

    doc = SimpleDocTemplate(docFile)
    story = []
    styles = getSampleStyleSheet()

    story.append(Paragraph("The Title", style=styles['Heading1']))
    story.append(Paragraph("Notes:", style=styles['Normal']))
    story.append(Paragraph(ipsum, style=styles['Normal']))

    story.append(PageBreak())
    story.append(Paragraph('<a name="TOC"/>Table of Contents', style=styles['Heading1']))
    toc = TableOfContents()
    toc.levelStyles = [ParagraphStyle(fontName='Helvetica', fontSize=14, name='Heading1',leftIndent=20, firstLineIndent=-20, spaceBefore=5,leading=16),
    ParagraphStyle(fontName='Times-Roman', fontSize=14, name='Heading2',leftIndent=20, firstLineIndent=-20, spaceBefore=5,leading=16)]
    story.append(toc)

    story.append(PageBreak())
    story.append(Paragraph('<a name="Part1"/>1. Part 1 Header <a href="#TOC" color="blue">&#8593;</a>', style=styles['Heading1']))
    story.append(DelayedRef(toc, 0, '<a href="#Part1" color="blue">1. Part 1 Header</a>', 1))
    for x in range(10):
    story.append(Paragraph(ipsum, style=styles['Normal']))

    story.append(PageBreak())
    story.append(Paragraph('<a name="Part2"/>2. Part 2 Header <a href="#TOC" color="blue">&#8593;</a>', style=styles['Heading1']))
    story.append(DelayedRef(toc, 0, '<a href="#Part2" color="blue">2. Part 2 Header</a>', 1))
    story.append(Paragraph(ipsum, style=styles['Normal']))


    story.append(Paragraph('<a name="Part21"/>2.1 Part 2.1 Header <a href="#TOC" color="blue">&#8593;</a>', style=styles['Heading2']))
    story.append(DelayedRef(toc, 1, '<a href="#Part21" color="blue">2.1 Part 2.1 Header</a>', 1))
    for x in range(10):
    story.append(Paragraph(ipsum, style=styles['Normal']))

    story.append(PageBreak())
    story.append(Paragraph('<a name="Part3"/>3. Part 3 Header <a href="#TOC" color="blue">&#8593;</a>', style=styles['Heading1']))
    story.append(DelayedRef(toc, 0, '<a href="#Part3" color="blue">3. Part 3 Header</a>',1))

    doc.multiBuild(story, onFirstPage=addPageNumber, onLaterPages=addPageNumber)

    if __name__ == '__main__':
    simple_toc()

    Continue reading...

Compartilhe esta Página