[Métodos] Generar tabla en PDF con xstream y xls en Java


Imaginemos que contamos con un xml de la siguiente manera:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="UTF-8"?>
<list>
  <juego>
    <nombre>Rise Of The Tomb Raider</nombre>
    <desarrolladora>Square Enix</desarrolladora>
    <distribuidora>Crystal Dinamics</distribuidora>
    <plataformas>PC, PS4, XBOX ONE XBOX 360</plataformas>
    <genero>Accion Aventura </genero>
    <fechaLanzamiento>2015-11-10 03:00:00.0 UTC</fechaLanzamiento>
  </juego>
  <juego>
    <nombre>Far Cry Primal</nombre>
    <desarrolladora>Ubisoft Montreal</desarrolladora>
    <distribuidora>Ubisoft</distribuidora>
    <plataformas>PC, PS4, XBOX ONE</plataformas>
    <genero>Accion Aventura Mundo Abierto </genero>
    <fechaLanzamiento>2016-02-23 03:00:00.0 UTC</fechaLanzamiento>
  </juego>
  <juego>
    <nombre>Resident Evil 7 BioHazard</nombre>
    <desarrolladora>Capcom</desarrolladora>
    <distribuidora>Capcom</distribuidora>
    <plataformas>PC, PS4, XBOX ONE</plataformas>
    <genero>Survival Horror</genero>
    <fechaLanzamiento>2017-01-24 03:00:00.0 UTC</fechaLanzamiento>
  </juego>
</list>

Entonces la idea seria poder generar un tabla, similar a las HTML, para poder asemejar cada etiqueta juego como un columna de nuestra tabla.
La sintaxis a usar para una tabla es:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<fo:table border="solid">
    <!-- declarar aqui las columnas que sean necesarias -->
    <fo:table-column column-width="30mm" />
    <!-- declaramos un cabecera -->
    <fo:table-header>
        <fo:table-row>
            <fo:table-cell>
                <fo:block font-weight="bold">Titulo de la columna</fo:block>
            </fo:table-cell>
        </fo:table-row>
    </fo:table-header>
    <!-- declaramos el cuerpo de la tabla -->
    <fo:table-body>
        <fo:table-row>
            <fo:table-cell>
                <fo:block>
                    <xsl:text>contenido de la celda</xsl:text>
                </fo:block>
            </fo:table-cell>
        </fo:table-row>
    </fo:table-body>
</fo:table>

    Es muy importante respetar la secuencia de etiqueta
  • <table-body></table-body>
  • <table-row></table-row>
  • <table-cell></table-cell>
  • <fo-block></fo-block>
  • Ya que de lo contrario, el transformador no entenderá y no generará el reporte

Para poder iterar sobre todas las etiquetas 'juego' vamos a hacer uso del tag <xsl:for-each select="list/juego">, 'seleccionando' a list y por cada juego:

1
2
3
<xsl:for-each select="/">
    <!-- aqui se repite por cada elemento -->
</xsl:for-each>

El XSL

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output method="xml" indent="yes" />
    <xsl:template match="/">
        <fo:root>
            <fo:layout-master-set>
                <fo:simple-page-master master-name="A4-portrait" page-height="29.7cm" page-width="21.0cm"
                    margin="1cm">
                    <fo:region-body />
                </fo:simple-page-master>
            </fo:layout-master-set>
            <fo:page-sequence master-reference="A4-portrait">
                <fo:flow flow-name="xsl-region-body">

                    <fo:table border="solid">
                        <fo:table-column column-width="30mm" />
                        <fo:table-column column-width="30mm" />
                        <fo:table-column column-width="30mm" />
                        <fo:table-column column-width="35mm" />
                        <fo:table-column column-width="35mm" />
                        <fo:table-column column-width="30mm" />
                        <fo:table-header>
                            <fo:table-row>
                                <fo:table-cell>
                                    <fo:block font-weight="bold">Juego</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block font-weight="bold">Desarrolladora</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block font-weight="bold">Distribuidora</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block font-weight="bold">Fecha de Lanzamiento</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block font-weight="bold">Genero</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block font-weight="bold">Plataforma</fo:block>
                                </fo:table-cell>
                            </fo:table-row>
                        </fo:table-header>
                        <fo:table-body>
                            <xsl:for-each select="list/juego">
                                <fo:table-row>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="nombre" />
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="desarrolladora" />
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="distribuidora" />
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="fechaLanzamiento" />
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="genero" />
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="plataformas" />
                                        </fo:block>
                                    </fo:table-cell>
                                </fo:table-row>
                            </xsl:for-each>
                        </fo:table-body>
                    </fo:table>

                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>
</xsl:stylesheet>



Clase de ayuda con el método de transformacion


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package dar10;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;

public class FopHelper {

    public void xmlString2Pdf(String xml, String xslPath, String pdfPath) throws IOException, FOPException, TransformerException{
        FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
        FOUserAgent foUserAgent = fopFactory.newFOUserAgent();

        OutputStream out;
        out = new FileOutputStream(pdfPath);

        try {
            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);

            // Ubicacion del archivo XSL
            File xsltFile = new File(xslPath);
            Source xslSource = new StreamSource(xsltFile);
            // Setup XSLT
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer(xslSource);

            // Resulting SAX events (the generated FO) must be piped through to FOP
            Result res = new SAXResult(fop.getDefaultHandler());

            // Se convierte a 'Source' el xml
            StringReader reader = new StringReader(xml);
            Source xmlSource = new StreamSource(reader);

            // se crea el PDF
            transformer.transform(xmlSource, res);
        } finally {
            out.close();
        }
    }

    public void xmlFile2Pdf(String xmlPath, String xslPath, String pdfPath) throws IOException, FOPException, TransformerException{
        FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
        FOUserAgent foUserAgent = fopFactory.newFOUserAgent();

        OutputStream out;
        out = new FileOutputStream(pdfPath);

        try {
            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);

            // Ubicacion del archivo XSL
            File xsltFile = new File(xslPath);
            Source xslSource = new StreamSource(xsltFile);
            // Setup XSLT
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer(xslSource);

            // Resulting SAX events (the generated FO) must be piped through to FOP
            Result res = new SAXResult(fop.getDefaultHandler());

            // Se convierte a 'Source' el xml
            File xmlFile= new File(xmlPath);
            Source xmlSource = new StreamSource(xmlFile);

            // se crea el PDF
            transformer.transform(xmlSource, res);
        } finally {
            out.close();
        }
    }

}



La llamada


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public static String xmlPath = "src//dar10//juegos.xml";
public static String xslPath = "src//dar10//template.xsl";
public static String pdfPath = "src//dar10//resultado.pdf";

public static void main(String...Legendar10){
    FopHelper fopHelper = new FopHelper();
    try {
        fopHelper.xmlFile2Pdf(xmlPath, xslPath, pdfPath);
    } catch (FOPException | IOException | TransformerException e) {
        e.printStackTrace();
    }
}



El resultado


No hay comentarios:

Publicar un comentario