简体   繁体   English

Reportlab表拆分

[英]Reportlab Table split

I am new to ReportLab, page templates. 我是ReportLab的新手,页面模板。 I have to create a report where I have 2 page templates- first page uses header page template and all other pages have common template. 我必须创建一个报告,其中有2个页面模板-第一页面使用标题页面模板,所有其他页面都使用通用模板。 Report has to split a table onto multiple pages. 报表必须将一个表拆分为多个页面。 On first page table has to be displayed on a less wider frame and then remaining table on wider frames on rest of the pages. 在首页上,表格必须显示在宽度较小的框架上,然后其余表格在较大的框架上显示其余页面。

How can I change column widths and table style when table splits among different pages? 当表格在不同页面之间拆分时,如何更改列宽和表格样式?

EDIT: Here I am putting some code which successfully splits but keeps the table at same width across all pages 编辑:在这里我放一些代码可以成功拆分,但在所有页面上保持表相同的宽度

# 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())

With the normal Table it seems that is not possible to do so automatically (based on the source code ). 对于普通Table ,似乎不可能自动执行此操作(基于源代码 )。 It is made to retain the column width when split, which makes sense as changing the layout of a table after a pagebreak would make it rather confusing for the end-user. 它可以在拆分时保留列宽,这很有意义,因为在分页符之后更改表的布局会使最终用户感到困惑。

You could make your own version of a Table that does change the column size but this would involve overwriting the rather complex split function of the Table . 您可以创建自己的Table版本,但该版本的确会改变列的大小,但这将涉及覆盖Table的相当复杂的split函数。

Thus in your case the easiest and probably most viable solution would be to make the frames in both templates the same width. 因此,在您的情况下,最简单且可能最可行的解决方案是使两个模板中的框架具有相同的宽度。 Then you don't have to change the column width at all. 然后,您根本不必更改列宽。

Edit: On request of OP I looked into options to indeed adept the style and column width for the laterpages. 编辑:应OP的要求,我研究了一些选项,以使后一页的样式和列宽更加熟练。 Based on this I created the following class based on Reportlabs Table : 基于此,我基于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)

This class allows the user to specify the style and columnwidth for the later pages using the keyword arguments laterColWidths and laterStyle of which the syntax is exactly the same as for the normal colWidths and style but will only be used on the parts of the table that placed outside the original page. 此类允许用户使用关键字参数laterColWidthslaterStyle指定后面的页面的样式和laterColWidths laterStyle ,其语法与普通colWidthsstyle colWidths ,但是仅在放置表的部分上使用在原始页面之外。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM