2

我正在处理发票,我只想在最后一页(也可以是第一页)上添加页脚。

由于表格的数据是动态的,我无法计算页数。

现在我正在使用 2 个页面模板,首页(带有 2 个框架和页脚 1)和下一页(带有 1 个框架和页脚 2)。这在数据填充两页时有效,但当表格仅填充一页或多于 2 页时,它不再有效。

我通过以下方式定义了页脚:

    footerFrame = Frame(x1=35*mm, y1=20*mm, width=175*mm, height=15*mm)
    footerStory = [ Paragraph("Have a nice day.", styles["fancy"]) ]

    def footer2(canvas,document):
        canvas.saveState()
        footerFrame.addFromList(footerStory, canvas)
        canvas.restoreState()

有没有更灵活的方法来定义页脚,所以它只显示在表格结束的页面上?

提前致谢。

4

1 回答 1

3

通过覆盖 ReportLabs 画布类,您可以跟踪页面(当然,我已经使用其他不涉及 flowables 的报告完成了它,但我相信您仍然可以使它工作!)。

由于您使用的是可流动的(段落),因此您需要知道每一代新的 PDF 将有多少页(长度是动态部分)。我不是 100% 肯定的,但我认为 ReportLab 的 flowable 仍然调用画布的“showPage()”方法。因此,您可以执行以下操作:

在伪代码/部分python中,我推荐以下(未经测试):

class MyFooterCanvas(canvas.Canvas):
    def __init__(self, *args, **kwargs):
        ## Subclass the ReportLab canvas class.  
        canvas.Canvas.__init__(self, *args, **kwargs)
        ## Create an empty list to store the saved pages so you can keep track of them.
        self._savedPages = []

    def showPage(self):
        """Override the showPage method"""

        ## We are writing our own showPage() method here, so we can keep track of 
        ## what page we are on.
        self._savedPages.append(self)
        ## Start a new page.
        self._startPage()

    def drawFooter(self):
        """Draws the footer to the page.  You can have it do whatever you want here"""
        self.drawString(50, 50, "This is my footer, yay me - footer freedom")

    def save(self):
        """Saves the entire PDF in one go, a bit costly to do it this way,
           but certainly one way to get a footer."""
        numPages = len(self._savedPages)

        for pages in self._savedPages:
            ## Finds the last page and when it 'hits', it will call the self.drawFooter() method.
            if pages == self._savedPages[-1]:
                self.drawFooter()
            else:
                ## If it's not the last page, explicitly pass over it.  Just being thorough here.
                pass

        ## And... continue doing whatever canvas.Canvas() normally does when it saves.
        canvas.Canvas.save(self)

再次,这是未经测试的,但我认为这会给你你想要的行为。试试看,如果你卡住了,请告诉我,如果需要,我可以解决其中的一些问题,但我已经为其他非流动对象做了同样的方法,过去它对我有用。

于 2013-06-18T15:03:57.217 回答