Well, I've knocked up some stuff for real using iText now. The rose-tinted glasses are off for sure, but I have to say, it's a good solution.
Writing a long complex report with a lot of formatting is pretty dull, it must be said. But that's the nature of the beast, really - northing's going to make report generation exciting. iText does at least make it relatively easy to get exactly the result you need.
The mailing list, as I usually find in the open source world, pisses all over the "support" that you'll get from the proprietary world. So, a big thank you to Bruno Lowagie and Paulo Soares, not only for writing iText in the first place, but for their time over on itext-questions.
The code that you have to write is pretty ugly, I must say. It's really procedural, and it's long. There are a lot of repetitious sections that look like they could be refactored into methods to avoid code duplication, but that you find are different enough that you can't - at least, not without making the code really complex. And while the report generation code is long, it's also very simple; add a paragraph, add a table cell, add another table cell, and so on, and so on.
One thing I would like to be able to work out how to do is unit test. I already know that my domain objects work - they have their own unit test. So I really just need to make sure that the PDFs are generated correctly, and I can only do that by eye. Anyone have any good suggestions here?
Anyway, in short, I wouldn't hesitate to recommend iText over StyleReport or the like to anyone who can code.
Posted to Java by Simon Brunning at September 23, 2004 01:23 PMPerhaps an intermediate unit test would be to verify that the composite objects - paragraph, tables, sections, etc, are correctly linked together/set up.
That is, run the report file out in test mode, and verify that
(a) the right file name was produced and it contains a non-zero number of bytes, maybe even shell it into acrobat and check if no errors occur, and
(b) then inspect the objects created inside your class to see thet they have the right structure.
Might not be the best, but it will certainly be a start.
Posted by: Mark Matthews on September 23, 2004 01:37 PMDo you try the Form filling with itext
it rocks
;)
You should avoid testing iText itself I think, unless you have a seperate acceptance test. Therefore, you should test what you are passing to iText in the first place - does iText take XML as an input? If so, you could use XPath queries (XPath is built in to Java 1.4) to check the content of the code, or even simple string comparisons. The XPath queries will be less brittle than a simple text comparison, but might be more work (but also I suspect more maintainable).
Posted by: Sam Newman on September 23, 2004 03:40 PMYou don't really pass it anything except for chunks of string - you just call a bunch of iText classes. So, for example, I create a paragraph of mixed format text like so:
currentCell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(new Paragraph("(8)", FONT_BODY));
paragraph = new Paragraph();
paragraph.add(new Chunk("A separate Section B should be completed for each different ",
FONT_BODY));
paragraph.add(new Chunk("Currency", FONT_BODY_BOLD));
paragraph.add(new Chunk(
". Where the names of currencies are similar – for example US Dollars and Australian Dollars – these should be clearly stated. If it is unclear what currency your claim is in, your claim for voting purposes may be rejected in whole or in part.",
FONT_BODY));
currentCell.setHorizontalAlignment(Element.ALIGN_JUSTIFIED);
table.addCell(paragraph);
Well, there are two things you can test in that case
1.) That you are making the right iText calls based on program execution - so make sure your code calls addCell in the right places. For that you just have to Mock out the paragraph and replace some of your constructors with a factory.
2.) Just do manual acceptance tests on the reports.
I guess it depends on how many reports you have - if you have one or two then manual acceptance tests should be so bad. If you have loads though (or an overworked QA) the work to allow automated testing might be worth it.
Posted by: Sam Newman on September 23, 2004 04:27 PMEven simpler, just abstract out your use of iText altogether, then mock your abstraction when testing. Then you're not testing iText, but your use of iText, which is as it should be. I kind of meant that before, but wasn't very clear :-)
Posted by: Sam Newman on September 23, 2004 04:28 PM"And while the report generation code is long, it's also very simple"... there's always the Ghetto mini-pattern for dealing with that. And if it's a pattern, it has to be good...
http://fishbowl.pastiche.org/2003/05/28/the_ghetto_minipattern
Half my bloody project is a Ghetto...
Posted by: Simon Brunning on September 24, 2004 08:44 AMHave you thought about using Apache FOP and XSL-FO for reporting?
Posted by: Ben Galbraith on September 24, 2004 04:11 PM