为了账号安全,请及时绑定邮箱和手机立即绑定

reportlab SimpleDocTemplate - 使用可变行数设置表格的固定高度

reportlab SimpleDocTemplate - 使用可变行数设置表格的固定高度

慕娘9325324 2021-11-16 15:21:24
我尝试Python使用reportlab.发票只有一页,而且单页上的空间永远不会有更多的细节;我的代码在生成 PDF 之前检查最大详细信息数。现在我正在使用SimpleDocTemplate将所有内容添加到页面,并使用Table. 这是一个简化的代码示例:from reportlab.lib.units import mmfrom reportlab.platypus import Paragraph, Spacer, Table, TableStylefrom reportlab.platypus import SimpleDocTemplate# add invoice headerflowable_list = [    Spacer(1, 5*mm),    Paragraph('Date: ...', pg_style_1),    Spacer(1, 5*mm),]# add invoice detailsdetail_list = [    ('Item 1', 8, 45),    ('Item 2', 1, 14),]row_list = [    [        Paragraph(desc, pg_style_1),        quantity,        amount,    ]    for desc, quantity, amount in detail_list]story.append(    Table(        data=row_list,        colWidths=[100*mm, 40*mm, 40*mm],        style=TableStyle([            ('VALIGN', (0, 0), (-1, -1), 'TOP'),            ... some other options ...        ])))# add invoice footer; this should be at a specific position on the pageflowable_list.append(Spacer(1, 5*mm))flowable_list.append(Paragraph('Total: 0', pg_style_1))# build PDFbuffer = io.BytesIO()doc = SimpleDocTemplate(buffer)doc.build(flowable_list)我的问题:底部的总金额每次都必须位于特定位置(类似于x*mm底部),但可能有可变数量的详细信息,导致详细信息表具有非固定高度。我目前的解决方案:Spacer在表后添加一个;这个间隔的高度必须根据表格中的行数来计算(更多的行意味着间隔会更小;更少的行产生更大的间隔)。但是,如果其中一行环绕并占用比单行更多的空间,则此操作将失败。我的问题:有没有办法为详细信息表设置固定高度,无论有多少行,但仍然继续使用SimpleDocTemplate?这个类似的问题显示了一个将所有内容手动绘制到画布上的解决方案,但SimpleDocTemplate如果可能的话,我想要一种继续使用 的方法。
查看完整描述

2 回答

?
翻翻过去那场雪

TA贡献2065条经验 获得超14个赞

试试这个使用“TopPadder”的可行示例,(结果是 Total 被推到 Frame 的底部,我假设你可以在它下面添加一个垫子,以控制底部的高度):


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

from reportlab.lib.units import mm

from reportlab.platypus import Paragraph, Spacer, Table, TableStyle

from reportlab.lib.styles import getSampleStyleSheet

from reportlab.platypus import SimpleDocTemplate

from reportlab.platypus.flowables import TopPadder

import io


def create_pdf():


    styles=getSampleStyleSheet()


    # add invoice header

    flowable_list = [

        Spacer(1, 5 * mm),

        Paragraph(f'Date: ...', styles['Normal']),

        Spacer(1, 5 * mm),

    ]


    # add invoice details

    detail_list = [

        ('Item 1', 8, 45),

        ('Item 2', 1, 14),

    ]

    row_list = [

        [

            Paragraph(f'desc', styles['Normal']),

            # quantity,

            # amount,

        ]

        for desc, quantity, amount in detail_list]


    story = []

    story.append(

        Table(

            data=row_list,

            colWidths=[100 * mm, 40 * mm, 40 * mm],

            style=TableStyle([

                ('VALIGN', (0, 0), (-1, -1), 'TOP'),

                # ... some other options...

            ])))


    # add invoice footer; this should be at a specific position on the page

    flowable_list.append(Spacer(1, 5 * mm))

    flowable_list.append(TopPadder(Paragraph(f'Total: 0', styles['Normal'])))


    # build PDF

    buffer = io.BytesIO()

    doc = SimpleDocTemplate("test2.pdf")

    doc.build(flowable_list)


    # ----------------------------------------------------------------------

if __name__ == "__main__":

    create_pdf()  # Printing the pdf


查看完整回答
反对 回复 2021-11-16
?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

我还没有找到更好的方法,所以我将添加我当前的解决方案;也许它会帮助一些未来有类似问题的读者。


...

story.append(

    Table(

        data=row_list,

        colWidths=[100*mm, 40*mm, 40*mm],

        style=TableStyle([

            ('VALIGN', (0, 0), (-1, -1), 'TOP'),

            ... some other options ...

        ])))


# calculate real height of details table, so we can add a 'Spacer' for the missing

# part to have the invoice totals at the correct height at the bottom of the page

_, real_height = story[-1].wrap(doc_width, doc_height)

height_reserved_for_details = 100*mm

remaining_height = max(0, height_reserved_for_details - real_height)

story.append(Spacer(1, remaining_height))


flowable_list.append(Paragraph('Total: 0', pg_style_1))


查看完整回答
反对 回复 2021-11-16
  • 2 回答
  • 0 关注
  • 530 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号