6

使用 ReportLab 2.7、Python 2.7:

我可以在目录 (toc) 中创建一个带有可点击书签的 pdf,或者我可以创建一个带有“x of y”页码的 pdf,但是当我尝试同时执行这两种操作时,书签页(键)似乎会中断。

示例代码:

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)]) #, id='F1'
        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))

    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)

任何意见将不胜感激。

4

1 回答 1

0

发现这个最初寻找解决方案无济于事,但是,想出了一些对我有用的东西并希望分享如下:

从 reportlab 示例的起点开始,关于创建包含文档的 toc(我假设您首先使用了该文档),请执行以下操作。

通过添加选项 onPage 和 onPageEnd 来修改 init 函数中的模板分配,这些选项定义了对用于在页面上绘制页眉和页脚的函数的调用,如下所示,猜测您可以只在一个函数中执行相同的操作,但是,我按顺序使用了两个在我的用例中分隔页眉/页脚部分:

template = PageTemplate('normal', [Frame(2.5*cm, 2.5*cm, 15*cm, 25*cm, id='F1')],onPage=header,onPageEnd=footer)

将命名的页眉/页脚函数添加到您的类中,如下所示,并说明了一些用于澄清的选项,包括页脚函数中的页码,以确保问题得到回答:

def header(canvas, doc):
    canvas.saveState()
    canvas.drawImage('some_image.gif', 5,780, width=None,height=None,mask=None)
    canvas.setLineWidth(1)
    canvas.line(5,780,120,780)
    canvas.setFont('Times-Bold',16)
    canvas.drawString(108, 108, 'blah')
    canvas.restoreState()

def footer(canvas, doc):
    canvas.saveState()
    canvas.setFont('Times-Roman',9)
    canvas.drawImage('py.jpg', inch,inch, width=None,height=None,mask=None)
    canvas.drawString(inch, 0.75 * inch, "Page %d " % doc.page)
    canvas.restoreState()   

无论您对添加的“编号画布类”做了什么以及它为什么会中断,我不知道,但由于您提供的代码让我强烈地想起了 reportlab toc 示例,我想您可以从它开始,应用我建议的更改/添加并查看情况如何。

这应该可以解决问题,希望有帮助!

于 2019-01-11T00:01:28.567 回答