[reportlab-users] Accessing page data in onPageEnd

Robin Becker robin at reportlab.com
Thu Mar 22 07:41:33 EDT 2007


Chris Wilson wrote:

> Hi All,

>

> I am rendering a document using the BaseDocTemplate. The document uses

> tables containing data of a variable size and often these tables span

> multiple pages, and I don't necessarily know where exactly in the table

> the run onto the next page will occur during the build(). I am using the

> onPageEnd event to draw onto the current canvas some text at the top and

> bottom of each page. My issue is that the text I want drawn relates to

> whatever text was placed in the table on the page currently being rendered.

>

> Is it possible to in the onPageEnd method to pull from the canvas or

> document the information that has just been rendered onto that page (or

> to save while preparing the flowables the information in a way that can

> be easily accessed int the onPageEnd during the document build()) so

> that I can determine what the text I am need to draw on the page during

> the onPageEnd method is?

>

> I understand that this question is potentially vague, and I apologies

> for this. I am just not sure how to better describe or phrase what I am

> doing.

>

> Thanks in advance for any help.

>

> Regards,


In the onPageEnd method you have access to the canvas.

canvas._code is a list of the strings that will eventually become the pdf so one
possibility is to inspect that, but I suspect that is the wrong way to go as the
pdf code is fairly impenetrable.

Probably a more fruitful approach is to consider overriding the table draw
method so you can inspect the contents of the cells that have been drawn.


The existing draw method is fairly complicated, but you can probably do this


class MyTable(Table):
recording = None
def draw(self):
if self.recording is not None:
self.recording[:] = []
self._curweight = self._curcolor = self._curcellstyle = None
self._drawBkgrnd()
if self._spanCmds == []:
# old fashioned case, no spanning, steam on and do each cell
for row, rowstyle, rowpos, rowheight in map(
None, self._cellvalues, self._cellStyles,
self._rowpositions[1:], self._rowHeights):
for cellval, cellstyle, colpos, colwidth in map(None, row,
rowstyle, self._colpositions[:-1], self._colWidths):
self._drawCell(cellval, cellstyle, (colpos, rowpos),
(colwidth, rowheight))
if self.recording is not None:
self.recording.append(cellval)
else:
# we have some row or col spans, need a more complex algorithm
# to find the rect for each
for rowNo in range(self._nrows):
for colNo in range(self._ncols):
cellRect = self._spanRects[colNo, rowNo]
if cellRect is not None:
(x, y, width, height) = cellRect
cellval = self._cellvalues[rowNo][colNo]
cellstyle = self._cellStyles[rowNo][colNo]
self._drawCell(cellval, cellstyle, (x, y), (width, height))
if self.recording is not None:
self.recording.append(cellval)
self._drawLines()



Then MyTable instances can be made to record each drawn table in turn so the
last table is available in MyTable.recording

after

MyRecording.recording = []

of course you could also just reset in the onPageEnd rather than in the draw
method itself.
-hope this isn't too complex-ly yrs-
Robin Becker


More information about the reportlab-users mailing list