Building A SCRUM StoryCards Generator - Part III

Pimp an Apache FOP example and use an XSL-FO style sheet to render the PDF generated by the SCRUM StoryCards Generator. In Part I we squeezed raw data out of an Excel sheet containing the SCRUM story cards. With a little bit of groovy this raw data got converted to XML. In the 2nd Part we created the XML needed as input for our PdfGenerator. In this third part we will pimp an Apache FOP example and use an XSL-FO style sheet to render the PDF generated by the SCRUM StoryCards Generator. Browsing the Apache FOP samples this one sounds like we are almost done ExampleXML2PDF.java. ;-) I'll strip the example code to a bare minimum - now it reveals where the music plays:

/**
  * This class demonstrates the conversion of an XML file to PDF using
  * JAXP (XSLT) and FOP (XSL-FO).
  */
public class ExampleXML2PDF {

  public static void main(String[] args) {
    ...
    FopFactory fopFactory = FopFactory.newInstance();
    FOUserAgent foUserAgent = fopFactory.newFOUserAgent();

    try {
      Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, pdfFile);

      TransformerFactory factory = TransformerFactory.newInstance();
      Transformer transformer = factory.newTransformer(new StreamSource(xsltFile));
      transformer.setParameter("versionParam", "2.0");

      Source src = new StreamSource(xmlFile);
      Result res = new SAXResult(fop.getDefaultHandler());
      transformer.transform(src, res);
    } finally {
      pdfFile.close();
    }  
  ...

As the name promises the formular is easy: XML + XSL-FO = PDF A few changes and we have a nice reusable OSGi service converting XML into PDF:

public class PdfGeneratorImpl implements PdfGenerator {

  @Override
  public byte[] generatePdf(byte[] xmlFile, byte[] xsltFile) {
    return generatePdf(new ByteArrayInputStream(xmlFile), new ByteArrayInputStream(xsltFile));
  }

  @Override
  public byte[] generatePdf(InputStream xmlFile, InputStream xsltFile) {
    try {
      return generatePdfWithFop(xmlFile, xsltFile);
    } catch (Exception e) {
    ...
    }
  }

  private byte[] generatePdfWithFop(InputStream xmlFile, InputStream xsltFile) throws Exception {

    FopFactory fopFactory = FopFactory.newInstance();
    FOUserAgent foUserAgent = fopFactory.newFOUserAgent();

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try {
      Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);

      TransformerFactory factory = TransformerFactory.newInstance();
      Transformer transformer = factory.newTransformer(new StreamSource(xsltFile));

      transformer.setParameter("versionParam", "2.0");
      Result res = new SAXResult(fop.getDefaultHandler());

      transformer.transform(new StreamSource(xmlFile), res);
      return out.toByteArray();
    } finally {
      out.close();
    }
  }
}

To export the PdfGenerator as OSGi service - yes right we use a spring-osgi one-liner :) With this single line we keep the PdfGenerator free from dependencies to Spring and OSGi.

<osgi:service id="pdfGenerator" interface="de.datenkollektiv.util.fop.PdfGenerator" />

In the roundup we bring the PdfGenerator into the web using spring-mvc...

Building A SCRUM StoryCards Generator - Part I

Building A SCRUM StoryCards Generator - Part II

Building A SCRUM StoryCards Generator - Part III

Building A SCRUM StoryCards Generator - Roundup


Header cover Photo by G. Crescoli