有人可以使用reportlab生成带有页眉(添加图像),页脚(Y的第X页)和带有书签的目录的PDF报告吗?

时间:2018-11-26 07:00:51

标签: python pdf reportlab

我可以生成带有页眉和页脚的PDF,也可以生成带有目录的PDF,但是我不能生成带有页眉(图像),页脚(y的x页)和带有书签的目录的pdf,我花了几天的时间将这三个功能结合在一起,但是失败了,谁能给我一些建议?我的代码有什么问题,pdf的目录未显示,并说“目录0的占位符”

class MyDocTemplate(BaseDocTemplate):
    def __init__(self, filename, **kw):
        self.allowSplitting = 0
        BaseDocTemplate.__init__(self, filename, **kw)
        template = PageTemplate('normal', [Frame(2.5*cm, 2.5*cm, 15*cm, 25*cm)])
        self.addPageTemplates(template)

def afterFlowable(self, flowable):
    if isinstance(flowable, Paragraph):
        txt = flowable.getPlainText()
        style = flowable.style.name
        if style == 'Heading1':
            key = 'h1-%s' % self.seq.nextf('heading1')
            self.canv.bookmarkPage(key)
            self.notify('TOCEntry', (0, txt, self.page))
        elif style == 'Heading2':
            key = 'h2-%s' % self.seq.nextf('heading2')
            print (key)
            self.canv.bookmarkPage(key)
            self.notify('TOCEntry', (1, txt, self.page, key))

class NumberedCanvas(canvas.Canvas):
    def __init__(self, *args, **kwargs):
        canvas.Canvas.__init__(self, *args, **kwargs)
        self._saved_page_states = []

    def showPage(self):
        self._saved_page_states.append(dict(self.__dict__))
        self._startPage()

    def save(self):
        """add page info to each page (page x of y)"""
        num_pages = len(self._saved_page_states)
        for state in self._saved_page_states:
            self.__dict__.update(state)
            self.draw_page_number(num_pages)
            canvas.Canvas.showPage(self)
        canvas.Canvas.save(self)

    def draw_page_number(self, page_count):
        self.setFont('Times-Bold',14)
        self.drawRightString(7.6*inch,.5*inch,
        "Page %d of %d" % (self._pageNumber, page_count))

if __name__ == "__main__":

    h1 = PS(name = 'Heading1',
    fontSize = 14,
    leading = 16)
    h2 = PS(name = 'Heading2',
    fontSize = 12,
    leading = 14,
    leftIndent = 25)

    #Build story.
    story = []
    toc = TableOfContents()

    #For conciseness, using the same styles for headings and TOC entries
    toc.levelStyles = [h1, h2]
    story.append(toc)
    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(Paragraph('Last heading', h1))
    doc = MyDocTemplate("mypdf.pdf")
    doc.multiBuild(story, canvasmaker=NumberedCanvas)

1 个答案:

答案 0 :(得分:0)

检查代码缩进。 afterFlowable方法应在class MyDocTemplate内定义:

class MyDocTemplate(BaseDocTemplate):
    def __init__(self, filename, **kw):
        self.allowSplitting = 0
        BaseDocTemplate.__init__(self, filename, **kw)
        template = PageTemplate('normal', [Frame(2.5*cm, 2.5*cm, 15*cm, 25*cm)])
        self.addPageTemplates(template)

    def afterFlowable(self, flowable):
        if isinstance(flowable, Paragraph):
            txt = flowable.getPlainText()
            style = flowable.style.name
            ...