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