我使用Python包ReportLab来创建PDF报告。
使用用户指南,reportlab网站和论坛中提供的示例,我设法通过可点击链接获得动态目录,但页码不会出现 (在目录中)。
如果有人能够指出我在下面的代码中遗漏了什么,那就太棒了:
from reportlab.platypus import Paragraph, Spacer, Image, PageBreak, KeepTogether
from reportlab.platypus.doctemplate import BaseDocTemplate, PageTemplate, NextPageTemplate
from reportlab.platypus.tableofcontents import TableOfContents
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, inch
from reportlab.rl_config import defaultPageSize
from reportlab.platypus.frames import Frame
from reportlab.pdfgen.textobject import PDFTextObject
from reportlab.pdfgen import canvas
from datetime import datetime
import os
styles = getSampleStyleSheet()
PAGE_HEIGHT=defaultPageSize[1]
PAGE_WIDTH=defaultPageSize[0]
filename = 'report_template.pdf'
model_type = 'Cygnus'
identifier = 'X1'
date = datetime.now().strftime('%d-%b-%y')
class MyDocTemplate(BaseDocTemplate):
def __init__(self, filename, **kw):
self.allowSplitting = 0
BaseDocTemplate.__init__(self, filename, **kw)
self.pagesize = defaultPageSize
def afterFlowable(self, flowable):
"Registers TOC entries."
if flowable.__class__.__name__ == 'Paragraph':
text = flowable.getPlainText()
style = flowable.style.name
if style == 'Heading1':
level = 0
elif style == 'Heading2':
level = 1
else:
return
E = [level, text, self.page]
#if we have a bookmark name, append that to our notify data
bn = getattr(flowable,'_bookmarkName',None)
if bn is not None: E.append(bn)
self.notify('TOCEntry', tuple(E))
def report_gen(Test):
def titlePage(canvas, doc):
canvas.saveState()
canvas.setFont('Times-Bold', 22)
canvas.drawCentredString(PAGE_WIDTH/2, PAGE_HEIGHT/2 + 4*12, "Model Test Report")
canvas.setFont('Times-Bold', 20)
canvas.drawCentredString(PAGE_WIDTH/2, PAGE_HEIGHT/2 - 6*12, model_type)
canvas.setFont('Times-Roman', 16)
canvas.drawCentredString(PAGE_WIDTH/2, PAGE_HEIGHT/2 - 10*12, date)
canvas.restoreState()
def contentPage(canvas, doc):
canvas.saveState()
canvas.setFont('Times-Roman', 12)
canvas.drawString(inch, 0.75*inch, "Page %d | %s %s %s" %(doc.page, model_type, identifier, date))
canvas.restoreState()
def doHeading(text,sty):
from hashlib import sha1
#create bookmarkname
bn=sha1(text+sty.name).hexdigest()
#modify paragraph text to include an anchor point with name bn
h=Paragraph(text+'<a name="%s"/>' % bn,sty)
#store the bookmark name on the flowable so afterFlowable can see this
h._bookmarkName=bn
Story.append(h)
#***Document Structures***#
doc = MyDocTemplate(filename)
frameT = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='normal')
doc.addPageTemplates([PageTemplate(id='TitlePage', frames=frameT, onPage=titlePage), PageTemplate(id='ContentPage', frames=frameT, onPage=contentPage)])
Story = []
toc = TableOfContents()
PS = ParagraphStyle
centered = PS(name = 'centered',
fontSize = 20,
leading = 16,
alignment = 1,
spaceAfter = 20)
h1 = PS(
name = 'Heading1',
fontSize = 14,
leading = 16)
h2 = PS(name = 'Heading2',
fontSize = 12,
leading = 14)
#*************************#
#***Title Page***#
logo = "logo.png"
im1 = Image(logo, 112.5, 32.5)
im1.hAlign = 'RIGHT'
Story.append(im1)
Story.append(NextPageTemplate('ContentPage'))
Story.append(PageBreak())
#***Table of Contents***#
Story.append(Paragraph('<b>Table of Contents</b>', centered))
toc.levelStyles = [
PS(fontName='Times-Bold', fontSize=14, name='TOCHeading1',
leftIndent=20, firstLineIndent=-20, spaceBefore=5, leading=16),
PS(fontSize=12, name='TOCHeading2',
leftIndent=40, firstLineIndent=-20, spaceBefore=0, leading=12),
PS(fontSize=10, name='TOCHeading3',
leftIndent=60, firstLineIndent=-20, spaceBefore=0, leading=12),
PS(fontSize=10, name='TOCHeading4',
leftIndent=100, firstLineIndent=-20, spaceBefore=0, leading=12),
]
Story.append(toc)
Story.append(PageBreak())
#***Content Pages***#
doHeading('First heading', h1)
Story.append(Paragraph('Text in first heading', PS('body')))
Story.append(Spacer(1,12))
doHeading('First sub heading', h2)
Story.append(Paragraph('Text in first sub heading', PS('body')))
Story.append(PageBreak())
doHeading('Second sub heading', h2)
Story.append(Paragraph('Text in second sub heading', PS('body')))
Story.append(PageBreak())
doHeading('Last heading', h1)
Story.append(Paragraph('Text in last heading', PS('body')))
doc.multiBuild(Story)
report_gen()
os.system(filename)
提前致谢!