You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Reportlab表格在Frame内垂直对齐或拉伸填充?

解决Reportlab表格垂直对齐问题

你的表格目前已在Frame内水平填充空间且单元格水平居中,但垂直方向为顶部对齐。以下两种方案可实现你需要的垂直对齐效果:

方案1:让表格在Frame内整体垂直居中

Frame默认从顶部开始布局Flowable,我们可以自定义一个容器Flowable,将Table包裹后计算垂直偏移量,实现整体居中:

from reportlab.lib.pagesizes import letter
from reportlab.lib.units import inch
from reportlab.lib import colors

from reportlab.platypus import (
    Frame, Flowable, PageTemplate, 
    BaseDocTemplate, TableStyle, Table,
    NextPageTemplate, 
)


class Square(Flowable):
    def __init__(self):
        super().__init__()
        self.width = inch
        self.height = inch
    
    def __repr__(self):
        return "Square"

    def draw(self):
        self.canv.setFillColorRGB(255, 0, 0) 
        self.canv.rect(0, 0, self.width, self.height, fill=True)

# 自定义容器Flowable,实现内容垂直居中
class VerticallyCenteredContainer(Flowable):
    def __init__(self, content, target_height):
        super().__init__()
        self.content = content
        self.target_height = target_height
        # 获取内容自身高度
        self.content.wrap(0, 0)
        self.width = self.content.width
        self.height = target_height

    def draw(self):
        # 计算垂直偏移量:(目标高度 - 内容高度)/2
        y_offset = (self.target_height - self.content.height) / 2
        # 保存当前画布状态,绘制后恢复
        self.canv.saveState()
        self.canv.translate(0, y_offset)
        self.content.draw()
        self.canv.restoreState()


medium_margin = inch * .5 
small_margin = inch * .25

segment_table_width = letter[0] - medium_margin * 2
segment_table_height = inch * 3
segment_table_frame = Frame(
    medium_margin, 
    medium_margin, 
    segment_table_width,
    segment_table_height,
    showBoundary=True,
    leftPadding=0,
    bottomPadding=0,
    rightPadding = 0,
    topPadding=0
)


segment_cover = PageTemplate(
    "segment-cover", 
    frames=[segment_table_frame],
    pagesize=letter
)


template = BaseDocTemplate(
    filename = "example.pdf",
    pageTemplates=[segment_cover],
    pageSize = letter
)


story = []

table_data = [[Square() for j in range(5)] for i in range(20)]
table_style = TableStyle([
    ('ALIGN', (0,0), (-1,-1), 'CENTER'), 
    ("BACKGROUND", (0,0), (-1,-1), colors.green)
])

table = Table(table_data, style=table_style)

parts = table.split(segment_table_width, segment_table_height)

table1, table2 = parts

# 将表格放入垂直居中容器
centered_table = VerticallyCenteredContainer(table1, segment_table_height)

story.append(NextPageTemplate("segment-cover"))
story.append(centered_table)

template.build(story)

方案2:让表格垂直填充Frame,同时单元格内容垂直居中

这种方案需要调整表格的行高,让表格总高度匹配Frame高度,并设置单元格垂直居中:

from reportlab.lib.pagesizes import letter
from reportlab.lib.units import inch
from reportlab.lib import colors

from reportlab.platypus import (
    Frame, Flowable, PageTemplate, 
    BaseDocTemplate, TableStyle, Table,
    NextPageTemplate, 
)


class Square(Flowable):
    def __init__(self):
        super().__init__()
        self.width = inch
        self.height = inch
    
    def __repr__(self):
        return "Square"

    def draw(self):
        self.canv.setFillColorRGB(255, 0, 0) 
        self.canv.rect(0, 0, self.width, self.height, fill=True)


medium_margin = inch * .5 
small_margin = inch * .25

segment_table_width = letter[0] - medium_margin * 2
segment_table_height = inch * 3
segment_table_frame = Frame(
    medium_margin, 
    medium_margin, 
    segment_table_width,
    segment_table_height,
    showBoundary=True,
    leftPadding=0,
    bottomPadding=0,
    rightPadding = 0,
    topPadding=0
)


segment_cover = PageTemplate(
    "segment-cover", 
    frames=[segment_table_frame],
    pagesize=letter
)


template = BaseDocTemplate(
    filename = "example.pdf",
    pageTemplates=[segment_cover],
    pageSize = letter
)


story = []

row_count = 20
col_count = 5
table_data = [[Square() for j in range(col_count)] for i in range(row_count)]

# 计算每行高度:Frame高度 / 行数
row_height = segment_table_height / row_count

table_style = TableStyle([
    ('ALIGN', (0,0), (-1,-1), 'CENTER'), 
    ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),  # 单元格内容垂直居中
    ("BACKGROUND", (0,0), (-1,-1), colors.green)
])

# 创建表格时指定行高
table = Table(table_data, style=table_style, rowHeights=[row_height]*row_count)

parts = table.split(segment_table_width, segment_table_height)

table1, table2 = parts

story.append(NextPageTemplate("segment-cover"))
story.append(table1)

template.build(story)

内容的提问来源于stack exchange,提问作者user13950701

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:36:18