Reportlab:对齐,vAlign Table 到帧的 'BOTTOM'

Reportlab: Align, vAlign Table to the 'BOTTOM' of a Frame

我无法将 Table 对象对齐到框架的底部,hAlign 'RIGHT' 和 'LEFT' 有效,但它似乎卡在了 'TOP' ,如何将 Table 向下对齐到框架的 'MIDDLE' 或 'BOTTOM'?下面是一个完整的 运行-able 示例。请注意,框架内的 table 应该位于底部,这意味着 table 位于右下角(现在,table 下面位于框架的顶部)。

from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
from reportlab.platypus import Frame, PageTemplate
from reportlab.lib.units import cm
from reportlab.platypus import (Table, TableStyle, BaseDocTemplate)

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

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

    # Create a frame
    CatBox_frame = Frame(
        x1=14.00 * cm,  # From left
        y1=1.5 * cm,  # From bottom
        height=9.60 * cm,
        width=5.90 * cm,
        leftPadding=0 * cm,
        bottomPadding=0 * cm,
        rightPadding=0 * cm,
        topPadding=0 * cm,
        showBoundary=1,
        id='CatBox_frame')

    # Create a table
    CatBox = Table([
        ['', '', '', 'A'],
        ['', '', '', 'B'],
        ['', '', '', 'C'],
        ['AA', 'BB', 'CC', '']], 1.2 * cm, 1.2 * cm, vAlign='BOTTOM')

    # Style the table
    CatBox.setStyle(TableStyle([
        ('SIZE', (0, 0), (-1, -1), 7),
        ('SIZE', (0, 0), (0, 0), 5.5),
        ('TEXTCOLOR', (0, 0), (-1, -1), colors.black),
        ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
        ('VALIGN', (0, 0), (-1, -1), 'BOTTOM'),
    ]))

    # Trying to tell the table to be a bottom align object (when later put in frame)
    CatBox.Align = 'BOTTOM'
    CatBox.vAlign = 'BOTTOM'

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

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

    # Creating a page template 
    frontpage = PageTemplate(id='FrontPage',
                             frames=[CatBox_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

更新:我在 flowables.py 中发现了一个叫做 TopPadder 的东西,但是却不知道如何使用它(当 Align 'BOTTOM' 应该是合乎逻辑的时候,我会感觉像是一个黑客/一个奇怪的应用程序完成右、左、上和中)。 (如本文档第 4 页所示:https://www.reportlab.com/examples/rml/test/test_008_tables.pdf

class TopPadder(Flowable): '''wrap a single flowable so that its first bit will be padded to fill out the space so that it appears at the bottom of its frame'''

更新二:是的,我解决了,解决方案是:

from reportlab.platypus.flowables import TopPadder

story = [TopPadder(CatBox)]

也许应该是这样的:

doc = SimpleDocTemplate('CatBox.pdf')

CatBox = []
table = Table([
    ['', '', '', 'A'],
    ['', '', '', 'B'],
    ['', '', '', 'C'],
    ['AA', 'BB', 'CC', '']], 1.2 * cm, 1.2 * cm, vAlign='BOTTOM')

table.setStyle(TableStyle([
    ('SIZE', (0, 0), (-1, -1), 7),
    ('SIZE', (0, 0), (0, 0), 5.5),
    ('TEXTCOLOR', (0, 0), (-1, -1), colors.black),
    ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
    ('VALIGN', (0, 0), (-1, -1), 'BOTTOM'),
]))

table.Align = 'BOTTOM'
table.vAlign = 'BOTTOM'

table_frame = Frame(
    x1=7.0 * cm,  # From left
    y1=1.5 * cm,  # From bottom
    height=9.60 * cm,
    width=5.90 * cm,
    leftPadding=0 * cm,
    bottomPadding=0 * cm,
    rightPadding=0 * cm,
    topPadding=0 * cm,
    showBoundary=1,
    id='CatBox_frame'
)

CatBox.append(table)

template = PageTemplate(id='all', frames=table_frame)
doc.addPageTemplates([template])

doc.build(CatBox)

基于 http://www.blog.pythonlibrary.org/2014/03/10/reportlab-how-to-create-custom-flowables/ 的替代方案可能是:

doc = SimpleDocTemplate('CatBox.pdf')
doc.build([CatBox(x=5, y=25)])

class CatBox(Flowable):

    def __init__(self, x=0, y=0):
        Flowable.__init__(self)
        self.x = x
        self.y = y

    #----------------------------------------------------------------------
    def coord(self, x, y, unit=1):
        """
        
        Helper class to help position flowables in Canvas objects
        """
        x, y = x * unit, self.height - y * unit
        return x, y

    #----------------------------------------------------------------------
    def draw(self):
        """
        Draw the shape, text, etc
        """

        table = Table([
            ['', '', '', 'A'],
            ['', '', '', 'B'],
            ['', '', '', 'C'],
            ['AA', 'BB', 'CC', '']], 1.2 * cm, 1.2 * cm, vAlign='BOTTOM')

        table.setStyle(TableStyle([
            ('SIZE', (0, 0), (-1, -1), 7),
            ('SIZE', (0, 0), (0, 0), 5.5),
            ('TEXTCOLOR', (0, 0), (-1, -1), colors.black),
            ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
            ('VALIGN', (0, 0), (-1, -1), 'BOTTOM'),
        ]))

        table.Align = 'BOTTOM'
        table.vAlign = 'BOTTOM'

        table.wrapOn(self.canv, self.width, self.height)
        table.drawOn(self.canv, *self.coord(self.x, self.y, cm))

Top Padder 会解决它。

class TopPadder(Flowable): '''wrap a single flowable so that its first bit will be padded to fill out the space so that it appears at the bottom of its frame'''

在构建 'story' 时在下面添加。

from reportlab.platypus.flowables import TopPadder

story = [TopPadder(CatBox)]