拆分ReportLab Flowable

时间:2016-05-03 13:05:36

标签: python reportlab

我试图为ReportLab写一个Flowable,它需要能够拆分。基于我对文档的理解,我需要定义一个函数split(self, aW, aH),它将可流动的内容分开。但是,我收到以下错误,我无法解决。

一个简单的Flowable:

class MPGrid (Flowable):
def __init__(self, height=1*cm, width=None):
    self.height = height
    self.width = None

def wrap(self, aW, aH):
    self.width = aW
    return (aW, self.height)

def split(self, aW, aH):
    if aH >= self.height:
        return [self]
    else:
        return [MPGrid(aH, aW), MPGrid(self.height - aH, None)]

def draw(self):
    if not self.width:
        from reportlab.platypus.doctemplate import LayoutError
        raise LayoutError('No Width Defined')

    c = self.canv
    c.saveState()
    c.rect(0, 0, self.width, self.height)
    c.restoreState()

在文档中使用并需要拆分时,会产生以下错误:

reportlab.platypus.doctemplate.LayoutError: Splitting error(n==2) on page 4 in
<MPGrid at 0x102051c68 frame=col1>...
S[0]=<MPGrid at 0x102043ef0 frame=col1>...

这个可流动的应该是一个固定的高度,如果它对于可用的高度来说太大了,它会被拆分以消耗高度,然后在下一帧中提醒固定高度。

我做错了导致这个不那么有用的错误?

1 个答案:

答案 0 :(得分:0)

经过相当多的测试,我得到了一个答案。如果有人有解决方案,我仍然愿意接受更好的解决方案。

这种情况正在发生,因为分割被调用两次,第二次是在可用高度为零(或接近零)时,您尝试创建一个具有(接近)零高度的可流动状态。解决方案是检查这种情况,在这种情况下无法拆分。

以下修订后的代码还有一些其他细微的变化,以使代码更多&#34;完成&#34;。

class MPGrid (Flowable):
def __init__(self, height=None, width=None):
    self.height = height
    self.width = width

def wrap(self, aW, aH):
    if not self.width:  self.width = aW
    if not self.height: self.height = aH

    return (self.width, self.height)

def split(self, aW, aH):
    if aH >= self.height:
        return [self]
    else:
        # if not aH == 0.0: (https://www.python.org/dev/peps/pep-0485)
        if not abs(aH - 0.0) <= max(1e-09 * max(abs(aH), abs(0.0)), 0.0):
            return [MPGrid(aH), MPGrid(self.height - aH, None)]
        else:
            return []   # Flowable Not Splittable

def draw(self):
    if not self.width or not self.height:
        from reportlab.platypus.doctemplate import LayoutError
        raise LayoutError('Invalid Dimensions')

    c = self.canv
    c.saveState()
    c.rect(0, 0, self.width, self.height)
    c.restoreState()