Pregunta

En este momento, estoy creando un archivo XML en Java y lo estoy mostrando en una página JSP al transformarlo con XSL / XSLT. Ahora necesito tomar ese archivo XML y mostrar la misma información en un PDF. ¿Hay alguna manera de que pueda hacer esto utilizando algún tipo de archivo XSL?

He visto la iText biblioteca de Java-PDF, pero no puedo encontrar ninguna forma para usarlo con XML y una hoja de estilo.

Cualquier ayuda sería muy apreciada. Gracias de antemano!

Otros consejos

A - Explicación

Debe usar el marco Apache FOP para generar la salida pdf . Simplemente proporcione los datos en formato xml y renderice la página con un archivo xsl-fo y especifique los parámetros como margen , diseño de página en este archivo xsl-fo .

Proporcionaré una demostración simple, utilizo la herramienta de compilación maven para recopilar los archivos jar necesarios. Notifique que al final de la página, hay un gráfico svg incrustado en pdf. También quiero demostrar que puede incrustar gráficos svg dentro de pdf.

B - Ejemplo de datos de entrada XML

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="application/xml"?>
<users-data>
    <header-section>
        <data-type id="019">User Bill Data</data-type>
        <process-date>Thursday December 9 2016 00:04:29</process-date>
    </header-section>
    <user-bill-data>
        <full-name>John Doe</full-name>
        <postal-code>34239</postal-code>
        <national-id>123AD329248</national-id>
        <price>17.84</price>
    </user-bill-data>
    <user-bill-data>
        <full-name>Michael Doe</full-name>
        <postal-code>54823</postal-code>
        <national-id>942KFDSCW322</national-id>
        <price>34.50</price>
    </user-bill-data>
    <user-bill-data>
        <full-name>Jane Brown</full-name>
        <postal-code>66742</postal-code>
        <national-id>ABDD324KKD8</national-id>
        <price>69.36</price>
    </user-bill-data>
</users-data>

C - La plantilla XSL-FO

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
    <xsl:output encoding="UTF-8" indent="yes" method="xml" standalone="no" omit-xml-declaration="no"/>
    <xsl:template match="users-data">
        <fo:root language="EN">
            <fo:layout-master-set>
                <fo:simple-page-master master-name="A4-portrail" page-height="297mm" page-width="210mm" margin-top="5mm" margin-bottom="5mm" margin-left="5mm" margin-right="5mm">
                    <fo:region-body margin-top="25mm" margin-bottom="20mm"/>
                    <fo:region-before region-name="xsl-region-before" extent="25mm" display-align="before" precedence="true"/>
                </fo:simple-page-master>
            </fo:layout-master-set>
            <fo:page-sequence master-reference="A4-portrail">
                <fo:static-content flow-name="xsl-region-before">
                    <fo:table table-layout="fixed" width="100%" font-size="10pt" border-color="black" border-width="0.4mm" border-style="solid">
                        <fo:table-column column-width="proportional-column-width(20)"/>
                        <fo:table-column column-width="proportional-column-width(45)"/>
                        <fo:table-column column-width="proportional-column-width(20)"/>
                        <fo:table-body>
                            <fo:table-row>
                                <fo:table-cell text-align="left" display-align="center" padding-left="2mm">
                                    <fo:block>
                                        Bill Id:<xsl:value-of select="header-section/data-type/@id"/>
                                        , Date: <xsl:value-of select="header-section/process-date"/>
                                    </fo:block>
                                </fo:table-cell>
                                <fo:table-cell text-align="center" display-align="center">
                                    <fo:block font-size="150%">
                                        <fo:basic-link external-destination="http://www.example.com">XXX COMPANY</fo:basic-link>
                                    </fo:block>
                                    <fo:block space-before="3mm"/>
                                </fo:table-cell>
                                <fo:table-cell text-align="right" display-align="center" padding-right="2mm">
                                    <fo:block>
                                        <xsl:value-of select="data-type"/>
                                    </fo:block>
                                    <fo:block display-align="before" space-before="6mm">Page <fo:page-number/> of <fo:page-number-citation ref-id="end-of-document"/>
                                    </fo:block>
                                </fo:table-cell>
                            </fo:table-row>
                        </fo:table-body>
                    </fo:table>
                </fo:static-content>
                <fo:flow flow-name="xsl-region-body" border-collapse="collapse" reference-orientation="0">
                    <fo:block>MONTHLY BILL REPORT</fo:block>
                    <fo:table table-layout="fixed" width="100%" font-size="10pt" border-color="black" border-width="0.35mm" border-style="solid" text-align="center" display-align="center" space-after="5mm">
                        <fo:table-column column-width="proportional-column-width(20)"/>
                        <fo:table-column column-width="proportional-column-width(30)"/>
                        <fo:table-column column-width="proportional-column-width(25)"/>
                        <fo:table-column column-width="proportional-column-width(50)"/>
                        <fo:table-body font-size="95%">
                            <fo:table-row height="8mm">
                                <fo:table-cell>
                                    <fo:block>Full Name</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block>Postal Code</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block>National ID</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block>Payment</fo:block>
                                </fo:table-cell>
                            </fo:table-row>
                            <xsl:for-each select="user-bill-data">
                                <fo:table-row>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="full-name"/>
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="postal-code"/>
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="national-id"/>
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="price"/>
                                        </fo:block>
                                    </fo:table-cell>
                                </fo:table-row>
                            </xsl:for-each>
                        </fo:table-body>
                    </fo:table>
                    <fo:block id="end-of-document">
                        <fo:instream-foreign-object>
                            <svg width="200mm" height="150mm" version="1.1" xmlns="http://www.w3.org/2000/svg">
                                <path d="M153 334
C153 334 151 334 151 334
C151 339 153 344 156 344
C164 344 171 339 171 334
C171 322 164 314 156 314
C142 314 131 322 131 334
C131 350 142 364 156 364
C175 364 191 350 191 334
C191 311 175 294 156 294
C131 294 111 311 111 334
C111 361 131 384 156 384
C186 384 211 361 211 334
C211 300 186 274 156 274" style="fill:yellow;stroke:red;stroke-width:2"/>
                            </svg>
                        </fo:instream-foreign-object>
                    </fo:block>
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>
</xsl:stylesheet>

D - Estructura del directorio del proyecto

 introduce la descripción de la imagen aquí

E - Archivo Pom

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.levent.fopdemo</groupId>
    <artifactId>apache-fop-demo</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>apache-fop-demo</name>
    <url>http://maven.apache.org</url>

    <properties>
        <fop.version>2.1</fop.version>
    </properties>

    <dependencies>      
        <!-- https://mvnrepository.com/artifact/org.apache.xmlgraphics/fop -->
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>fop</artifactId>
            <version>${fop.version}</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>Apache Fop Demo</finalName>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

F - Código de demostración: PdfGenerationDemo.java

package com.levent.fopdemo;

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

import javax.xml.transform.Result;
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 PdfGenerationDemo 
{
    public static final String RESOURCES_DIR;
    public static final String OUTPUT_DIR;

    static {
        RESOURCES_DIR = "src//main//resources//";
        OUTPUT_DIR = "src//main//resources//output//";
    }

    public static void main( String[] args )
    {
        try {
            convertToPDF();
        } catch (FOPException | IOException | TransformerException e) {
            e.printStackTrace();
        }
    }

    public static void convertToPDF() throws IOException, FOPException, TransformerException {
        // the XSL FO file
        File xsltFile = new File(RESOURCES_DIR + "//template.xsl");
        // the XML file which provides the input
        StreamSource xmlSource = new StreamSource(new File(RESOURCES_DIR + "//data.xml"));
        // create an instance of fop factory
        FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
        // a user agent is needed for transformation
        FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
        // Setup output
        OutputStream out;
        out = new java.io.FileOutputStream(OUTPUT_DIR + "//output.pdf");

        try {
            // Construct fop with desired output format
            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);

            // Setup XSLT
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer(new StreamSource(xsltFile));

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

            // Start XSLT transformation and FOP processing
            // That's where the XML is first transformed to XSL-FO and then
            // PDF is created
            transformer.transform(xmlSource, res);
        } finally {
            out.close();
        }
    }
}

G - Salida de muestra: output.pdf

 introduce la descripción de la imagen aquí

También puede consultar el proyecto de apache aquí

BIRT tiene una GUI para Eclipse que le permite definir el PDF desde XML, DB , CSV, etc. etc.

Es posible que desee ver las bibliotecas XSL-FO que existen que pueden hacer la creación de PDF como una transformación. Intentaré encontrar un enlace.

Puede aplicar XSL-Fo a su XML y transformarlo con el transformador Java:

File xmlfile = new File(baseDir, xml);
File xsltfile = new File(baseDir, xsl);
File pdffile = new File(outDir, "ResultXMLPDF.pdf");

FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();

OutputStream out = new java.io.FileOutputStream(pdffile);
out = new java.io.BufferedOutputStream(out);

try
{
    Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
    // Setup XSLT
    TransformerFactory factory = TransformerFactory.newInstance();
    Transformer transformer = factory.newTransformer(new StreamSource(xsltfile));

    transformer.setParameter("versionParam", "1.0");

    Source src = new StreamSource(xmlfile);

    Result res = new SAXResult(fop.getDefaultHandler());

    transformer.transform(src, res);

} finally {
    out.close();
}

System.out.println("Success!");

Use JasperReports. Puede extraer los datos de la base de datos o XML. Puede exportar a muchos formatos: pdf, excel, html, etc. ...

Llegando tarde, puede crear un PDF estático con el diseñador de Adobe con campos editables, luego crear un documento XDP XML coincidente.

Hay dos formas de hacer esto.

  • En primer lugar, puede crear un PDF normal que, cuando se lea de nuevo, no le dará la jerarquía del archivo XML original. Esto se explica muy detalladamente en 'Sección 9.4.2 Análisis XML' del 'iText en Acción: Edición 2' .

  • En segundo lugar, puede crear un PDF etiquetado que contenga tanto la jerarquía del XML como los datos. Esto le permite volver a leer el archivo PDF y crear un archivo XML a partir de este (que coincide exactamente con el archivo XML original). Este concepto también se trata en detalle en '15 .2.3 Adding structure ' del ' iText in Action: Edition 2 '.

Según sus requisitos, puede utilizar cualquiera de los enfoques mencionados anteriormente.

XML, CSS, XHTML, etc. consisten en un " ecosistema vivo " de estándares abiertos, mientras que XSL-FO es un estándar aislado.

... Históricamente, XSL-FO y XSLT se crearon como hermanos gemelos, pero solo XSLT sigue siendo un "estándar vivo", XSL-FO concentra mucho ADN en estándares patentados (Adobe) ... ahora está obsoleto.

Estrictamente hablando, XSL-FO es parte de una " forma abandonada " que no evolucionará, ignora CSS, la "nueva forma" para expresar el diseño en el "ecosistema vivo".

No es un problema de Java

Vea esta respuesta sobre el uso de página CSS con XML o XHTML.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top