Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python reportlab SimpleDoctTemplate-使用可变行数设置表的固定高度_Python_Python 3.x_Reportlab - Fatal编程技术网

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

Python reportlab SimpleDoctTemplate-使用可变行数设置表的固定高度,python,python-3.x,reportlab,Python,Python 3.x,Reportlab,我尝试使用reportlab在Python中生成PDF发票 发票将只有一页,并且不会有比这一页上的空白更多的细节;我的代码在生成PDF之前检查最大数量的详细信息 现在我正在使用SimpleDocTemplate将所有内容添加到页面中,并使用表来构造详细信息。 下面是一个简化的代码示例: from reportlab.lib.units import mm from reportlab.platypus import Paragraph, Spacer, Table, TableStyle fro

我尝试使用
reportlab
Python
中生成PDF发票

发票将只有一页,并且不会有比这一页上的空白更多的细节;我的代码在生成PDF之前检查最大数量的详细信息

现在我正在使用
SimpleDocTemplate
将所有内容添加到页面中,并使用
表来构造详细信息。
下面是一个简化的代码示例:

from reportlab.lib.units import mm
from reportlab.platypus import Paragraph, Spacer, Table, TableStyle
from reportlab.platypus import SimpleDocTemplate

# add invoice header
flowable_list = [
    Spacer(1, 5*mm),
    Paragraph('Date: ...', pg_style_1),
    Spacer(1, 5*mm),
]

# add invoice details
detail_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 page
flowable_list.append(Spacer(1, 5*mm))
flowable_list.append(Paragraph('Total: 0', pg_style_1))

# build PDF
buffer = io.BytesIO()
doc = SimpleDocTemplate(buffer)
doc.build(flowable_list)
我的问题:底部的总金额每次都必须位于特定位置(类似于底部的
x*mm
),但可能存在数量可变的细节,从而导致细节表的高度不固定

我当前的解决方案:在表格后添加一个
垫片
;必须根据表中的行数计算此间隔的高度(行越多表示间隔越小;行越少表示间隔越大)。但如果其中一行环绕并占用比一行更多的空间,则此操作将失败

我的问题:是否有一种方法可以设置明细表的固定高度,不管有多少行,但仍然使用
SimpleDocTemplate


显示了一个将所有内容手动绘制到画布上的解决方案,但如果可能,我希望有一种方法可以继续使用
SimpleDoctTemplate

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

...
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))

使用“TopPadder”尝试这个可行的示例(结果是总数被推到框架的底部,我假设您可以在其下方添加一个缓冲垫,以控制从底部开始的高度):


发票明细(在页眉和页脚之间)分为两个框架,行列表的大框架和总计的小框架如何?每个框架包含一个表,一个用于详细信息,另一个用于总计。给定帧,可以精确放置它们。然而,我问了一个类似的问题,如果我想在一个框架中自下而上工作,而不是自上而下工作,该怎么办@杰科:那怎么用框架呢?我不完全确定我是否理解。嗨,拉尔夫,我想到了页面上的框架,你可以在框架内放置桌子。不是将整个表放在一个框架中,而是将表分成两部分,一部分包含详细信息,另一部分仅包含总和(正如你所说的,除非误解,否则你希望每页的总和都在相同的位置。你下面的答案看起来与本文档第4页相似,它是Platypus.py中的一个类,名为Top Padder。也许你也可以看看我的问题,看看你是否可以找到解决方案。对不起,在flowable范围内s、 但是,再加上你对这个问题的评论,我想我理解你指的是什么来解决我的问题。我可能会尝试一下。谢谢。谢谢你的更新。这样做似乎是可行的。
########################################################################
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