We have a solution that sounds similar. We are not a high volume site so I am not sure how scalable this is since it creates a new Fop with each request. We extended VelocityOnlyLayout to create a PdfLayout:

public class PdfLayout extends VelocityOnlyLayout {

    FopFactory fopFactory = FopFactory.newInstance();
    TransformerFactory tFactory = TransformerFactory.newInstance();
    Log logger = LogFactory.getLog(PdfLayout.class);
    public void doBuild(RunData data) throws Exception {


        /* Screen string will store the XSL-FO */
        String screenString = "";

        /*
         * First, generate the screen and put the results into a string
        */
ConcreteElement results = ScreenLoader.getInstance().eval(data, data.getScreen());
        if (results != null)
            screenString = results.toString();


        /**
         * Get the response object and set content type for PDF
         */

        HttpServletResponse response = data.getResponse();
        ByteArrayOutputStream out = new ByteArrayOutputStream();


        /**
         * Get a reader and instantiate the PDF Driver
         */
        StringReader reader = new StringReader(screenString);

        Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);



        try {

            /**
             * Render the document and write to the response
             */

            Source source = new StreamSource(reader);
            Result res = new SAXResult(fop.getDefaultHandler());
            Transformer transformer = tFactory.newTransformer();
            transformer.transform(source, res);

            byte[] byteContent = out.toByteArray();
            response.setContentType("application/pdf");
            response.setContentLength(byteContent.length);
            response.getOutputStream().write(byteContent);
            response.getOutputStream().flush();


        } catch (IllegalArgumentException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        } catch (TransformerException e) {
// Attempt to send the XSL-FO back to the browser for troubleshooting.
                response.setContentType("text/xml");
                PrintWriter writer = response.getWriter();
                writer.print(screenString.toString());
                writer.flush();
                out.close();
logger.error("FOP Exception in PDFLayout "+ e.getMessage());
        } finally {
            out.close();
        }




    }

}

Here is our PdfScreen:

/**
     * This screen incorporates the security function (isAuthorized)
* from VelocitySecureScreen, the only difference being the getLayout method, which returns PdfLayout if the user is authenticated.
     * See PdfLayout for the actual rendering of the PDF document
     */
public class PdfScreen extends VelocitySecureScreen {

    public String getLayout(RunData data) {

        boolean ok = false;
        String rv = null;

        try {
            ok = this.isAuthorized(data);
        } catch (Exception e) {
        }

        if (ok) {
            rv = "PdfLayout";
        } else {
            rv = "LoginLayout";
            data.setLayoutTemplate("/Login.vm");
        }

        return rv;

    }


}


Now whenever we need a PDF we extend PdfScreen and create the xsl-fo template.

Let me know if this is what you were looking for.

Steve Yokanovich



Alexander Zimmer wrote:
Thank you both for your answers. Anyway, I just would like to stress that the conversion FO->PDF and the streaming (via a RawScreen-like Screen) is not a problem and is already solved. What I do not know (yet) is, how I can use Velocity plus all the nice Turbine pull tools for the Velocity template to assemble the FO input, such a template would look just like this (as you can see, a valid FO file, except the VTL sequences, which should be taken care of by Velocity):
<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format";>
  <fo:layout-master-set>
    <fo:simple-page-master master-name="simpleA4" page-height="29.7cm" page-width="21cm" margin-top="2cm" 
margin-bottom="2cm" margin-left="2cm" margin-right="2cm">
      <fo:region-body/>
    </fo:simple-page-master>
  </fo:layout-master-set>
  <fo:page-sequence master-reference="simpleA4">
    <fo:flow flow-name="xsl-region-body">
      <fo:block>Hello World, my name is $!{name}!</fo:block>
      #foreach ($entry in $names)
        <fo:block>Next name: $entry.Firstname $entry.Lastname</fo:block>
      #end
    </fo:flow>
  </fo:page-sequence>
</fo:root>
How can I use template functionality? The problem involved are:
1. I want to use the Velocity engine and capture its output in a 
String/ByteArray. The output will be a valid FO file.
2. I want to be able to use all (at least: some) pull tools Turbine provides 
for screen templates
I think that I've solved the other problems (how to do the streaming, how to 
convert into PDF, ...).
I try to dive into the VelocityOnlyLayout (as Peter Courcoux pointed out), but 
if you have additional clues for me, I would be very happy to hear from you!

Cheers,
Alex


-----Ursprüngliche Nachricht-----
Von: Jeffery Painter [mailto:[EMAIL PROTECTED] Gesendet: Freitag, 18. Jänner 2008 15:21
An: Alexander Zimmer
Betreff: Re: Using Turbine's tools for assembling PDF output (using FOP): how 
to?


I haven't looked at this stuff in quite some time, but I had posted
a PdfScreen that might give you a start on how to do things.

http://kiasoft.com/opensource/PdfScreen.java

I was using it with the iText library back in the day, but I believe your
options are more varied now.

http://www.lowagie.com/iText/

good luck!


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to