使用 ReportLab 将页码和总页数正确添加到 PDF
Properly add page numbers and total number of pages to PDF using ReportLab
我正在尝试创建页码格式为 "Page x of y" 的文档。
我已经尝试过 NumberedCanvas 方法 (http://code.activestate.com/recipes/576832/ and also from the forums https://groups.google.com/forum/#!topic/reportlab-users/9RJWbrgrklI) but that conflicts with my clickable Table of Contents (https://www.reportlab.com/snippets/13/)。
我从这个 post http://two.pairlist.net/pipermail/reportlab-users/2002-May/000020.html 中了解到,使用表格可能是可能的,但是这方面的例子非常稀少且缺乏信息。
有人知道如何使用表单(或修复 NumberedCanvas 方法吗?)
所以我最终渲染了两次文档。需要多花几秒钟,但效果很好!
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,因为报告实验室在第一次构建期间向它们添加了一些属性,这将导致第二次构建出错。
我有点担心 canvas 对象在某些时候可能会在构建后被销毁或重置,所以如果将来有人想使用它,请小心。
此页面 (http://www.blog.pythonlibrary.org/2013/08/12/reportlab-how-to-add-page-numbers/) 解释了一个很好的方法。我做了一些更改以更好地利用继承。
它创建了一个继承自 ReportLab Canvas class 的新 Class。
这是我修改后的代码:
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
更改为 NumberedCanvas
。保存文件后,将添加数字。
我正在尝试创建页码格式为 "Page x of y" 的文档。 我已经尝试过 NumberedCanvas 方法 (http://code.activestate.com/recipes/576832/ and also from the forums https://groups.google.com/forum/#!topic/reportlab-users/9RJWbrgrklI) but that conflicts with my clickable Table of Contents (https://www.reportlab.com/snippets/13/)。
我从这个 post http://two.pairlist.net/pipermail/reportlab-users/2002-May/000020.html 中了解到,使用表格可能是可能的,但是这方面的例子非常稀少且缺乏信息。 有人知道如何使用表单(或修复 NumberedCanvas 方法吗?)
所以我最终渲染了两次文档。需要多花几秒钟,但效果很好!
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,因为报告实验室在第一次构建期间向它们添加了一些属性,这将导致第二次构建出错。
我有点担心 canvas 对象在某些时候可能会在构建后被销毁或重置,所以如果将来有人想使用它,请小心。
此页面 (http://www.blog.pythonlibrary.org/2013/08/12/reportlab-how-to-add-page-numbers/) 解释了一个很好的方法。我做了一些更改以更好地利用继承。
它创建了一个继承自 ReportLab Canvas class 的新 Class。
这是我修改后的代码:
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
更改为 NumberedCanvas
。保存文件后,将添加数字。