Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

Generating beautiful reports

by kappa (Chaplain)
on Apr 09, 2002 at 08:31 UTC ( #157678=perlquestion: print w/replies, xml ) Need Help??

kappa has asked for the wisdom of the Perl Monks concerning the following question:

Hello, fellow perlmonks.
My current project (as well as many projects in the past) involves generating reports (or just filling forms) for printing. You see, I've got a document form which must be filled with data entered through a web-form and then be presented alone on a page suitable for printing right from the browser.
The hard part is generating the image. The way of calculating (x,y) coordinates of each and every text string (i'm using raw GD right now) is really hard especially as the forms are changing often, new fields are added and old are moved around. Growing complexity brings me more and more grief as I now need to wrap text blocks, underline words, resize tables, add different justification and the like. I don't really want to reinvent a TeX or just MS Word.
The next problem is templating. The guy next to me draws a new form which I then translate to series of (x,y) by hands. The process is really no fun and slows down the work greatly.
What I really need, is a tool similar to numerous report-generating engines in the VB/Delphi/Access world. What do you all think on this issue? I've googled the thing but found nothing! NOTHING at all! I dream of something like:
my $rep = new Image::Template('invoice.png'); $rep->param(account => '123123123', name => 'Don Quixote'); $rep->savefile('filled.png');
Of course, this probably would involve some voodoo :)
And no, TT2 GD plug-in is not what I look for.

Replies are listed 'Best First'.
Re: Generating beautiful reports
by Corion (Patriarch) on Apr 09, 2002 at 08:39 UTC

    What you want to do really screams for a templating engine, as the only thing that changes per document is the data from the web form.

    Personally, I wouldn't create the images with GD but create PDFs from LaTeX, as LaTeX gives a lot of flexibility and a nice layout. The sooner you go away from overlaying text onto a pretty picture, the easier it will be.

    The only problem is, of course, if the pretty background picture is something you cannot change/influence. Then, TeX is out of the window, as you'd then have to describe the fields as locations to TeX, which is no more fun than describing them to GD.

    Have a look at TT2, which is, AFAIK, a general templating system (opposed to a templating system geared for HTML) and what TeX output you can get from there. The rest, spawning off LaTeX to create a temporary PDF and redirecting the user to that PDF file is then fairly simple.

    perl -MHTTP::Daemon -MHTTP::Response -MLWP::Simple -e ' ; # The $d = new HTTP::Daemon and fork and getprint $d->url and exit;#spider ($c = $d->accept())->get_request(); $c->send_response( new #in the HTTP::Response(200,$_,$_,qq(Just another Perl hacker\n))); ' # web
      Yes, of course I want a templating engine :) And I'd love to use LaTeX to produce PDFs. I have a fairly extensive LaTeX experience. And there's a gotcha:
      LaTeX isn't really that good on documents where you want some absolute positioning. It is not much easier to convert an invoice form from a pretty looking Excel sheet to a LaTeX source than to a series of GD primitives. What LaTeX would make easy are justified paragraphs, anti-aliased text and the like. But, e.g., LaTeX tables are pretty awkward and there's usually a good amount of hassle in trying to convert a big Excel table to a LaTeX table.
Re: Generating beautiful reports
by cjf (Parson) on Apr 09, 2002 at 09:36 UTC
      Oh, thanks, cjf! Too bad I didn't find that node via search. It has a good discussion but no solution, as far as I understand. My PNGs are nice :) They print okay and are viewable in all browsers. They are just too much trouble to create and PDFs (or PostScript, doesn't matter) are no difference :((( Our designer cannot point and click to create template which I would merge with data to produce real document.
Re: Generating beautiful reports
by simon.proctor (Vicar) on Apr 09, 2002 at 09:07 UTC
    Use a PDF generating module and/or program. There are a variety of commercial modules and programs available that you can use but if you can put up with little notices in footers then you can normally use these for free.

    A quick look through my bookmarks turned up PDFLib. Though I know there are many, many others. Google is your friend here.

    Generating a report as an image is not a good idea for many, many reasons not least of which are the ones you have already discovered. Your goal, then, is to automate the method of generating the report but if you are already doing this then you should just be able to plug in the PDF functionality right away and change the code generator.

    I've not played with anything strictly like this in the past but my instincts tell me you have two options. Either create a single script per report type or create a meta language (possibly XML like Docbook, possibly something else like TT) which can then be processed by your script. The latter option may be more useful to you as you only have one processor script and a single format.

    The advantage to the latter approach is that you have a nice, generic way of doing things. However it may be a little slower (well ok more than a little) than doing a specific program.

    Your other option, perhaps, is to interface with something like Jade and use XSL-FO to generate the report. Here you can either use the stuff from the Cocoon project or you can just interface with the command line tool. But this is probably not what you want.
      How would a PDF-generating lib make difference in this case? How is:
      my $pdf = new PDF::Create(...); my $root = $pdf->new_page('MediaBox' => [ 0, 0, 612, 792 ]); my $page = $root->new_page; $page->stringc($f2, 40, 306, 426, "PDF::Create");
      ...better or easier to handle than:
      $im = new GD::Image(100,100); $image->stringFT($color,$font,10,0,123,321,"GD")
        My post covered two topics using PDFs instead of images and potential options for making that generation easier. If you want a reasoned argument about why using PDFs would be better than images then I suggest you firstly do a super search and then, if not satsified, post a meditation on the matter. Its a bit OT so you may want to label it as such.

        As for the generation of the PDF being easier, I didn't specifically cover any particular method of code generation but considered it from a higher level. Ease is in the eye of the beholder. From a personal standpoint I'd either write a command line java tool using the Cocoon libraries for XSL-FO and build a docbook template. Or I would build a system that could automatically generate the right output code and then process that. The end result for both of these would be significantly simpler to use and maintain. But as you should know by now, theres more than one way to do it.

        Update In response to Kappas question (which may be below your node depth) I would personally go for an XML approach if I knew I was going to be deploying this system on a large number of projects. I would produce a template that had template toolkit processing instructions in it and would populate it from the variables returned from the CGI environment. For that I would use

        Once the template has been populated, I've then got a nice generic text representation of my data which I can process by passing this to my processing object. This processing object would, initially, use a Java based commandline tool with XSL-FO. This would allow me to have a demonstration system running quickly but I can then change the generation at a later stage by changing the processing object internals if I really need to. If speed was a requirement, I'd consider doing the PDF generation using the same library under Tomcat.

        I'd use the information from the Apache XML project to do it.

        Please note, this is just how I would do it and I've put it here cos I was asked specifically. I'm not saying this is the only way or the best way. Its just my way (till I see a better one!).

        HTH :)
Re: Generating beautiful reports
by dws (Chancellor) on Apr 09, 2002 at 16:21 UTC
    I've got a document form which must be filled with data entered through a web-form and then be presented alone on a page suitable for printing right from the browser.

    You have at least four options:

    1. Assume that people have an Acrobat reader installed with their browser, and serve up printable PDF. There's enough info in the links that people have provided above to work through the problems of generating PDF from Perl.

    2. Assume that people have a browser capable of understanding CSS, and generate your printable report using CSS to augment HTML.

    3. Assume that people have Microsoft office installed, and generate your printable report as either an Excel or Word document. This will require that your web server be IIS, and that the web server also have the necessary pieces of Office installed. Do a Super Search for Excel, and you'll find plenty of examples of how to generate and populate Excel files from Perl.

    4. Generate a printable image (GIF, PNG, or JPEG), using ImageMagik or GD. This give you maximal control on the server side, but will probably involve the maximal amount of work.
Re: Generating beautiful reports
by clintp (Curate) on Apr 09, 2002 at 17:20 UTC
    I've submitted a talk for YAPC (waiting for approval...) on generating reports from XML data in Perl for a variety of output formats (Excel, HTML, plaintext, PDF, etc...). Haven't considered a *graphics* format, but it wouldn't be hard.

    Laying out an human aesthetically pleasing report is not a trivial exercise as I found out. Once you factor in group, break, sort, total and everything else it's nightmarish.

    The architecture I've got is fairly intelligent and felxible, and so far has held up to months of pounding by a lot of customers and support people. It's pluggable so that new output formats are a snap to add, and the kind of data you feed it is unimportant -- we can run system reports or invoices through the exact same code.

    Bad news: the code is not open-source. The company paid a lot of money for it, and won't let the code out. It's a competative advantage right now for them not to release it. Good news: I'm allowed to discuss the architecture and design as much as I want as long as I don't give the code away.

    If you're interested I can give some details or an overview of how things are done. Of course, I'm not going to put a ton of work into documenting it until YAPC approves the talk. :)

      My question is this: how does your system generate report templates? Do you have a hand-crafted WYSIWYG tool?
Re: Generating beautiful reports
by Matts (Deacon) on Apr 09, 2002 at 14:47 UTC
    For your first problem, I'll advocate PDFLib, which will do the text blocks for you (and allow you to wrap text within them). Text blocks also allow you to build rudimentary tables quite easily (that's how I built table support into AxPoint).

    Unfortunately it can't really help you with converting a design to code - for that I guess you'd have to build some sort of description language like AxPoint (perhaps the code will help). In fact the AxPoint code is probably exactly what you need, modulo some fiddling around with page sizes and fonts. Then just describe your report in XML and SVG...

A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://157678]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2022-11-29 01:02 GMT
Find Nodes?
    Voting Booth?