Progress Report (was Re: [reportlab-users] Tables)
Rasjid Wilcox
reportlab-users@reportlab.com
Sun, 19 Oct 2003 23:33:38 +1000
On Friday 17 October 2003 21:40, Henning von Bargen wrote:
> Just like Rasjid, I'm planning to use RL for generating Database reports,
> and I think if we join our effors we could make it better than Oracle
> Reports or Crystal reports
> (at least for PDF generation).
So Henning (and anyone else) can work out if they are interested in what I'm
dong, here is some info.
For my database report object, I have done some 'concept' code. The idea is
to create composite Flowables from existing ones, in a similar way
(code-wise) that one creates a Gui. An example is probably best.
x1 = XBox(50, 50, 'text 1')
s1 = Spacer(10, 5)
x2 = XBox(40, 40, 'text 2')
rG = RptGroup() # this is a flowable
rG.add('x1', x1, left=0, top=0)
rG.add('s1', s1, left='x1.right', top = 0)
rG.add('x2', x2, left='s1.right', top='s1.height')
w, h = rG.wrap(200, 200)
print "Width: %s, height %s" % (w, h)
# w, h = (100, 50)
c = Canvas('test2.pdf', A4)
rG.drawOn(c, 20, A4[1] - 20 - h)
c.showPage()
c.save()
The code does exactly what you expect. It creates a flowable rG, which
contains two XBoxes x1, and x2 and a Spacer s1. The RptGroup classes' main
feature is that you can specify the position of one object in rG based on the
properties of other objects in rG, many of which may not be known until
wrapping. (It uses recursion to determine derived paramaters, and yes, it
does detect recursive loops.)
Having got the above working, I am now going to try and get a more generalised
form, where one could write:
rG.add('x3', x3, left='1 * cm', top='x2.bottom + 1 * cm')
and it would place the x3 XBox 1 cm below the base of x2, 1cm from the left
margin. (Obviously more useful for paragraphs, where you don't know the
bottom until during the wrap process.)
Once this is done, I'll then tie in the database stuff etc.
That about sums up the current state and direction of my database report
writing stuff.
Lastly, for anyone interested, I have finished the Plane object. I decided
that it was not the direction I wanted to head right now, so it is only
lightly tested. However, it is still useful. It allows placing of Flowables
on an 'infinite canvas', which is then split up into page-sized (or smaller)
pieces (which I have called Partitions). Usually you would have each
Partition on a single page, and would be good for creating large charts or
posters that span several pages (particularly an 'n x m' spread). For
example - large flow-charts, organisation charts or family tree diagrams.
The following code places a single XBox in a Plane, and then draws the four
Partition flowables returned on a page, replete with crop-marks so you could
cut out each partition and paste the XBox back together again.
from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.pagesizes import A4, A5
from reportlab.platypus import XBox
c = Canvas('plane-test.pdf', A4)
# very small test
plane = Plane(60, 60, horizBleed = 5, vertBleed = 5, drawCropMarks=1)
X = XBox(90, 90, "XBox in a Plane")
plane.add(X, -45, -45)
partition, i, j = plane.getPartition()
# note the 'partition' returned is a flowable
while partition:
partition.drawOn(c, 200 + i * 150, 200 + j * 150)
c.drawString(200 + i * 150, 180 + j * 150, \
'Partition (%s, %s)' % (i, j))
partition, i, j = plane.getPartition()
c.showPage()
c.save()
If you want the code for either the plane object or the 'concept' code for my
database report object, go to http://www.openminddev.net/files/reportlab/ and
have a look. The generated pdf's and some png's are there too.
Happy coding everyone.
Cheers,
Rasjid.
--
Rasjid Wilcox
Canberra, Australia (UTC +10 hrs)
http://www.openminddev.net