Reportlab Platypus FrameBreak 导致每项元素独占一页的问题及解决方案

69 阅读2分钟

在使用 Reportlab 生成一个四页的 PDF 文档时,针对第二页的元素生成出现了问题。使用 FrameBreaks 后,该方法中的每个元素都会生成一个新的页面。除了完全从代码中删除 FrameBreaks 以外,其他元素都会独占一个页面。

2、解决方案 检查代码并注意以下几点:

  • 确保 PageTemplate 中的 frames 配置正确,并且每个元素都被包含在至少一个 Frame 中。
  • 检查是否使用了 NextPageTemplate 或 PageBreak 元素,它们可能导致页面中断。
  • 确保 Frame 的 leftPadding、rightPadding、topPadding 和 bottomPadding 属性的值都为零,这可以防止出现不必要的边距。
  • 尝试使用不同的 Frame 类型,例如 FlowFrame 或 TableFrame,并了解它们是否适合您的用例。

以下是如何解决第二页元素独占一页问题的代码示例:

def page_two():
    yld_header_height = 0.71 * inch
    f_yld_header = FlowFrame(doc.leftMargin, height - doc.topMargin - yld_header_height,
                            doc.width, yld_header_height,
                            leftPadding=0, rightPadding=0,
                            topPadding=0, bottomPadding=0,
                            id='yld_header')

    yld_text_height = 3.59 * inch
    yld_text_width = 1.75 * inch
    f_yld_text = FlowFrame(doc.leftMargin, height - doc.topMargin - yld_header_height - yld_text_height,
                        yld_text_width, yld_text_height,
                        leftPadding=0, rightPadding=0,
                        topPadding=0, bottomPadding=0,
                        id='yld_text')

    yld_graph_height = yld_text_height
    yld_graph_width = 4.95 * inch
    f_yld_graph = FlowFrame(doc.leftMargin + yld_text_width - 0 * inch,
                            height - doc.topMargin - yld_header_height - yld_text_height,
                            doc.width - yld_text_width, yld_graph_height,
                            leftPadding=0, rightPadding=0,
                            topPadding=0, bottomPadding=0,
                            id='yld_graph')

    dash_buffer = 20

    daly_header_height = 1.0 * inch
    daly_cap_height = 4.15 * inch
    f_daly_header = FlowFrame(doc.leftMargin,
                            doc.bottomMargin + footer_height + daly_cap_height,
                            doc.width, daly_header_height,
                            leftPadding=0, rightPadding=0,
                            topPadding=0, bottomPadding=0,
                            id='daly_header')

    daly_graph_width = 5.8 * inch
    daly_cap_width = yld_text_width
    f_daly_cap = FlowFrame(doc.leftMargin,
                        doc.bottomMargin + footer_height,
                        daly_cap_width, daly_cap_height,
                        leftPadding=0, rightPadding=0,
                        topPadding=0, bottomPadding=0,
                        id='daly_cap')

    f_daly_title = FlowFrame(width - doc.rightMargin - daly_graph_width + 0.2 * inch,
                            doc.bottomMargin + footer_height + 7,
                            daly_graph_width, daly_cap_height,
                            leftPadding=0, rightPadding=0,
                            topPadding=0, bottomPadding=0,
                            id='daly_title')

    f_daly_graph = FlowFrame(width - doc.rightMargin - daly_graph_width,
                            doc.bottomMargin + footer_height,
                            daly_graph_width, daly_cap_height,
                            leftPadding=0, rightPadding=0,
                            topPadding=0, bottomPadding=0,
                            id='daly_graph')

    post_header_space = 3
    elements.append(Paragraph("TITLE)"
                              , styles['body_heading']))
    elements.append(Spacer(1, post_header_space))
    yld_para = "description"
    elements.append(Paragraph(yld_para
                              , styles['body_text']))

    elements.append(Spacer(1, 40))
    elements.append(Paragraph("Lorem Ipsum", styles['justified']))

    elements.append(Paragraph("Sub description"
                              , styles['fig_cap']))
    elements.append(Paragraph("DISABILITY-ADJUSTED LIFE YEARS (DALYs)"
                              , styles['body_heading']))
    elements.append(Spacer(1, post_header_space))
    daly_para = "another paragraph"
    elements.append(Paragraph(daly_para
                              , styles['body_text']))
    elements.append(Spacer(1, 10))
    elements.append(Paragraph("Yet another paragraph",
                              styles['justified']))
    elements.append(Paragraph("Another sub paragraph", styles['fig_cap']))
    elements.append(NextPageTemplate('ThirdPage'))
    elements.append(PageBreak())
    doc.addPageTemplates(PageTemplate(id='SecondPage', frames=[f_yld_header, f_yld_text, f_yld_graph, f_daly_header, f_daly_cap, f_daly_title, f_daly_graph], onPageEnd=foot_dash_2))

在示例代码中,使用了 FlowFrame 代替了 Frame,并确保了所有元素都包含在一个 Frame 中。此外,还使用了 NextPageTemplate 和 PageBreak 来手动控制页面中断。通过这些修改,第二页的元素将正常生成,并且不会出现独占一页的情况。