Reportlab表拆分

时间:2016-03-25 16:13:03

标签: python reportlab

我是ReportLab的新手,页面模板。我必须创建一个报告,其中我有2个页面模板 - 第一页使用标题页模板,所有其他页面都有公共模板。报告必须将表拆分为多个页面。在第一页上,表格必须显示在较宽的框架上,然后在其余页面上的较宽框架上保留表格。

当表格在不同页面之间拆分时,如何更改列宽和表格样式?

编辑:我在这里放了一些成功拆分的代码,但是在所有页面上保持表格的宽度相同

# ReportLab PDF Generation Library
from reportlab.pdfgen        import canvas
from reportlab.lib.units     import inch, cm
from reportlab.lib.pagesizes import letter, landscape
from reportlab.lib           import colors

from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import BaseDocTemplate, Frame, Paragraph, NextPageTemplate, PageBreak, PageTemplate, Spacer
from reportlab.platypus.tables import Table, TableStyle

# Constants
Font_Leading = 10
Word_Spacing = 0.0
Char_Spacing = 0.08

#global table
data= [['DATE', 'NAME', 'ITEM', 'AMOUNT', 'BALANCE'],
    ['01/12/15', 'William', 'ITEM1 RELATED STUFF', '365.00', '43.30']
    # CONSIDER MANY MORE ITEMS HERE
    # NUMBER FO ITMES VARYING IN WAY TO CAUSE 1 OR MORE PAGES
    # 3RD COLUMN WILL HAVE DESCRIPTIVE ITEM
    # WHICH WILL REPLACE WITH PARAGARPHS LATER ON
  ]
t=Table(data,repeatRows=1,
  colWidths=[.7*inch, 1*inch, 2.4*inch, .8*inch, .8*inch])
 #The top left cell is (0, 0) the bottom right is (-1, -1).
tStyle = TableStyle([
    # All Cells
    ('FONTSIZE', (0,0), (-1,-1), 8),
    ('TOPPADDING', (0,0), (-1,-1), 0),
    ('BOTTOMPADDING', (0,0), (-1,-1), 0),
    ('VALIGN', (0,0), (-1,-1), 'TOP'),
    ('LEADING', (0,0), (-1,-1), 10),
    # Top row
    ('BACKGROUND', (0,0), (-1,0), colors.maroon),
    ('TEXTCOLOR', (0,0), (-1,0), colors.white),
    ('ALIGN', (0,0), (-1,0), 'CENTRE'),
    # 3RD and 4th column,
    ('ALIGN', (3,0), (4,-1), 'RIGHT'),
    # Line commands
    # All
    ('BOX',(0,0),(-1,-1),.5,colors.black),
    # top row
    ('GRID',(0,0),(-1,0),.5,colors.black),
    # all columns
    ('LINEBEFORE',(0,0),(-1,-1),.5,colors.black),
    # last column
    ('LINEAFTER',(-1,0),(-1,-1),.5,colors.black),
    # last row
    ('LINEBELOW',(0,-1),(-1,-1),.5,colors.black)])
t.setStyle(tStyle)

def othPg(c, doc):
  t.colWidths = [.2*inch, .2*inch,4*inch, .2*inch, .2*inch]
  tStyle.add('BACKGROUND',(0,0),(-1,-1),colors.lightblue)
  x=1

def pgHdr(c, doc):
  width,height = letter
  c.saveState()
  c.translate(.3 * inch, 0 * inch)

# STUFF RELATED TO 2 INCH STTIC HEADER FOR FIRST PAGE
  c.restoreState()


def main():
  pdf_file = 'stmt.pdf'
  Elements = []
  doc = BaseDocTemplate(pdf_file,
                        pagesize=letter,
                        leftMargin=.3*inch,
                        rightMargin= .1 * inch,
                        topMargin= .1 * inch,
                        bottomMargin=.3 * inch,
                        showBoundary=1)
  #normal frame as for SimpleFlowDocument
  frameT = Frame(doc.leftMargin + 2*inch, doc.bottomMargin, doc.width - 2.01*inch, doc.height - 4.1*inch, id='normal', showBoundary=0)
  frameB = Frame(doc.leftMargin+2, doc.bottomMargin, 7.5*inch, 10*inch, id='small', showBoundary=1)



  doc.addPageTemplates([PageTemplate(id='First',frames=frameT,onPage=pgHdr),
                        PageTemplate(id='Later',frames=frameB,onPage=othPg)
                      ])
  Elements.append(NextPageTemplate('Later'))
  Elements.append(t)
  doc.build(Elements)

if __name__ == "__main__":
    sys.exit(main())

1 个答案:

答案 0 :(得分:2)

使用正常的Table似乎无法自动执行此操作(基于source code)。它是为了在拆分时保留列宽,这有意义,因为在分页后更改表的布局会使最终用户感到困惑。

您可以创建自己的Table版本来更改列大小,但这会涉及覆盖split的相当复杂的Table函数。

因此,在您的情况下,最简单且可能最可行的解决方案是使两个模板中的帧具有相同的宽度。然后,您根本不必更改列宽。

编辑:根据OP的要求,我查看了确实擅长后期页面的样式和列宽的选项。基于此,我基于Reportlabs Table创建了以下类:

class LaterPagesTable(Table):
    def __init__(self, data, laterColWidths=None, laterStyle=None, **kwargs):
        Table.__init__(self, data, **kwargs)

        self._later_column_widths = laterColWidths
        self._later_style = laterStyle


    def split(self, availWidth, availHeight):
        self._calc(availWidth, availHeight)
        if self.splitByRow:
            if not rl_config.allowTableBoundsErrors and self._width>availWidth: return []
            tables = self._splitRows(availHeight)

            if len(tables):
                self.onLaterPages(tables[1])
            return tables
        else:
            raise NotImplementedError


    def onLaterPages(self, T):
        if self._later_column_widths:
            T._argW = self._later_column_widths

        if self._later_style:
            T.setStyle(self._later_style)

此类允许用户使用关键字参数laterColWidthslaterStyle指定后续页面的样式和列宽,其语法与普通colWidths的语法完全相同和style但仅用于放置在原始页面之外的表格部分。