Re: Large table with totals in page footer
Tony Middleton via reportlab-users <[email protected]>
| Newsgroups | gmane.comp.python.reportlab.user |
|---|---|
| Message-ID | <[email protected]> |
I've now got a solution to this - example attached. Thank you to Robin Becker for his help. To recap, I need to create a document which is one big table approximately 600 pages long. On the footer of each page I need to include something derived from the rows printed on that page. I need to include page breaks at certain points; there doesn't seem to be a way of doing this within a table so my document is a sequence of separate tables which has made the solution more complicated. The solution isn't terribly elegant but it seems to work. Regards Tony Middleton On 29/03/17 14:41, Tony Middleton via reportlab-users wrote: > > I am trying to create a document with a multipage table. At the > bottom of each page I need a footer which includes some information > derived from rows printed on that page. I am using the Table() class > and rows are variable height so I don't know which rows will print on > a page. > > I've looked around and can't find any way to do this. Any pointers > would be greatly appreciated. > > Regards > > Tony Middleton > > > > _______________________________________________ > reportlab-users mailing list > [email protected] > https://pairlist2.pair.net/mailman/listinfo/reportlab-users
example.py
(text/x-python, 4.5 KB)
from reportlab.lib.pagesizes import A4,landscape
from reportlab.lib.units import mm
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, PageBreak
###################################################################
###################################################################
class TableDocTemplate(SimpleDocTemplate):
def afterPage(self):
###############
#
# Amend this as required to create your page footer
#
###############
page = self.page
data = self.TBconnect.get().getdata()
pagesum = sum([x[1] for x in data[1:]])
canvas = self.canv
canvas.saveState()
canvas.drawString(65, 65, "Page %s - value %s" % (page,pagesum))
canvas.restoreState()
def Docinit(self,connector):
self.TBconnect=connector
class TBTable(Table):
def onSplit(self,T,byRow=1):
'''
This method will be called when the Table is split.
Called twice. First with Table() to fit on page then with Table() containing remaining data.
'''
T.TBconnect = self.TBconnect
T.TBid = self.TBid
T.TBconnect.put(T)
def TBinit(self,connector):
self.TBconnect = connector
self.TBid = connector.addtable(self)
def getdata(self):
return self._cellvalues
def getid(self):
return self.TBid
class TBConnect:
def __init__(self):
self.tables = []
self.currtable = 0
self.splitstatus = 0
self.first = None
self.second = None
def addtable(self,table):
self.tables.append(table)
return len(self.tables)
def put(self,table):
if self.splitstatus == 0:
###############
#
# First of pair of onSplit calls when TBTable() can't fit on page - first split of TBTable().
#
###############
self.currtable += 1
if self.currtable != table.getid():
raise Exception("Unexpected table : Expected %s, received %s" % (self.currtable, table.getid()))
self.first = table
self.second = None
self.splitstatus = 1
elif self.splitstatus == 1:
###############
#
# Second of pair of onSplit calls when TBTable() can't fit on page.
#
###############
if self.currtable != table.getid():
raise Exception("Unexpected table : Expected %s, received %s" % (self.currtable, table.getid()))
self.second = table
self.splitstatus = 2
elif self.splitstatus == 3:
###############
#
# First of pair of onSplit calls when remainder of TBTable() can't fit on page.
#
###############
if self.currtable != table.getid():
raise Exception("Unexpected table : Expected %s, received %s" % (self.currtable, table.getid()))
self.first = table
self.second = None
self.splitstatus = 1
else:
raise Exception("TBConnect put when split status = %s" % self.splitstatus)
def get(self):
if self.splitstatus == 0:
###############
#
# Table isn't being split so return whole original data table.
#
###############
self.currtable += 1
if self.currtable > len(self.tables):
raise Exception("TBConnect No data left")
return self.tables[self.currtable - 1]
elif self.splitstatus == 2:
###############
#
# Table split - return first table to fit on page.
#
###############
self.splitstatus = 3
return self.first
elif self.splitstatus == 3:
###############
#
# Table split - return last part of table to fit on page.
#
###############
self.splitstatus = 0
return self.second
else:
raise Exception("TBConnect get when split status = %s" % self.splitstatus)
###################################################################
###################################################################
def printtables(datalist,widths):
###############
#
# datalist is a list of tuples (table data, table style data)
#
###############
connector = TBConnect()
elements = []
for data, style in datalist:
t = TBTable(data,colWidths=widths,repeatRows=1)
t.setStyle(TableStyle(style))
t.TBinit(connector)
if elements:
elements.append(PageBreak())
elements.append(t)
doc = TableDocTemplate("filename.pdf" ,pagesize=landscape(A4),
topMargin=15*mm, bottomMargin=10*mm, leftMargin=12*mm,rightMargin=12*mm)
doc.Docinit(connector)
doc.build(elements)