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]