View Full Version : [XSLT] Creare il file XSL per creare PDF da XML
Se io ho il seguente file xml:
<?xml version="1.0" encoding="windows-1252"?>
<richiesta codice="2">
<richiedente codiceFiscale="MGUAIH8787ASDSAD">PAOLO ROSSI</richiedente>
<obiettivo>TEST</obiettivo>
<destinazione>Milano, Italia</destinazione>
<dataInizio>Wed Oct 22 00:00:00 CEST 2008</dataInizio>
<durata>12</durata>
<anticipo>no</anticipo>
<dataRichiesta>Wed Jul 16 00:00:00 CEST 2008</dataRichiesta>
</richiesta>
Potete aiutarmi a formattare il file xsl per creare un pdf tramite processore FOP?
Il risultato è semplice.
Dovrebbe essere qualcosa del genere:
Il sottoscritto: ***** codice fiscale: ****
fa richiesta di missione con obiettivo: ****** e destinazione: *****
La missione inizierà in data: ***** e durerà *** gg
Data Richiesta: ****
Firma
Ho impostato tutto correttamente per la trasformazione tramite servlet java, però ho problemi seri a crearmi il .xsl
Potete aiutarmi per favore? :(
Neanche un aiutino piccolo piccolo? :cry:
Allora, facendo alcuni test con il seguente file .xsl
<?xml version="1.0" encoding="ISO-8859-1"?>
<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" version="1.0" omit-xml-declaration="no" indent="yes"/>
<xsl:template match="root">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master
margin-right="1.5cm"
margin-left="1.5cm"
margin-bottom="2cm"
margin-top="1cm"
page-width="21cm"
page-height="29.7cm"
master-name="simpleA4" >
<fo:region-body margin-top="1cm" margin-bottom="1.5cm"/>
<fo:region-before extent="1cm"/>
<fo:region-after extent="1.5cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="simpleA4">
<fo:static-content flow-name="xsl-region-before">
<fo:block font-size="18pt"
font-family="sans-serif"
line-height="24pt"
space-after.optimum="15pt"
background-color="blue"
color="white"
text-align="center"
padding-top="3pt"> Richiesta Missioni </fo:block>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after">
<fo:block line-height="14pt" font-size="10pt"
text-align="end">Page <fo:page-number/></fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<fo:block text-align="end"><xsl:variable name="pp" select="./@rrr" /> <fo:external-graphic src="{$pp}" /> </fo:block>
<xsl:apply-templates/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="richiesta">
</xsl:template>
</xsl:stylesheet>
Tutto sembra funzionare, mi si apre il pdf ma mi esce l'errore:
Questo file non può essere aperto perché non contiene alcuna pagina
Perché? :( so che non stampo ancora niente dal file xml ma non dovrebbe almeno apparire la pagina con la scritta: Richiesta Missioni ?
Di seguito vi incollo il codice della Servlet che crea prima il file xml e poi il pdf. Penso sia tutto giusto.. l'errore secondo me sta nel file .xsl
Voi che dite? Qualcuno può darmi una mano per favore?
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package missioni.servlet;
import java.io.*;
import java.net.*;
import javax.ejb.EJB;
import javax.servlet.*;
import javax.servlet.http.*;
import org.jdom.*;
import org.jdom.output.XMLOutputter;
import missioni.ejb.session.GestoreMissioniLocal;
//Java
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
//JAXP
import java.util.*;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerException;
import javax.xml.transform.Source;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.sax.SAXResult;
//Avalon
//import org.apache.avalon.framework.ExceptionUtil;
import org.apache.avalon.framework.logger.ConsoleLogger;
import org.apache.avalon.framework.logger.Logger;
//FOP
import org.apache.fop.messaging.*;
import org.apache.fop.apps.Driver;
import org.apache.fop.apps.FOPException;
/**
*
* @author while
*/
public class CreaPDFServlet extends HttpServlet {
@EJB
GestoreMissioniLocal gestore=null;
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
RequestDispatcher rd =null;
String path=getServletContext().getRealPath(""); //recupera il path assoluto --rende così
path=path+"/"; //l'applicazione indipendent dal file System locale
// del container che la esegue --
HttpSession sessione=request.getSession();
//RICHIEDENTE
String n=(String)sessione.getAttribute("nome");
String c=(String)sessione.getAttribute("cognome");
String codiceFiscale=(String)sessione.getAttribute("codiceFiscale");
//DATI MISSIONE
String codiceRichiesta=request.getParameter("codiceRichiesta");
String ob=request.getParameter("obiettivo");
String cit=request.getParameter("citta");
String naz=request.getParameter("nazione");
String di=request.getParameter("dataInizio");
String dr=request.getParameter("dataRichiesta");
String ant=request.getParameter("anticipo");
String dur=request.getParameter("durata");
//CREO FILE XML
File fileTmp = new File(path+"rich.xml");
//CREO L'ELEMENTO ROOT
Element root = new Element("richiesta");
/* Per specificare il foglio di stile associato al file all'apertura tramite browser
* dobbiamo creare un'istanza della classe ProcessingInstruction in cui tramite l'ogetto HashMap
* in cui settiamo le coppie chiave valore opportune
*/
Map mapping=new HashMap();
mapping.put("type","text/xsl");
mapping.put("href",path+"richieste.xsl");
ProcessingInstruction pi=new ProcessingInstruction("xml-stylesheet",mapping);
ArrayList arry=new ArrayList();
arry.add(pi);
arry.add(root);
Document documento = new Document(arry);
//AGGIUNGIAMO ATTRIBUTO: <root attributo=valore>
root = root.setAttribute("codice",codiceRichiesta);
//ELEMENTI INNESTATI
Element richiedente = new Element("richiedente");
richiedente = richiedente.setAttribute("codiceFiscale", codiceFiscale);
Element obiettivo = new Element("obiettivo");
Element destinazione = new Element("destinazione");
Element dataInizio = new Element("dataInizio");
Element durata = new Element("durata");
Element anticipo = new Element("anticipo");
Element dataRichiesta = new Element("dataRichiesta");
//VALORI ELEMENTI INNESTATI
richiedente.addContent(n+" "+c);
obiettivo.addContent(ob);
destinazione.addContent(cit+", "+naz);
dataInizio.addContent(di);
durata.addContent(dur);
anticipo.addContent(ant);
dataRichiesta.addContent(dr);
//ATTACCO TUTTO A ROOT
root.addContent(richiedente);
root.addContent(obiettivo);
root.addContent(destinazione);
root.addContent(dataInizio);
root.addContent(durata);
root.addContent(anticipo);
root.addContent(dataRichiesta);
BufferedWriter out = null;
out = new BufferedWriter(new FileWriter(fileTmp));
/* ISTANZIAMO LA CLASSE XMLOutputter CHE CI PERMETTE DI FORMATTARE IL FILE XML. */
XMLOutputter xout = new XMLOutputter();
xout.setEncoding("windows-1252"); //impostiamo l'encoding per la corretta visualizzazione con explorer
xout.setIndent(true);
xout.setNewlines(true);
/* CON QUESTA ISTRUZIONE SCRIVIAMO IL DOCUMENTO documento IN UN BufferedWriter CHE CREA
IL FILE TRAMITE UN FileWriter */
xout.output(documento,out);
out.close();
String fwd ="/rich.pdf";
//*********** creazione del file PDF ****************/
File xmlfile = new File (path+"rich.xml");
File xsltfile = new File (path+"richieste2.xsl");
File pdffile = new File (path+"rich.pdf");
Xml2Pdf app = new Xml2Pdf();
app.convertXML2PDF(xmlfile, xsltfile, pdffile);
rd=request.getRequestDispatcher(fwd);
rd.forward(request, response);
}catch(Exception e){
e.printStackTrace();
HttpSession sessione=request.getSession();
sessione.setAttribute("msg", e);
response.sendRedirect("jsp/error.jsp");
}
}
}
class Xml2Pdf {
public void convertXML2PDF(File xml, File xslt, File pdf)
throws IOException, FOPException, TransformerException {
//Construct driver
Driver driver = new Driver();
//Setup logger
Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO);
MessageHandler.setScreenLogger(logger);
driver.setLogger(logger);
//Driver.enableLogging(logger);
//driver.initialize();
//Setup Renderer (output format)
driver.setRenderer(Driver.RENDER_PDF);
//Setup output
OutputStream out = new java.io.FileOutputStream(pdf);
out = new java.io.BufferedOutputStream(out);
try {
driver.setOutputStream(out);
//Setup XSLT
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(xslt));
//Setup input for XSLT transformation
Source src = new StreamSource(xml);
//Resulting SAX events (the generated FO) must be piped through to FOP
Result res = new SAXResult(driver.getContentHandler());
//Start XSLT transformation and FOP processing
transformer.transform(src, res);
} finally {
out.close();
}
}
}
Ho risolto.
Per dare un contributo alla sezione scrivo il codice di seguito:
xsl (incompleto ma da cui si può prendere spunto)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="A4">
<fo:region-body margin="2cm" />
<fo:region-before/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="xsl-region-body">
<fo:block>
<xsl:value-of select="richiesta/richiedente"/>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
Codice per richiamare la trasformazione:
FopFactory fopFactory = FopFactory.newInstance();
TransformerFactory tFactory = TransformerFactory.newInstance();
//Setup a buffer to obtain the content length
ByteArrayOutputStream out2 = new ByteArrayOutputStream();
//Setup FOP
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out2);
//Setup Transformer
Source xsltSrc = new StreamSource(new File(path+"rich.xsl"));
Transformer transformer = tFactory.newTransformer(xsltSrc);
//Make sure the XSL transformation's result is piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());
//Setup input
Source src = new StreamSource(new File(path+"rich.xml"));
//Start the transformation and rendering process
transformer.transform(src, res);
//Prepare response
response.setContentType("application/pdf");
response.setContentLength(out2.size());
//Send content to Browser
response.getOutputStream().write(out2.toByteArray());
response.getOutputStream().flush();
Codice di tutta la Servlet che crea prima il .xml e poi lo trasforma in .pdf (il codice della trasformazione è compreso)
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package missioni.servlet;
import java.io.*;
import java.net.*;
import javax.ejb.EJB;
import javax.servlet.*;
import javax.servlet.http.*;
import org.jdom.*;
import org.jdom.output.XMLOutputter;
import missioni.ejb.session.GestoreMissioniLocal;
//Java
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
//JAXP
import java.util.*;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerException;
import javax.xml.transform.Source;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.sax.SAXResult;
//Avalon
//import org.apache.avalon.framework.ExceptionUtil;
import org.apache.avalon.framework.logger.ConsoleLogger;
import org.apache.avalon.framework.logger.Logger;
//FOP
//import org.apache.fop.messaging.*;
//import org.apache.fop.apps.Driver;
import org.apache.fop.apps.FOPException;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.logging.Level;
//import java.util.logging.Logger;
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.FopFactory;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.MimeConstants;
/**
*
* @author while
*/
public class CreaPDFServlet extends HttpServlet {
@EJB
GestoreMissioniLocal gestore=null;
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
RequestDispatcher rd =null;
String path=getServletContext().getRealPath(""); //recupera il path assoluto --rende così
path=path+"/"; //l'applicazione indipendent dal file System locale
// del container che la esegue --
HttpSession sessione=request.getSession();
//RICHIEDENTE
String n=(String)sessione.getAttribute("nome");
String c=(String)sessione.getAttribute("cognome");
String codiceFiscale=(String)sessione.getAttribute("codiceFiscale");
//DATI MISSIONE
String codiceRichiesta=request.getParameter("codiceRichiesta");
String ob=request.getParameter("obiettivo");
String cit=request.getParameter("citta");
String naz=request.getParameter("nazione");
String di=request.getParameter("dataInizio");
String dr=request.getParameter("dataRichiesta");
String ant=request.getParameter("anticipo");
String dur=request.getParameter("durata");
//CREO FILE XML
File fileTmp = new File(path+"rich.xml");
//CREO L'ELEMENTO ROOT
Element root = new Element("richiesta");
/* Per specificare il foglio di stile associato al file all'apertura tramite browser
* dobbiamo creare un'istanza della classe ProcessingInstruction in cui tramite l'ogetto HashMap
* in cui settiamo le coppie chiave valore opportune
*/
Map mapping=new HashMap();
mapping.put("type","text/xsl");
mapping.put("href",path+"richieste.xsl");
ProcessingInstruction pi=new ProcessingInstruction("xml-stylesheet",mapping);
ArrayList arry=new ArrayList();
arry.add(pi);
arry.add(root);
Document documento = new Document(arry);
//AGGIUNGIAMO ATTRIBUTO: <root attributo=valore>
root = root.setAttribute("codice",codiceRichiesta);
//ELEMENTI INNESTATI
Element richiedente = new Element("richiedente");
richiedente = richiedente.setAttribute("codiceFiscale", codiceFiscale);
Element obiettivo = new Element("obiettivo");
Element destinazione = new Element("destinazione");
Element dataInizio = new Element("dataInizio");
Element durata = new Element("durata");
Element anticipo = new Element("anticipo");
Element dataRichiesta = new Element("dataRichiesta");
//VALORI ELEMENTI INNESTATI
richiedente.addContent(n+" "+c);
obiettivo.addContent(ob);
destinazione.addContent(cit+", "+naz);
dataInizio.addContent(di);
durata.addContent(dur);
anticipo.addContent(ant);
dataRichiesta.addContent(dr);
//ATTACCO TUTTO A ROOT
root.addContent(richiedente);
root.addContent(obiettivo);
root.addContent(destinazione);
root.addContent(dataInizio);
root.addContent(durata);
root.addContent(anticipo);
root.addContent(dataRichiesta);
BufferedWriter out = null;
out = new BufferedWriter(new FileWriter(fileTmp));
/* ISTANZIAMO LA CLASSE XMLOutputter CHE CI PERMETTE DI FORMATTARE IL FILE XML. */
XMLOutputter xout = new XMLOutputter();
xout.setIndent(true);
xout.setNewlines(true);
/* CON QUESTA ISTRUZIONE SCRIVIAMO IL DOCUMENTO documento IN UN BufferedWriter CHE CREA
IL FILE TRAMITE UN FileWriter */
xout.output(documento,out);
out.close();
FopFactory fopFactory = FopFactory.newInstance();
TransformerFactory tFactory = TransformerFactory.newInstance();
//Setup a buffer to obtain the content length
ByteArrayOutputStream out2 = new ByteArrayOutputStream();
//Setup FOP
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out2);
//Setup Transformer
Source xsltSrc = new StreamSource(new File(path+"rich.xsl"));
Transformer transformer = tFactory.newTransformer(xsltSrc);
//Make sure the XSL transformation's result is piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());
//Setup input
Source src = new StreamSource(new File(path+"rich.xml"));
//Start the transformation and rendering process
transformer.transform(src, res);
//Prepare response
response.setContentType("application/pdf");
response.setContentLength(out2.size());
//Send content to Browser
response.getOutputStream().write(out2.toByteArray());
response.getOutputStream().flush();
}catch(Exception e){
e.printStackTrace();
HttpSession sessione=request.getSession();
sessione.setAttribute("msg", e);
response.sendRedirect("jsp/error.jsp");
}
}
}
Ciao ;)
banryu79
28-07-2008, 15:54
Solo un appunto: nel codice che hai postato della Servlet hai degli import duplicati (in particolare gli import di Java.io.* di org.apache.fop.apps.FOPException)
Solo un appunto: nel codice che hai postato della Servlet hai degli import duplicati (in particolare gli import di Java.io.* di org.apache.fop.apps.FOPException)
Grazie per la segnalazione.
Erano rimasti molti import inutili del vecchio codice.
Di seguito solo quelli necessari:
import java.io.*;
import java.net.*;
import javax.ejb.EJB;
import javax.servlet.*;
import javax.servlet.http.*;
import org.jdom.*;
import missioni.ejb.session.GestoreMissioniLocal;
import java.util.*;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Source;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.MimeConstants;
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.