如何实现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
相关产品推荐
相关产品推荐

