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!
回答1:
You can use XSL Formatting objects. Here are some good articles on how to do it:
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.
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;publicclassPdfGenerationDemo{publicstaticfinalString RESOURCES_DIR;publicstaticfinalString OUTPUT_DIR;static{ RESOURCES_DIR ="src//main//resources//"; OUTPUT_DIR ="src//main//resources//output//";}publicstaticvoid main(String[] args ){try{ convertToPDF();}catch(FOPException|IOException|TransformerException e){ e.printStackTrace();}}publicstaticvoid convertToPDF()throwsIOException,FOPException,TransformerException{// the XSL FO fileFile xsltFile =newFile(RESOURCES_DIR +"//template.xsl");// the XML file which provides the inputStreamSource xmlSource =newStreamSource(newFile(RESOURCES_DIR +"//data.xml"));// create an instance of fop factoryFopFactory fopFactory =FopFactory.newInstance(newFile(".").toURI());// a user agent is needed for transformationFOUserAgent foUserAgent = fopFactory.newFOUserAgent();// Setup outputOutputStreamout;out=new java.io.FileOutputStream(OUTPUT_DIR +"//output.pdf");try{// Construct fop with desired output formatFop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent,out);// Setup XSLTTransformerFactory factory =TransformerFactory.newInstance();Transformer transformer = factory.newTransformer(newStreamSource(xsltFile));// Resulting SAX events (the generated FO) must be piped through to// FOPResult res =newSAXResult(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();}}}
Use JasperReports. You can either pull the data from Database or XML. You can export to many formats : pdf, excel, html, etc...
回答9:
Coming in late, you can create a static PDF with Adobe's designer with editable fields, then create a matching XDP XML document.
回答10:
There are two ways to do this.
Firstly, you can create a normal PDF which when read back will not give you the hierarchy of the original XML file. This is explained very elaborately in 'Section 9.4.2 Parsing XML' of the 'iText in Action : Edition 2'.
Secondly, you can create a tagged PDF which contains both the hierarchy of the XML as well as the data. This enables you to read back the PDF file and create an XML file from this(which exactly matches the original XML file). This concept is also dealt with in detail in '15.2.3 Adding structure' of the 'iText in Action : Edition 2'.
Based on your requirements, you can use either of the approaches mentioned above.
回答11:
XML, CSS, XHTML, etc. consist in an "alive ecosystem" of open standards, while XSL-FO is an isolated standard.
... Historically XSL-FO and XSLT was created as twins brothers, but only XSLT remains an "alive standard", XSL-FO concentrates a lot of DNA in proprietary (Adobe) standards... now is obsolete.
Strictly speaking, XSL-FO is part of an "abandoned way" that will not evolve, it ignores CSS, the "new way" to express layout in the "alive ecosystem".
It is not a Java problem
See this answer about the use of CSS-page with XML or XHTML.