Reportlab:更改页边距后重新生成文档?

2024-06-16 14:12:26 发布

您现在位置:Python中文网/ 问答频道 /正文

在我为一个朋友的生意写的程序中,我使用reportlab模块为各种报表构建PDF文档。在大多数情况下,报告可以包含在一页上,但在某些罕见的情况下,它可能跨越两页。在这种罕见的情况下,我想做的是重新设置页面的格式,使其具有较小的上下边距,以查看是否可以使其适合单个页面。如果没有,我就用最小的页边距,让它跨过两页。在

为了构建报表,我正在创建SimpleDocTemplate类的实例。在将我所有的流表传递给build方法之后,我发现可以查询page属性来查看它使用了多少页。我试过的第一件事是:

parts = []
path = "/path/to/my/file.pdf"
# ... a bunch of code that appends various flowables to 'parts'
doc = SimpleDocTemplate(path, pagesize=landscape(letter))
doc.build(parts)
# Shrink the margins while it's more than one page and the margins are above zero
while doc.page > 1 and not any([doc.topMargin <= 0, doc.bottomMargin <= 0]):
    # Decrease the page margins and rebuild the page
    doc.topMargin -= inch * .125
    doc.bottomMargin -= inch * .125
    doc.build(parts)
# If the margins are nil and we're still at 2 or more pages, use minimal margins
if doc.page > 1:
    doc.topMargin = inch * .25
    doc.bottomMargin = inch * .25
    doc.build(parts)

我假设在更改页边距后用相同的部分调用build方法将重新计算所有内容。然而,经过多次尝试和错误之后,我了解到传递给build方法的parts列表在构建过程中基本上被剥离干净,留下{}为空列表。一旦再次将其传递回build方法,它就创建了一个没有页面的文档。在

为了解决这个问题,我尝试使用parts列表的副本来构建文档:

^{pr2}$

这导致了一些奇怪的异常,因此我尝试使用copy模块进行深度复制:

doc.build(copy.deepcopy(parts))

这没有引发任何异常,但也没有改变利润率。在

有点绝望,我深入研究了SimpleDocTemplate属性,找到了一个名为_calc的方法。考虑到这可能会重新计算页面,我尝试在更改页边距后调用它。它没有抛出任何异常,但也不起作用。在

我成功做到这一点的唯一方法是使用deepcopy流程,并在每次调整利润时构建全新的文档:

doc = SimpleDocTemplate(path, pagesize=landscape(letter))
doc.build(copy.deepcopy(parts))
# Shrink the margins while it's more than one page and the margins are above zero
while doc.page > 1 and not any([doc.topMargin <= 0, doc.bottomMargin <= 0]):
    doc.topMargin -= inch * .125
    doc.bottomMargin -= inch * .125
    doc = SimpleDocTemplate(path, pagesize=landscape(letter),
                            topMargin = doc.topMargin,
                            bottomMargin = doc.bottomMargin)
    doc.build(copy.deepcopy(parts))
# If the margins are nil and we're still at 2 or more pages, use minimal margins
if doc.page > 1:
    doc.topMargin = inch * .25
    doc.bottomMargin = inch * .25
    doc = SimpleDocTemplate(path, pagesize=landscape(letter),
                            topMargin = doc.topMargin,
                            bottomMargin = doc.bottomMargin)
    doc.build(copy.deepcopy(parts))

然而,走那条路感觉有很多不必要的工作。我宁愿更改文档边距并告诉文档使用这些新值重新构建自己,但我不知道如何进行。有可能吗?在


Tags: andthepath方法文档builddocpage
1条回答
网友
1楼 · 发布于 2024-06-16 14:12:26

一个非常有趣的问题。但是,我相信您已经在ReportLab中找到了正确的方法。构建过程是一次性的,您可以对文档执行此操作,因为它会产生无法返回的副作用。谢天谢地,正如你已经发现的那样,尽管有些烦人,但做你想做的并不难。在

相关问题 更多 >