I've been using FOP to generate PDFs from the Tapestry application for quite a few years. There's nothing specific to Tapestry, you just create a "rendering service" which does all the processing for you. The only caveat I remember is using Saxon instead of Xalan for running initial transformation (it's *much* faster and has a lower memory footprint).
This is the entire code responsible for producing PDF: // 1) create transformer if (fopFactory == null) { fopFactory = FopFactory.newInstance(); final URL fopConfigResource = getClass().getClassLoader().getResource(FOP_CONFIG_URL); final URL fontsDirectoryResource = getClass().getClassLoader().getResource("your/font/package"); assert fopConfigResource != null && fontsDirectoryResource != null; fopFactory.setUserConfig(fopConfigResource.toExternalForm()); fopFactory.getFontManager().setFontBaseURL(fontsDirectoryResource.toExternalForm()); } // use Saxon instead of Xalan System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl"); TransformerFactory transformerFactory = TransformerFactory.newInstance(); // register Saxon extension functions TransformerFactoryImpl saxonFactory = (TransformerFactoryImpl) transformerFactory; Configuration configuration = saxonFactory.getConfiguration(); extensionFunctions.getAvailableFunctions(activeLocale).forEach(configuration::registerExtensionFunction); // initialize transformer Source template = new StreamSource(templateStream); Transformer transformer = transformerFactory.newTransformer(template); // 2) serialize object to xml File tmpFile = File.createTempFile("fop", ".xml"); FileOutputStream marshallerOutputStream = new FileOutputStream(tmpFile); JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass()); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(object, marshallerOutputStream); marshallerOutputStream.close(); logger.info("marshaller result: {}, {} bytes", tmpFile, tmpFile.length()); // 3) perform transformation FileInputStream fopInputStream = new FileInputStream(tmpFile); FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); foUserAgent.setProducer("producer name"); foUserAgent.setCreationDate(new Date()); Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, outputStream); Source xmlSource = new StreamSource(fopInputStream); Result pdfResult = new SAXResult(fop.getDefaultHandler()); transformer.transform(xmlSource, pdfResult); fopInputStream.close(); if (!tmpFile.delete()) logger.warn("unable to remove temporary file {}", tmpFile); There's basically nothing else. After processing, *outputStream* will contain your PDF. Note that my example includes: - using custom fonts (you probably don't need this); - using custom extension functions for Saxon (you probably don't need this either). Otherwise it's pretty much straightforward. On Thu, Jan 27, 2022 at 9:19 AM Volker Lamp <volker.l...@gmail.com> wrote: > Hello Tapestry users, > > Our Tapestry webapp needs to generate printable PDFs including user input. > We are currently looking at using Apache FOP for that. > > Has anyone integrated FOP in their Tapestry webapp and perhaps a Tapestry > module to share? > > Suggestions for other approaches are also welcome. > > Cheers, > > Volker > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org > For additional commands, e-mail: users-h...@tapestry.apache.org > > -- Ilya Obshadko