You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Volker Lamp <vo...@gmail.com> on 2022/01/27 07:19:06 UTC

Apache FOP integration

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-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Apache FOP integration

Posted by Ben Weidig <be...@netzgut.net>.
Hi Volker,

can't help with FOP, but we're using JasperReport.

With the HTML-to-PDF path it's often quite hard to get the layout right.
That's why Jasper uses its own WYSIWYG designer, which isn't the nicest
tool but it gets the job done.
You can include variables, link other Jasper-files, loop through stuff...

For  other PDF operations (e.g. merging) we use PDFBox.

Cheers,
Ben



On Thu, Jan 27, 2022 at 10:03 AM Numa Schmeder <nu...@dfacto.ch> wrote:

> Hello,
>
> I tried all solutions, and I finally use iText that converts an html file
> into PDF. You can tweak iText with specific css rules for page breaks etc..
> This solution is quicker and easier to have a nice look and feel than FOP.
>
>
>   <http://www.dfacto.ch/>       Numa Schmeder    www.dfacto.ch  <
> http://www.dfacto.ch/>
> NUMA@DFACTO.CH <ma...@dfacto.ch>   |   M +41 79 538 30 01
>
> DIGITAL STRATEGY   |   DESIGN   |   DEVELOPMENT
>
>
>
>
> > Le 27 janv. 2022 à 08:19, Volker Lamp <vo...@gmail.com> a écrit :
> >
> > 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-unsubscribe@tapestry.apache.org
> > For additional commands, e-mail: users-help@tapestry.apache.org
> >
>
>

Re: Apache FOP integration

Posted by Numa Schmeder <nu...@dfacto.ch>.
Hello,

I tried all solutions, and I finally use iText that converts an html file into PDF. You can tweak iText with specific css rules for page breaks etc..
This solution is quicker and easier to have a nice look and feel than FOP.


  <http://www.dfacto.ch/>	Numa Schmeder    www.dfacto.ch  <http://www.dfacto.ch/>
NUMA@DFACTO.CH <ma...@dfacto.ch>   |   M +41 79 538 30 01 

DIGITAL STRATEGY   |   DESIGN   |   DEVELOPMENT


 

> Le 27 janv. 2022 à 08:19, Volker Lamp <vo...@gmail.com> a écrit :
> 
> 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-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 


Re: Apache FOP integration

Posted by Ivano Luberti <lu...@archicoop.it.INVALID>.
Forgot to say I use pdfbox for pdf and zxing for QRCodes

Il 28/01/2022 08:28, Ivano Luberti ha scritto:
> On a related argument, how do you print QRCodes or barcodes on the pdf?
>
> Il 27/01/2022 14:52, Ilya Obshadko ha scritto:
>> 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<vo...@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-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail:users-help@tapestry.apache.org
>>>
>>>
-- 

Archimede Informatica tratta i dati personali in conformità a quanto
stabilito dal Regolamento UE n. 2016/679 (GDPR) e dal D. Lgs. 30 giugno 
2003 n. 196
per come modificato dal D.Lgs. 10 agosto 2018 n. 101.
Informativa completa 
<http://www.archicoop.it/fileadmin/pdf/InformativaTrattamentoDatiPersonali.pdf>

dott. Ivano Mario Luberti

Archimede Informatica società cooperativa a r. l.
Via Gereschi 36, 56127 Pisa

tel.: +39 050/580959 | fax: +39 050/8932061

web: www.archicoop.it
linkedin: www.linkedin.com/in/ivanoluberti
facebook: www.facebook.com/archimedeinformaticapisa/

Re: Apache FOP integration

Posted by Ivano Luberti <lu...@archicoop.it.INVALID>.
On a related argument, how do you print QRCodes or barcodes on the pdf?

Il 27/01/2022 14:52, Ilya Obshadko ha scritto:
> 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<vo...@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-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail:users-help@tapestry.apache.org
>>
>>
-- 

Archimede Informatica tratta i dati personali in conformità a quanto
stabilito dal Regolamento UE n. 2016/679 (GDPR) e dal D. Lgs. 30 giugno 
2003 n. 196
per come modificato dal D.Lgs. 10 agosto 2018 n. 101.
Informativa completa 
<http://www.archicoop.it/fileadmin/pdf/InformativaTrattamentoDatiPersonali.pdf>

dott. Ivano Mario Luberti

Archimede Informatica società cooperativa a r. l.
Via Gereschi 36, 56127 Pisa

tel.: +39 050/580959 | fax: +39 050/8932061

web: www.archicoop.it
linkedin: www.linkedin.com/in/ivanoluberti
facebook: www.facebook.com/archimedeinformaticapisa/

Re: Apache FOP integration

Posted by Ilya Obshadko <il...@gmail.com>.
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 <vo...@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-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

-- 
Ilya Obshadko

Re: Apache FOP integration

Posted by D Tim Cummings <ti...@triptera.com.au.INVALID>.
iText is still open source but the license has changed.

OpenPDF is the LGPL and MPL fork of iText from before the license 
changed to the AGPLv3. If you want to use iText with the free AGPLv3 
license then you need to open source your software as well. 
Alternatively iText has commercial licenses.

OpenPDF uses Gnu Lesser General Public License and Mozilla Public 
License so you can use it for free without open sourcing your code. I 
now use OpenPDF.

https://github.com/LibrePDF/OpenPDF


On 28/1/22 19:31, Ivano Luberti wrote:
> BTW Itext is no more open source, right?
>
> Il 28/01/2022 10:29, Volker Lamp ha scritto:
>> Hello everybody
>>
>> Thank you all for your responses. Very useful to learn various libraries
>> are being used in Tapestry apps. iText, JasperReport, PDFBox, and FOP.
>>
>> We'll go with Apache FOP in our project as it turns out we can re-use 
>> some
>> FOP stylesheets from another project.
>>
>> A Tapestry FOP module would be useful for configuring FOP in a Tapestry
>> manner. Likewise, it would include a service that would hold the 
>> FopFactory
>> instance which (according to the FOP docs) is supposed to be reused 
>> if one
>> plans to render multiple documents during a JVM's lifetime.
>>
>> As Ilya described, a Tapestry FOP module is, however, not necessary. One
>> can just read a config file and configure FOP programmatically.
>>
>> Again, thank you all for your thoughts. Have a nice weekend.
>>
>> Cheers,
>>
>> Volker
>>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Apache FOP integration

Posted by Ivano Luberti <lu...@archicoop.it.INVALID>.
BTW Itext is no more open source, right?

Il 28/01/2022 10:29, Volker Lamp ha scritto:
> Hello everybody
>
> Thank you all for your responses. Very useful to learn various libraries
> are being used in Tapestry apps. iText, JasperReport, PDFBox, and FOP.
>
> We'll go with Apache FOP in our project as it turns out we can re-use some
> FOP stylesheets from another project.
>
> A Tapestry FOP module would be useful for configuring FOP in a Tapestry
> manner. Likewise, it would include a service that would hold the FopFactory
> instance which (according to the FOP docs) is supposed to be reused if one
> plans to render multiple documents during a JVM's lifetime.
>
> As Ilya described, a Tapestry FOP module is, however, not necessary. One
> can just read a config file and configure FOP programmatically.
>
> Again, thank you all for your thoughts. Have a nice weekend.
>
> Cheers,
>
> Volker
>
-- 

Archimede Informatica tratta i dati personali in conformità a quanto
stabilito dal Regolamento UE n. 2016/679 (GDPR) e dal D. Lgs. 30 giugno 
2003 n. 196
per come modificato dal D.Lgs. 10 agosto 2018 n. 101.
Informativa completa 
<http://www.archicoop.it/fileadmin/pdf/InformativaTrattamentoDatiPersonali.pdf>

dott. Ivano Mario Luberti

Archimede Informatica società cooperativa a r. l.
Via Gereschi 36, 56127 Pisa

tel.: +39 050/580959 | fax: +39 050/8932061

web: www.archicoop.it
linkedin: www.linkedin.com/in/ivanoluberti
facebook: www.facebook.com/archimedeinformaticapisa/

Re: Apache FOP integration

Posted by Volker Lamp <vo...@gmail.com>.
Hello everybody

Thank you all for your responses. Very useful to learn various libraries
are being used in Tapestry apps. iText, JasperReport, PDFBox, and FOP.

We'll go with Apache FOP in our project as it turns out we can re-use some
FOP stylesheets from another project.

A Tapestry FOP module would be useful for configuring FOP in a Tapestry
manner. Likewise, it would include a service that would hold the FopFactory
instance which (according to the FOP docs) is supposed to be reused if one
plans to render multiple documents during a JVM's lifetime.

As Ilya described, a Tapestry FOP module is, however, not necessary. One
can just read a config file and configure FOP programmatically.

Again, thank you all for your thoughts. Have a nice weekend.

Cheers,

Volker

Re: Apache FOP integration

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
On Thu, Jan 27, 2022 at 2:55 PM Jens Breitenstein <jb...@j-b-s.de> wrote:

> The only interaction with Tapestry is the StreamResponse from an
> EventHandler to the client.


Friendly reminder you can return StreamResponse from a page's onActivate()
method too.

--
Thiago

Re: Apache FOP integration

Posted by Jens Breitenstein <jb...@j-b-s.de>.
Hi Volker!

The only interaction with Tapestry is the StreamResponse from an EventHandler to the client. So are you asking for this part or is it more general „how do I create pdfs using fob“ which is honestly not related to tapestry?

Von meinem iPhone gesendet

> Am 27.01.2022 um 08:19 schrieb Volker Lamp <vo...@gmail.com>:
> 
> 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-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org