Reportlab Table 拆分
Reportlab Table split
我是 ReportLab 页面模板的新手。我必须创建一个报告,其中我有 2 个页面模板 - 第一页使用 header 页面模板,所有其他页面都有通用模板。报告必须将 table 拆分到多个页面。在第一页 table 必须显示在较宽的框架上,然后在其余页面的较宽框架上显示 table。
当 table 在不同页面之间拆分时,如何更改列宽和 table 样式?
编辑:我在这里放置了一些成功拆分但在所有页面上保持 table 相同宽度的代码
# 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())
使用正常的 Table
似乎不可能自动执行此操作(基于 source code)。它在拆分时保留列宽,这很有意义,因为在分页后更改 table 的布局会使最终用户感到困惑。
您可以制作自己的 Table
版本来更改列大小,但这将涉及覆盖 Table
.[=21= 的相当复杂的 split
函数]
因此,在您的情况下,最简单且可能最可行的解决方案是使两个模板中的框架具有相同的宽度。那么您根本不必更改列宽。
编辑: 应 OP 的要求,我研究了一些选项,以真正掌握后续页面的样式和列宽。基于此,我基于 Reportlabs Table
创建了以下 class:
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)
此 class 允许用户使用关键字参数 laterColWidths
和 laterStyle
指定后面页面的样式和列宽,其语法与正常 colWidths
和 style
但只会用于 table 中位于原始页面之外的部分。
我是 ReportLab 页面模板的新手。我必须创建一个报告,其中我有 2 个页面模板 - 第一页使用 header 页面模板,所有其他页面都有通用模板。报告必须将 table 拆分到多个页面。在第一页 table 必须显示在较宽的框架上,然后在其余页面的较宽框架上显示 table。
当 table 在不同页面之间拆分时,如何更改列宽和 table 样式?
编辑:我在这里放置了一些成功拆分但在所有页面上保持 table 相同宽度的代码
# 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())
使用正常的 Table
似乎不可能自动执行此操作(基于 source code)。它在拆分时保留列宽,这很有意义,因为在分页后更改 table 的布局会使最终用户感到困惑。
您可以制作自己的 Table
版本来更改列大小,但这将涉及覆盖 Table
.[=21= 的相当复杂的 split
函数]
因此,在您的情况下,最简单且可能最可行的解决方案是使两个模板中的框架具有相同的宽度。那么您根本不必更改列宽。
编辑: 应 OP 的要求,我研究了一些选项,以真正掌握后续页面的样式和列宽。基于此,我基于 Reportlabs Table
创建了以下 class:
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)
此 class 允许用户使用关键字参数 laterColWidths
和 laterStyle
指定后面页面的样式和列宽,其语法与正常 colWidths
和 style
但只会用于 table 中位于原始页面之外的部分。