I have an object PDFData
with some attributes. One of them are Arraylist
: One with String
and another with a custom object (with some primitive attributes).
I need to render both list with a XSLT for create a PDF file with Apache-FOP. I've googled multiple ways to solve it but I have not found anything.
My class for render the PDF is:
public class PDFRender {
public static final String SUMMARY_REPORT_XSL = "summary_report.xsl";
//private final Logger log = LoggerFactory.getLogger(getClass());
public ByteArrayInputStream createPDFFile(ByteArrayOutputStream xmlSource) throws IOException {
ByteArrayInputStream inputStream = null;
InputStream template = Thread.currentThread().getContextClassLoader().getResourceAsStream(SUMMARY_REPORT_XSL);
StreamSource transformSource = new StreamSource(template);
FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
ByteArrayOutputStream pdfOutStream = new ByteArrayOutputStream();
StreamSource source = new StreamSource(new ByteArrayInputStream(xmlSource.toByteArray()));
Transformer xslfoTransformer;
try {
TransformerFactory transfact = TransformerFactory.newInstance();
xslfoTransformer = transfact.newTransformer(transformSource);
Fop fop;
try {
fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, pdfOutStream);
// Resulting SAX events (the generated FO) must be piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing
try {
xslfoTransformer.transform(source, res);
inputStream = new ByteArrayInputStream(pdfOutStream.toByteArray());
} catch (TransformerException e) {
String msg = "Caught exception transforming source to generate PDF";
//log.error(msg, e);
throw new RuntimeException(msg, e);
}
} catch (FOPException e) {
String msg = "Caught FOP exception generating PDF";
//log.error(msg, e);
throw new RuntimeException(msg, e);
}
} catch (TransformerConfigurationException e) {
String msg = "Caught exception transforming source to generate PDF";
//log.error(msg, e);
throw new RuntimeException(msg, e);
}
return inputStream;
}
public ByteArrayOutputStream getXMLSource(PDFData data) throws Exception {
JAXBContext context;
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
try {
context = JAXBContext.newInstance(PDFData.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(data, outStream);
} catch (JAXBException e) {
String msg = "Caught exception marshalling application to generate PDF";
//log.error(msg, e);
throw new RuntimeException(msg, e);
}
return outStream;
}
}
PDFData
is as follows:
@XmlRootElement(name = "PDFData")
public class PDFData {
public String clientName;
public String clientProfile;
public String clientLang;
public URL clientLogo;
public ObjectId verificationId;
public String verificationCountry;
public String verificationDocumentType;
public List<Page> verificationPages = new ArrayList<>();
public String verificationTemplateName;
public Long verificationTime;
public List<ActionResult> verificationActions = new ArrayList<>();
public List<String> verificationMrz = new ArrayList<>();
/* ... */
}
My XSLT has no relevance because I don't have anything yet about it. Maybe just for comment it, is relevant that when I have to access to some attribute (for example clientName
), I do it as follows:
<xsl:when test="clientName = 'Test client'">Orange</xsl:when>
I am using XSLT 1.1 with Jar dependency 'org.apache.xmlgraphics:fop:1.0'
(version 1.1. dependencies don't load with gradle, I don't know why).
Summary: Someone knows how to render a Java List to a XSL template?
Thanks in advance!
UPDATE 1: Well... I have found a solution here. It solves one of my problems. I can get all the values. But now I have another problem. How can I loop over them?
UPDATE 2: @KevinBrown thinks that my XSLT could be important, so here is my XSLT:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="PDFData">
<!-- Define variables -->
<xsl:variable name="green" select="'green'" />
<xsl:variable name="red" select="'#90AB76'" />
<xsl:variable name="dark_gray" select="'#3C3F41'" />
<xsl:variable name="light_gray" select="'#CCCCCC'" />
<xsl:variable name="black" select="'#3D6B5C'" />
<xsl:variable name="labelHeader">
<xsl:choose>
<xsl:when test="clientName = 'Test client'">Orange</xsl:when>
<xsl:otherwise>Résultat Global: Le document est jugé rejecte</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="A4"
page-height="297mm"
page-width="210mm"
margin-bottom="2.5cm">
<fo:region-body margin-bottom="4mm"/>
<fo:region-after extent="13mm" display-align="after"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="xsl-region-body">
<fo:block font-family="any"
font-size="10pt">
<!-- Header -->
<fo:table table-layout="fixed"
width="100%"
margin-bottom="1.5em"
font-size="1.5em"
font-weight="bold"
background-color="{$dark_gray}">
<fo:table-column column-number="1" column-width="28%"/>
<fo:table-column column-number="2" column-width="10%"/>
<fo:table-column column-number="3" column-width="40%"/>
<fo:table-column column-number="4" column-width="1%"/>
<fo:table-column column-number="5" column-width="15%"/>
<fo:table-column column-number="6" column-width="1%"/>
<fo:table-body>
<!-- Empty -->
<fo:table-row height="2em">
<fo:table-cell>
<fo:block>
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row color="{$light_gray}">
<!-- Logo -->
<fo:table-cell>
<fo:block margin-left="1mm" font-weight="bold" text-align="center">
</fo:block>
</fo:table-cell>
<!-- Company name -->
<fo:table-cell number-columns-spanned="2" background-color="{$light_gray}" color="{$dark_gray}" >
<fo:block margin-left="1mm" margin="3mm 2mm 3mm 2mm" font-weight="bold">
<xsl:value-of select="$labelHeader" />
</fo:block>
</fo:table-cell>
<!-- Empty -->
<fo:table-cell>
<fo:block margin-left="1mm" font-weight="bold">
</fo:block>
</fo:table-cell>
<!-- Result -->
<fo:table-cell background-color="{$light_gray}" color="{$dark_gray}" >
<fo:block margin-left="1mm"
font-weight="bold"
font-size="0.9em"
text-align="center">Resultat</fo:block>
<fo:block margin-left="1mm"
font-weight="bold"
font-size="0.9em"
text-align="center"
color="{$green}">Positif</fo:block>
</fo:table-cell>
<!-- Empty -->
<fo:table-cell>
<fo:block margin-left="1mm" font-weight="bold">
</fo:block>
</fo:table-cell>
</fo:table-row>
<!-- Empty -->
<fo:table-row height="2em">
<fo:table-cell>
<fo:block>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
<!-- Verification results -->
<fo:table table-layout="fixed"
width="100%"
margin-bottom="0.5em"
margin-left="1em"
margin-right="1em"
font-size="1em">
<fo:table-column column-number="1" column-width="25%"/>
<fo:table-column column-number="2" column-width="25%"/>
<fo:table-column column-number="3" column-width="25%"/>
<fo:table-column column-number="4" column-width="25%"/>
<fo:table-body>
<!-- Header row -->
<fo:table-row height="0.1em">
<fo:table-cell number-columns-spanned="4"
font-weight="bold"
text-align="left"
font-size="1.3em"
padding-bottom="0.5em">
<fo:block>Résultat des vérifications:</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row height="0.1em">
<fo:table-cell font-weight="bold"
text-align="left"
font-size="1.1em">
<fo:block>Moment de réception:</fo:block>
</fo:table-cell>
<fo:table-cell text-align="left"
font-size="1em">
<fo:block>25-06-2015 15:38:14</fo:block>
</fo:table-cell>
<fo:table-cell font-weight="bold"
text-align="left"
font-size="1.1em">
<fo:block>Moment de envoi:</fo:block>
</fo:table-cell>
<fo:table-cell text-align="left"
font-size="1em">
<fo:block>25-06-2015 15:38:47</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row height="0.1em">
<fo:table-cell font-weight="bold"
text-align="left"
font-size="1.1em">
<fo:block>Durée de vérification:</fo:block>
</fo:table-cell>
<fo:table-cell text-align="left"
font-size="1em">
<fo:block>25s 187ms</fo:block>
</fo:table-cell>
<fo:table-cell font-weight="bold"
text-align="left"
font-size="1.1em">
<fo:block>Modèle de document:</fo:block>
</fo:table-cell>
<fo:table-cell text-align="left"
font-size="1em">
<fo:block>Carte d'identité</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell number-columns-spanned="4" height="0.7em">
<fo:block></fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row height="0.1em">
<fo:table-cell font-weight="bold"
text-align="left"
font-size="1.1em">
<fo:block>Vérifications positives:</fo:block>
</fo:table-cell>
<fo:table-cell text-align="left"
font-size="1em">
<fo:block>20</fo:block>
</fo:table-cell>
<fo:table-cell font-weight="bold"
text-align="left"
font-size="1.1em">
<fo:block>Total des vérifications:</fo:block>
</fo:table-cell>
<fo:table-cell text-align="left"
font-size="1em">
<fo:block>20</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell number-columns-spanned="4" height="1.5em">
<fo:block></fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
<!-- Line separator 1 -->
<fo:table table-layout="fixed"
width="auto"
margin-bottom="1.5em"
margin-left="0.5em"
margin-right="0.5em"
font-size="1.5em"
font-weight="bold"
border-top="1px solid {$dark_gray}">
<fo:table-column column-number="1" column-width="100%"/>
<fo:table-body>
<!-- Empty -->
<fo:table-row height="0.1em">
<fo:table-cell>
<fo:block>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
<!-- MRZ -->
<fo:table table-layout="fixed"
width="auto"
margin-bottom="0.5em"
margin-left="1em"
margin-right="1em"
font-size="1em"
font-family="'arial'"
text-align="center">
<fo:table-column column-number="1" column-width="20%"/>
<fo:table-column column-number="2" column-width="60%" border="2px solid {$dark_gray}"/>
<fo:table-column column-number="3" column-width="20%"/>
<fo:table-body>
<!-- Header row -->
<fo:table-row height="0.1em">
<fo:table-cell height="1.5em">
<fo:block></fo:block>
</fo:table-cell>
<fo:table-cell number-columns-spanned="1"
font-weight="bold"
text-align="left"
font-size="1.3em"
padding="0.5em"
text-align-last="center"
font-family="monospace">
<fo:block>IDFRABEN<HAMOUDA<<<<<<<<<<<<<<783030</fo:block>
<fo:block>1310783007866MAHJOUB<<<<<<<8202109M9</fo:block>
</fo:table-cell>
<fo:table-cell height="1.5em">
<fo:block></fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
<!-- Champs veriifications -->
<fo:table table-layout="fixed"
width="100%"
margin-bottom="0.5em"
margin-left="1em"
margin-right="1em"
font-size="1em">
<fo:table-column column-number="1" column-width="50%" border-right="1px solid {$dark_gray}"/>
<fo:table-column column-number="2" column-width="50%"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell number-columns-spanned="2" height="1.5em">
<fo:block>
<!-- HERE COMES ONE OF THE LISTS -->
</fo:block>
</fo:table-cell>
</fo:table-row>
<!-- Header row -->
<fo:table-row height="0.1em">
<fo:table-cell number-columns-spanned="2"
font-weight="bold"
text-align="left"
font-size="1.3em"
padding-bottom="0.5em">
<fo:block>Vérifications des champs de la ZLA positives:
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row height="0.1em">
<fo:table-cell text-align="left"
font-size="1em">
<fo:block><!-- HERE COMES THE ANOTHER LIST --></fo:block>
</fo:table-cell>
<fo:table-cell text-align="left"
font-size="1em">
<fo:block>25-06-2015 15:38:14</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
<!-- Visual verifications -->
<fo:table table-layout="fixed"
width="100%"
margin-bottom="0.5em"
margin-left="1em"
margin-right="1em"
font-size="1em">
<fo:table-column column-number="1" column-width="50%" border-right="1px solid {$dark_gray}"/>
<fo:table-column column-number="2" column-width="50%"/>
<fo:table-body>
<!-- Header row -->
<fo:table-row height="0.1em">
<fo:table-cell number-columns-spanned="2"
font-weight="bold"
text-align="left"
font-size="1.3em"
padding-bottom="0.5em">
<fo:block>ZLA-Vérifications visuelles positives:</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row height="0.1em">
<fo:table-cell text-align="left"
font-size="1em">
<fo:block>Moment de réception:</fo:block>
</fo:table-cell>
<fo:table-cell text-align="left"
font-size="1em">
<fo:block>25-06-2015 15:38:14</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell number-columns-spanned="2" height="1.5em">
<fo:block></fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
<!-- Line separator -->
<fo:table table-layout="fixed"
width="auto"
margin-bottom="1.5em"
margin-left="0.5em"
margin-right="0.5em"
font-size="1.5em"
font-weight="bold"
border-top="1px solid {$dark_gray}">
<fo:table-column column-number="1" column-width="100%"/>
<fo:table-body>
<!-- Empty -->
<fo:table-row height="0.1em">
<fo:table-cell>
<fo:block>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
<!-- Front image (if there is only one image, will be here -->
<!-- Back image -->
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
UPDATE 3: Woohooo!! This weekend I have tried some solutions and I have obtained a loop:
<xsl:for-each select="verificationMrz">
<xsl:variable name="i" select="position()" />
<xsl:value-of select="$i" />
</xsl:for-each>
Ok, cool! But when I try to access the list with the index (<xsl:value-of select="verificationMrz[$i]" />
) I don't get any value. I have checked if the list is not empty with <xsl:value-of select="verificationMrz[1]" />
and it works nice. So I think my problem is with variable i
, maybe data type? I don't know...