LayoutError in ReportLab

Attempting To: Generate a PDF file listing a few attributes of various systems. Each set of system information needs to stay together as a block of info on the page; having some on one page, and the remainder on the following page is unacceptable.

Established Method: Employ the “KeepTogether” flowable. Pass a list of things (here, Paragraph objects) to it, and it’s supposed to handle things properly. If the length of the content passed exceeds that of the page, it will auto-magically insert a page break, and place the content on the next page.

Problem: ReportLab throws “LayoutError: Splitting error” on one of the KeepTogether flowable objects. Further, this particular exception seems impossible to handle; wrapping the calls in “try” and “except” clauses appears to have no effect whatsoever, and the error is raised without fail.

Investigation, conclusion & code examples follow…

Bumbling Investigation:
1. Remove the KeepTogether, and simply add Paragraphs: Works fine, but splits text blocks across pages. Unacceptable.

2. Re-insert KeepTogether, but use ReportLab Markup to condense last 2 Paragraph objects into 1 via ‘<br />’ tag. Works fine, but no whitespace between text blocks, due to “ParagraphStyle” named “body” having “spaceAfter=0”. Unacceptable.

3. KeepTogether, but change ParagraphStyle call of 2-line Paragraph to use “body_space_after” which has “spaceAfter=9”. Same error returns. Fuck.

4. KeepTogether, but change ParagraphStyle attributes for “head” to use “spaceBefore=9”, and use only “body” with “spaceAfter=0”. Success.

5. KeepTogether, use “head” with “spaceBefore=9”, and split the previously-condensed, 2-line Paragraph into 2 separate “body” Paragraphs. Success again.

Conclusion: Changing the attributes of ParagraphStyle(s) in the document’s style sheet may help circumvent this nefarious error. I can’t guarantee it, but it worked for me.

Broke-Dick Code (relevant pieces only):

from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.platypus.flowables import KeepTogether
from reportlab.lib.styles import StyleSheet1, ParagraphStyle

def getReportStyleSheet():
    s = StyleSheet1()
    s.add(  ParagraphStyle( name='head',
            fontSize=7, leading=8.2,
            fontName='Helvetica-Bold',
            spaceAfter=0 )  )
    s.add(  ParagraphStyle( name='body',
            fontSize=7, leading=8.2,
            fontName='Helvetica',
            spaceAfter=0 )  )
    s.add(  ParagraphStyle( name='body_space_after',
            fontSize=7, leading=8.2,
            fontName='Helvetica',
            spaceAfter=9 )  )
    return s
styles = getReportStyleSheet()

def generatePDF():
    doc = SimpleDocTemplate( 'filename',
        pagesize=(PAGE_WIDTH, PAGE_HEIGHT),
        leftMargin=MARGIN, rightMargin=MARGIN,
        topMargin=MARGIN, bottomMargin=MARGIN )
    Story = []
    for X in WHATEVER:
        L = []
        L.append(Paragraph('header text', styles['head']))
        L.append(Paragraph('line 1 text', styles['body']))
        L.append(Paragraph('line 2 text', styles['body_space_after']))
        Story.append(KeepTogether(L))
    doc.build(Story)

Working Code (relevant pieces only):

same imports as above

def getReportStyleSheet():
    s = StyleSheet1()
    s.add(  ParagraphStyle( name='head',
            fontSize=7, leading=8.2,
            fontName='Helvetica-Bold',
            spaceBefore=9 )  )
    s.add(  ParagraphStyle( name='body',
            fontSize=7, leading=8.2,
            fontName='Helvetica',
            spaceAfter=0 )  )
    return s
styles = getReportStyleSheet()

def generatePDF():
    doc = SimpleDocTemplate( 'filename',
        pagesize=(PAGE_WIDTH, PAGE_HEIGHT),
        leftMargin=MARGIN, rightMargin=MARGIN,
        topMargin=MARGIN, bottomMargin=MARGIN )
    Story = []
    for X in WHATEVER:
        L = []
        L.append(Paragraph('header text', styles['head']))
        L.append(Paragraph('line 1 text', styles['body']))
        L.append(Paragraph('line 2 text', styles['body']))
        Story.append(KeepTogether(L))
    doc.build(Story)
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s