【问题标题】:Reportlab Table splitReportlab 表拆分
【发布时间】:2016-03-25 16:13:02
【问题描述】:

我是 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())

【问题讨论】:

    标签: python reportlab


    【解决方案1】:

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

    您可以制作自己的Table 版本,它确实会改变列大小,但这将涉及覆盖Table 的相当复杂的split 函数。

    因此,在您的情况下,最简单且可能最可行的解决方案是使两个模板中的框架具有相同的宽度。那么你根本不需要改变列宽。

    编辑: 应 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 指定后面页面的样式和列宽,其语法与普通colWidthsstyle 完全相同,但会只能用于放置在原始页面之外的表格部分。

    【讨论】:

    • 这不是一个可行的解决方案,因为表格太大,只有第一页空间较小。您能否建议我如何根据帧大小拆分数据,以便我可以创建 2 个表,第一个用于第一页模板,第二个将拆分到所有剩余页面。
    • 您能否向我们提供一些代码来显示您在这种情况下的问题?这使得解决它变得容易得多。
    • @bvnbhati 我添加了一些代码,应该能够提供您正在寻找的行为。
    • 我仍然被这个问题困扰。我在同一个文档中有很多这样的表格。我的下一步是 - 对于每个表格,我必须为表格的第一部分使用一个页面模板,为表格的其余部分使用另一个页面模板。我是否使用代码 sn-p 发布一个单独的问题?
    • 我建议为此提出一个新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 2014-04-03
    • 2014-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多