【问题标题】:ReportLab: LayoutError when content of cell too long for a pageReportLab:当单元格内容对于页面而言太长时出现 LayoutError
【发布时间】:2016-04-10 17:42:50
【问题描述】:

我正在尝试创建一个包含 7 个列的表。最后一列包含一个似乎造成错误的长文本。似乎当单元格超过页面大小时,它会抛出异常。

from reportlab.lib.pagesizes import landscape, A4
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import SimpleDocTemplate, LongTable, TableStyle, Paragraph
from reportlab.lib import colors
from reportlab.lib.units import mm
from datetime import date

doc = SimpleDocTemplate(response, pagesize=A4, rightMargin=30,leftMargin=30, topMargin=30,bottomMargin=18)
doc.pagesize = landscape(A4)
elements = []

styles = getSampleStyleSheet()
cell_style = styles['BodyText']
cell_style.wordWrap = 1
cell_style.fontName = 'Courier'
cell_style.spaceBefore = 30
cell_style.spaceAfter = 30

title_style = styles['Title']
title_style.fontName = 'Courier'
title = Paragraph('Export Issue Tracker (%s)' % (date.today().isoformat()), title_style)
elements.append(title)

data2 = [[Paragraph(cell, cell_style) for cell in row] for row in data]
table = LongTable(data2, colWidths=(None, None, None, None, None, None, 50*mm))
table_style = TableStyle([('BOX', (0,0), (-1,-1), 0.25, colors.black),
                            ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
                            ('FONTNAME',(0,0),(-1,-1),'Courier'),
                            ('VALIGN',(0,0),(-1,-1),'TOP'),
                            ('ALIGN',(0,0),(-1,0),'CENTER'),
                            ('TEXTCOLOR',(0,0),(-1,0), colors.yellow),
                            ('BACKGROUND', (0,0), (-1,0), colors.gray),
                            ('FONTSIZE',(0,0),(-1,-1),50)] + color_style)
table.setStyle(table_style)
elements.append(table)

doc.build(elements)

但是我收到以下错误:

LayoutError at /issues/export_comments/
Flowable <LongTable@0x7F5AFBBB6560 35 rows x 7 cols(tallest row 2694)> with cell(0,0) containing
u'<Paragraph at 0x7f5afbcb7ef0>9'(769.88976378 x 4782), tallest cell 2694.0 points,  too large on page 2 in frame 'normal'(769.88976378 x 535.275590551*) of template 'Later'

我看过很多关于如何使用 KeepTogether、Spacer、LongTable 的帖子,但没有一个适合我。

【问题讨论】:

  • 这样最后一列大约 2 英寸宽,采用横向格式。您的错误是告诉您该单元格是 42 英寸高......在 8.5 英寸高的页面上(在您考虑边框之前) !)。我觉得您需要拆分该文本。
  • @mauve 是的,但是有没有办法将文本扩展到下一页而不拆分文本?就像普通桌子一样。
  • 谁能提供带有示例数据的最低工作示例代码。

标签: python pdf reportlab


【解决方案1】:

这个问题通常通过将内容格式化为可流动的段落(具有定义的段落样式)来解决,否则文本不知道它是否应该换行。很多时候,它与表格中的格式对文本的作用存在冲突。上面的问题是 RL 抛出一个错误,因为它没有被告知如何处理溢出文本。 cmets 中提到的收缩、KeepTogether 的解决方法不适用于无格式文本,您首先需要将其转换为段落。

根据我的经验,使用表格样式处理除段落之外的所有内容的规则是最容易的。

下面是一个通用的解决方案。去年年底,我看到 @sagar-gupta 正在寻找这个老问题的答案。

from reportlab.lib.pagesizes import letter, A4, landscape
from reportlab.lib.enums import TA_JUSTIFY, TA_LEFT, TA_CENTER, TA_RIGHT
from reportlab.lib.styles import ParagraphStyle, StyleSheet1
from reportlab.lib import colors
from reportlab.platypus import Frame, PageTemplate, KeepInFrame, Paragraph
from reportlab.lib.units import cm
from reportlab.platypus import (Table, TableStyle, BaseDocTemplate)

########################################################################

def create_pdf():
    """
    Create a pdf
    """

    # Create a frame
    text_frame = Frame(
        x1=3.00 * cm,  # From left
        y1=1.5 * cm,  # From bottom
        height=19.60 * cm,
        width=15.90 * cm,
        leftPadding=0 * cm,
        bottomPadding=0 * cm,
        rightPadding=0 * cm,
        topPadding=0 * cm,
        showBoundary=1,
        id='text_frame')

    styles = StyleSheet1()
    styles.add(ParagraphStyle(name='Breadpointlist_style',
                              alignment=TA_LEFT,
                              bulletFontSize=7,
                              bulletIndent=0,
                              endDots=None,
                              firstLineIndent=0,
                              fontSize=8,
                              justifyBreaks=0,
                              justifyLastLine=0,
                              leading=9.2,
                              leftIndent=11,
                              rightIndent=0,
                              spaceAfter=0,
                              spaceBefore=0,
                              textColor=colors.black,
                              wordWrap='LTR',
                              splitLongWords=True,
                              spaceShrinkage=0.05,
                              ))

    bps = ParagraphStyle('bps', parent=styles['Breadpointlist_style'])

    # Create a table
    test_table = []
    data = []
    for i in range(11, 1, -1):
        column1data = Paragraph('Column_1 on row {i}', bps)
        column2data = Paragraph('Column_last on row {i}', bps)
        data.append(['1','1','1','1','1',column1data, column2data])

    data_table = Table(data, 15.90 * cm / 7)
    data_table.setStyle(TableStyle([

        ('ALIGN', (0, 0), (1, -1), 'RIGHT'),
        ('SIZE', (0, 0), (-1, -1), 7),
        ('LEADING', (0, 0), (-1, -1), 8.4),
        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
        ('TOPPADDING', (0, 0), (-1, -1), 2.6),
        ('BOTTOMPADDING', (0, 0), (-1, -1), 2.6),
        ('LINEBELOW', (0, 0), (-1, -1), 0.3, colors.gray),
    ]))

    test_table.append(data_table)
    test_table = KeepInFrame(0, 0, test_table, mode='shrink')

    # Building the story
    story = [test_table] # adding test_table table (alternative, story.add(test_table))

    # Establish a document
    doc = BaseDocTemplate("Example_output.pdf", pagesize=letter)

    # Creating a page template
    frontpage = PageTemplate(id='FrontPage',
                             frames=[text_frame]
                             )
    # Adding the story to the template and template to the document
    doc.addPageTemplates(frontpage)

    # Building doc
    doc.build(story)


# ----------------------------------------------------------------------
if __name__ == "__main__":
    create_pdf() # Printing the pdf

【讨论】:

    猜你喜欢
    • 2010-12-22
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 2014-11-30
    • 1970-01-01
    • 2011-01-25
    相关资源
    最近更新 更多