Steve is correct, this may not scale well.... You may want to make your PDF generation asynchronous (perform the generation outside of scope of your app server). Partially for performance reasons, and especially for memory useage.
I have a secondary (asynchronous) process that is signaled to generate the pdf... it generates it... and signals back that the pdf is ready for use. The app then uses the code (see my other response) to load up the pdf and send it back. The best thing about this approach is your app server is not bogged down just because you are generating pdf's. It scales much better. Also you then have the option of serving the pdf back either through your app server or directly through an http server (which is much more efficient). I currently have sites serving it up (for different reasons) each way, and they both work well. Best of luck. -----Original Message----- From: Steve Yokanovich [mailto:[EMAIL PROTECTED] Sent: Friday, January 18, 2008 6:41 AM To: Turbine Users List Subject: Re: AW: Using Turbine's tools for assembling PDF output (using FOP): how to? 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] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
