使用ReportLab

时间:2018-07-24 12:29:08

标签: python pdf reportlab page-numbering tableofcontents

我正在尝试创建一个文档,其页面编号格式为“第x页,共y页”。 我尝试了NumberedCanvas方法(http://code.activestate.com/recipes/576832/,也来自论坛https://groups.google.com/forum/#!topic/reportlab-users/9RJWbrgrklI),但这与我的可点击目录(https://www.reportlab.com/snippets/13/)冲突。

我从这则http://two.pairlist.net/pipermail/reportlab-users/2002-May/000020.html的帖子中了解到,使用表格是可能的,但是关于表格的例子非常少见且没有信息。 是否有人对如何使用表单(或修复NumberedCanvas方法)实现有任何想法?

2 个答案:

答案 0 :(得分:3)

此页面(http://www.blog.pythonlibrary.org/2013/08/12/reportlab-how-to-add-page-numbers/)解释了一种很好的方法。我进行了一些更改以更好地利用继承。

它将创建一个继承自ReportLab Canvas类的新类。

这是我修改的代码:

from reportlab.lib.units import mm
from reportlab.pdfgen.canvas import Canvas


class NumberedPageCanvas(Canvas):
    """
    http://code.activestate.com/recipes/546511-page-x-of-y-with-reportlab/
    http://code.activestate.com/recipes/576832/
    http://www.blog.pythonlibrary.org/2013/08/12/reportlab-how-to-add-page-numbers/
    """

    def __init__(self, *args, **kwargs):
        """Constructor"""
        super().__init__(*args, **kwargs)
        self.pages = []

    def showPage(self):
        """
        On a page break, add information to the list
        """
        self.pages.append(dict(self.__dict__))
        self._startPage()

    def save(self):
        """
        Add the page number to each page (page x of y)
        """
        page_count = len(self.pages)

        for page in self.pages:
            self.__dict__.update(page)
            self.draw_page_number(page_count)
            super().showPage()

        super().save()

    def draw_page_number(self, page_count):
        """
        Add the page number
        """
        page = "Page %s of %s" % (self._pageNumber, page_count)
        self.setFont("Helvetica", 9)
        self.drawRightString(179 * mm, -280 * mm, page)

要使用它,只需在创建新文件时将Canvas的{​​{1}}更改为NumberedCanvas。保存文件后,将添加数字。

答案 1 :(得分:0)

所以我最终两次渲染了文档。再花几秒钟,但效果很好!

class MyDocTemplate(BaseDocTemplate):
    def generate(self, story):
        self.multiBuild(story[:])
        # Decrease by one because canvas is at the page after the last
        self.page_count = self.canv.getPageNumber() - 1
        self.multiBuild(story[:])


class MyPageTemplate(PageTemplate):
    def onPage(self, canvas, doc):
        if getattr(doc, 'page_count', None) is not None:
            canvas.drawString(x, y, canvas.getPageNumber(), doc.page_count)

不是100%满意,但有时您会尽力而为!

请确保不要将相同的对象传递给第一个和第二个multiBuild,因为报表实验室在第一次构建时会向它们添加一些属性,这会在第二次构建中导致错误。

我有点担心在构建后某个时刻画布对象可能会被破坏或重置,因此,如果将来有任何人想要使用它,请当心。