At the moment, I'm creating an XML file in Java and displaying it in a JSP page by transforming it with XSL/XSLT. Now I need to take that XML file and display the same information in a PDF. Is there a way I can do this by using some kind of XSL file?
I've seen the iText Java-PDF library, but I can't find any way to use it with XML and a stylesheet.
Any assistance would be much appreciated. Thanks in advance!
Four steps for converting your PDF to XML.Use the Select tool to mark the content you want to save. Right-click the highlighted text. Choose Export Selection As. Select XML, and slick Save.
To produce a PDF file from a XML file, first step is that we need an XSLT stylesheet that converts the XML to XSL-FO. Created XSL-FO file is also an XML file which contains formatted objects. The second step will be done by FOP when it reads the generated XSL-FO document and formats it to a PDF document.
You should use Apache FOP framework to generate pdf output. Simply you provide data in xml format and render the page with an xsl-fo file and specify the parameters like margin, page layout in this xsl-fo file.
I'll provide a simple demo, I use maven build tool to gather the needed jar files. Please notify that at the end of the page, there is an svg graphics embedded in pdf. I also want to demonstrate that you can embed svg graphics inside pdf.
<?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>
<?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>
<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>
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(); } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With