Python ReportLab生成PDF目录时动态设置页码的问题
Python 3.10 + ReportLab 3.6.10 生成带动态页码与跳转目录的PDF实现
需求:使用Python 3.10结合ReportLab 3.6.10的SimpleDocTemplate生成包含目录的PDF,要求页码支持动态设置,现有示例大多不具备该功能。以下是已完成的实现代码,目录已支持文档内跳转超链接:
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.platypus import SimpleDocTemplate, Paragraph, Flowable, PageBreak, Spacer, Table 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">↑</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">↑</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">↑</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">↑</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()
内容的提问来源于stack exchange,提问作者cornhenge
相关产品推荐
相关产品推荐

