Bonjour,
J'essaie de transformer un JDOM en un fichier pdf en utilisant Xsl Fo et j'avoue que je galère un peu...![]()
Quelqu'un aurait il une méthode "simple" pour générer ce pdf:
D'avance, un grand merci.![]()
Bonjour,
J'essaie de transformer un JDOM en un fichier pdf en utilisant Xsl Fo et j'avoue que je galère un peu...![]()
Quelqu'un aurait il une méthode "simple" pour générer ce pdf:
D'avance, un grand merci.![]()
En fait, j'ai un flux XML que je veux transformer en un flux PDF dans une application Web (sous WSAD 5.0).
J'ai déjà pas mal avancé puisque j'arrive à transformer un fichier xml en un fichier pdf grâce au code suivant (pour ceux que cela peut intéresser) :
Et donc j'essaie d'améliorer cette classe afin de transformer non pas des fichiers mais des flux de type String.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 public class XmlToPdf { 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); driver.setLogger(logger); MessageHandler.setScreenLogger(logger); //Setup Renderer (output format) driver.setRenderer(Driver.RENDER_PDF); //Setup output OutputStream out = new java.io.FileOutputStream(pdf); 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); System.out.println("Xml input :"+xml); System.out.println("Xsl input :"+xslt); //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); System.out.println("Pdf output :"+out.toString()); } finally { out.close(); } } public static void main(String[] args) { try { System.out.println("FOP ExampleXML2PDF "); System.out.println("Preparing..."); //Setup directories File baseDir = new File("."); File outDir = new File(baseDir, "out"); outDir.mkdirs(); //Setup input and output files File xmlfile = new File(baseDir, "xml/xml/projectteam.xml"); File xsltfile = new File(baseDir, "xml/xslt/projectteam2FO.xsl"); File pdffile = new File(outDir, "ResultXML2PDF.pdf"); System.out.println("Input: XML (" + xmlfile + ")"); System.out.println("Stylesheet: " + xsltfile); System.out.println("Output: PDF (" + pdffile + ")"); System.out.println(); System.out.println("Transforming..."); XmlToPdf app = new XmlToPdf(); app.convertXML2PDF(xmlfile, xsltfile, pdffile); System.out.println("Success!"); } catch (Exception e) { System.err.println(ExceptionUtil.printStackTrace(e)); System.exit(-1); } } }
Toutes vos suggestions sont les bien venues.![]()
Tu n'as quasiment rien à changer : Xalan permet de construire un "StreamSource" à partir d'un Reader ou d'un InputStream, donc tu n'as qu'à passer ton flux au constructeur...
Euh... j'avoue que j'ai pas très bien compris.Envoyé par Greedo
![]()
http://xml.apache.org/xalan-j/apidoc...eamSource.html
La classe StreamSource qui "contient" ton document XML possède plusieurs constructeurs. Tu t'es servi (enfin l'exemple dont tu t'es inspiré s'est servi) du constructeur prenant un objet File en paramètre.
Si ton document XML est sous forme de String, tu crées un StringReader
Puis tu passes ce reader au constructeur de StreamSource
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 StringReader reader = new StringReader(monDocEnString);
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 Source src = new StreamSource(reader);
Ok, merci pour la récupération de la String et son passage dans le constructeur.![]()
Maintenant, mon problème est la récupération de mon pdf sous forme de String après le passage dans le Xslt...![]()
En tout cas, un grand merci pour ton coup de main.
Même principe : au lieu de récupérer un SAXResult, crée un StreamResultMaintenant, mon problème est la récupération de mon pdf sous forme de String après le passage dans le Xslt...
(je donne une syntaxe approximative):
Et ensuite tu récupères ton PDF en faisant un result.getWriter().toString() (je n'ai pas testé mais ca doit marcher)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 StreamResult result = new StreamResult(new StringWriter());
En fait, j'ai testé deux possibilités :
getWriter,
getBuffer.
Les deux retours possibles sont :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 /** * * @param xsltPath * @param xml * @param pdf * @throws FlowException */ public static String xmlToPdf(String xml, String xsltPath) throws IOException, FOPException, TransformerException { //Construct driver Driver driver = new Driver(); //Setup logger Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); driver.setLogger(logger); MessageHandler.setScreenLogger(logger); //Setup Renderer (output format) driver.setRenderer(Driver.RENDER_PDF); //Setup reader StringReader reader = new StringReader(xml); //Setup output //OutputStream out = new java.io.FileOutputStream(pdf); try { //driver.setOutputStream(out); StringWriter w = new StringWriter(); //Setup XSLT TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(new StreamSource(xsltPath)); //Setup input for XSLT transformation Source src = new StreamSource(reader); System.out.println("Xml input :"+xml); System.out.println("Xsl input :"+xsltPath); //Resulting SAX events (the generated FO) must be piped through to FOP StreamResult res = new StreamResult(new StringWriter()); System.out.println("-->Stream OK"); transformer.transform(src, new StreamResult(w)); System.out.println("-->transformer.transform OK"); res.getWriter().toString(); System.out.println("-->getWriter OK"); System.out.println("Fichier Pdf getWriter : "+res); String retour = new String(w.getBuffer()); System.out.println("Fichier Pdf getBuffer : "+w); w.close(); return retour; } finally { } }
getWriter : une adresse mémoire du genre : javax.xml.transform.stream.StreamResult@34ec1d39
getBuffer : un mélange de XSLFO et XML
Mon soucis est que le retour de ma méthode doit être lisible par Acrobate Reader et je me demande si c'est le cas de l'un des retours que j'ai en sortie de cette méthode:
![]()
De plus, je ne me serts plus de "Driver" ce qui, à mon avis (mais je peux me tromper), permettait la transformation en pdf ; non ?
J'avoue qu'un coup de main serait le bien venu parce que là, je nage totalement...![]()
Aaaaah OK OK, je n'avais pas compris ca comme ca : je croyais que tu voulais a tout prix récupérer du String.
Si tu veux retourner le document PDF tel quel (dans le cas d'une appli web), il doit falloir utiliser un tableau de bytes => ByteArrayOutputStream.
Mais si, plus simplement, tu veux écrire directement dans un fichier, du peux créer un StreamResult a partir d'un objet File.
Ok, je retourne un tableau de bytes :Envoyé par Greedo
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 /** * * @param xsltPath * @param xml * @param pdf * @throws FlowException */ public static void xmlToPdf(String xsltPath, Document documentJDOM) throws Exception { // Declaration // Declarations Transformer transformer; Source src; Result res; ByteArrayOutputStream out; Driver driver; Logger logger; byte[] content; // Initialisations transformer = null; src = null; res = null; out = null; driver = null; logger = null; content = null; try { out = new ByteArrayOutputStream(); driver = new Driver(); // Setup logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); driver.setLogger(logger); MessageHandler.setScreenLogger(logger); driver.setRenderer(Driver.RENDER_PDF); driver.setOutputStream(out); transformer = TransformerFactory.newInstance().newTransformer(new StreamSource(new File(xsltPath))); // Setup input for XSLT transformation src = new JDOMSource(documentJDOM); //Resulting SAX events (the generated FO) must be piped through to FOP res = new SAXResult(driver.getContentHandler()); //Start XSLT transformation and FOP processing transformer.transform(src, res); content = out.toByteArray(); } catch (IOException e) { throw e; } catch (TransformerConfigurationException e) { throw e; } catch (TransformerFactoryConfigurationError e) { throw e; } catch (TransformerException e) { throw e; } }![]()
Mais j'en fais quoi de mon tableau de bytes:
En quoi faut il que je le transforme pour que je puisse afficher le pdf:
Merci pour ta patience.![]()
Par contre là je ne connais pas très bien la méthode : j'ai déja généré du PDF dans une appli java-servlet, mais le retour du PDF etait réalisé par un framework.
Si tu souhaites effectivement retourner du PDF depuis une servlet, je te conseille de regarder du côté de la classe HttpServletResponse.
En gros, il doit falloir faire un setContentType() sur la reponse (avec pour valeur le type MIME pdf ; cherche sur google la liste des types mime) et trouver comment y placer un byte array (regarde peut etre du côté de la methode getOutputStream).
Tiens moi au courant, ca m'intéresse...
Ok, je regarde ça et je te tiens au courant...![]()
J'ai suivi tes conseils et grâce à ce que j'ai trouvé sur Internet, j'ai "pondu" cette nouvelle méthode :Envoyé par Greedo
Et j'ai créé une servlet :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 public static void xmlToPdf(String xsltPath, Document documentJDOM, HttpServletResponse response) throws Exception { // Declaration // Declaration Transformer transformer; Source src; Result res; ByteArrayOutputStream out; Driver driver; Logger logger; byte[] content; // Initialisation transformer = null; src = null; res = null; out = null; driver = null; logger = null; content = null; try { out = new ByteArrayOutputStream(); response.setContentType("application/pdf"); driver = new Driver(); // Setup logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); driver.setLogger(logger); MessageHandler.setScreenLogger(logger); driver.setRenderer(Driver.RENDER_PDF); driver.setOutputStream(out); transformer = TransformerFactory.newInstance().newTransformer(new StreamSource(new File(xsltPath))); // Setup input for XSLT transformation src = new JDOMSource(documentJDOM); //Resulting SAX events (the generated FO) must be piped through to FOP res = new SAXResult(driver.getContentHandler()); //Start XSLT transformation and FOP processing transformer.transform(src, res); content = out.toByteArray(); response.setContentLength(content.length); response.getOutputStream().write(content); response.getOutputStream().flush(); } catch (IOException e) { throw e; } catch (TransformerConfigurationException e) { throw e; } catch (TransformerFactoryConfigurationError e) { throw e; } catch (TransformerException e) { throw e; } }
Comme tu l'as deviné, je suis débutant en Struts et je ne sais pas comment appeler ma Servlet.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 public class RenderPdfServlet extends HttpServlet { /* (non-Javadoc) * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //TODO tester que le pdf est bien generable try { Utilitaire.xmlToPdf("D:\\workspace\\Metier-War-Autoweb\\Web Content\\xsl\\pdf.xsl", Utilitaire.fileToJdom("D:\\workspace\\Metier-War-Autoweb\\Web Content\\documents\\ds200405041349194.xml"), response); } catch (Exception e) { throw new ServletException(e); } } }
De plus, ça ne me plaît pas trop d'appeler ma méthode dans la servlet car les paramètres de celle ci sont changeant.![]()
Aurais tu une idée pour résoudre mes deux nouveaux problèmes:
Merci pour ton aide.![]()
Voilà, j'ai trouvé tout seul comme un grand. 8)
Le code de ma méthode (dans la classe Utilitaire) :
Le code de ma servlet :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 /** * Retourne un tableau de bytes à partir d'un doc JDOM et d'un fichier xslt * * @param xsltPath * @param xml * @param pdf * @throws FlowException */ public static byte[] xmlToPdf(String xsltPath, Document documentJDOM) throws Exception { // Declaration Transformer transformer; Source src; Result res; ByteArrayOutputStream out; Driver driver; Logger logger; byte[] content; // Initialisation transformer = null; src = null; res = null; out = null; driver = null; logger = null; content = null; try { out = new ByteArrayOutputStream(); driver = new Driver(); // Setup logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); driver.setLogger(logger); MessageHandler.setScreenLogger(logger); driver.setRenderer(Driver.RENDER_PDF); driver.setOutputStream(out); transformer = TransformerFactory.newInstance().newTransformer(new StreamSource(new File(xsltPath))); // Setup input for XSLT transformation src = new JDOMSource(documentJDOM); //Resulting SAX events (the generated FO) must be piped through to FOP res = new SAXResult(driver.getContentHandler()); //Start XSLT transformation and FOP processing transformer.transform(src, res); content = out.toByteArray(); return content; } catch (TransformerConfigurationException e) { throw e; } catch (TransformerFactoryConfigurationError e) { throw e; } catch (TransformerException e) { throw e; } }
Et je rajoute l'appel de la servlet dans une page jsp :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 public class RenderPdfServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Déclarations String xsltPath = "D:\\workspace\\Metier-War-Autoweb\\Web Content\\xsl\\ds-fo.xsl"; String contenuDoc = null; Document docXml = null; byte[] content = null; try { // Récupération contenu du document en focntion de l'identifiant contenuDoc = GestionDoc.RecupTotalDoc(request.getParameter("identDoc")); // Transforme le xml en xml+normes docXml = GestionDoc.xmlToXmlNorme(contenuDoc); // Transformation du document jdom en tableau de bytes content = Utilitaire.xmlToPdf(xsltPath, docXml); System.out.println("preparation de la reponse"); response.setContentType("application/pdf"); response.setContentLength(content.length); response.getOutputStream().write(content); System.out.println("avant flush"); response.getOutputStream().flush(); System.out.println("fin flush"); } catch (Exception e) { throw new ServletException(e); } } }
J'espère que cela pourra aider certains d'entre vous...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 <html:link paramId="identDoc" paramName="document" paramProperty="identDoc" href="http://localhost:9080/projet/render">Format pdf</html:link>![]()
A+ et bonne prog à tous.
Partager