2010-11-18 47 views
9

Ceci est ma première question ici, j'espère que je le fais bien. J'utilise JSF 2.0 (Eclipse IDE) et j'essaie de générer des fichiers PDF avec Apache FOP 1.0.FOP: comment spécifier le chemin relatif de l'image src?

J'ai été capable de créer des fichiers PDF simples en utilisant les instructions sur Apache Fop site, mais je ne peux pas insérer d'image depuis mon dossier d'application. Ma structure de dossier est comme ceci: Dans ma demande WebContent j'ai (entre autre) pdf_transform/xslt/transformFile.xsl et pdf_transform/xslt/logo.jpg

En transformFile.xsl j'ai

<fo:block><fo:external-graphic src="url('logo.jpg')"/></fo:block> 

mais quand je clik bouton 'showPDF' dans mon servlet, j'obtenir le fichier PDF sans image (tout le reste est là), et ces messages dans la console:

GRAVES: La Source qui a été retourné fr om résolution URI ne contient pas un InputStream pour URI: logo.jpg Nov 18, 2010 5:16:49 PM org.apache.fop.events.LoggingEventListener processEvent SEVERE: Image non trouvée. URI: logo.jpg. (Pas d'info contexte disponible)

j'ai essayé d'utiliser 'logo.jpg' au lieu de url ('logo.jpg'), mettre l'image sur différents endroits dans le dossier WebContent et en utilisant différents navigation (» ./ logo .jpg ") mais ça n'a pas marché.

Cela fonctionne très bien si je définis le chemin absolu (par exemple "d: /fop/images/logo.jpg") mais j'ai besoin de resurces dans mon application.

Lors de la recherche, j'ai trouvé que cela est lié à fopFactory.setURIResolver() et/ou userAgent.setBaseURL(). J'ai essayé quelque chose avec ça, mais je n'ai pas réussi. Je suis nouveau à la fois JSF et FOP, et cette situation d'image m'a dérangé pendant un certain temps. Est-ce que quelqu'un peut m'aider avec ceci, ou au moins diriger moi à un certain tutoriel sur "comment configurer FOP pour l'usage de chemin relatif"?

EDIT: Je ne veux pas de chemins absolus et l'application devrait fonctionner indépendamment de son emplacement sur l'ordinateur (pour être publiable). Ma recherche me dit que cela a quelque chose à voir avec la configuration de FOP, mais je ne sais pas comment le faire :)

Merci d'avance.

P.S. Cette méthode est qui est appelée à afficher PDF:

public void printExchangeRateList(ActionEvent event) { 

    BufferedOutputStream output = null; 

    FacesContext facesContext = FacesContext.getCurrentInstance(); 
    ExternalContext externalContext = facesContext.getExternalContext(); 
    HttpServletResponse response = (HttpServletResponse) externalContext.getResponse(); 

    String path = externalContext.getRealPath("/"); 


    try { 

     response.reset(); 
     response.setHeader("Content-Type", "application/pdf"); 
     output = new BufferedOutputStream(response.getOutputStream(), 10240); 

     File xsltfile = new File(path+"/pdf_transform/xslt/transformFile.xsl"); 

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

     try { 
      Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, output); 

      TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
      Transformer transformer = transformerFactory.newTransformer(new StreamSource(xsltfile)); 

      Source src = new DOMSource(makeXML()); // my method 
      Result res = new SAXResult(fop.getDefaultHandler()); 

      transformer.transform(src, res); 


     } finally { 
      if (output != null) output.close(); 
      /*try { 
       out.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      }*/ 
     } 

    } catch (Exception e) { 
     // TODO Auto-generated catch block 
    } 

    facesContext.responseComplete(); 
} 

Répondre

2

Si vous avez accès à l'URL Web pour les photos que vous pouvez l'utiliser aussi bien lors de la génération de rapports, à savoir http://localhost/images/logo.jpg.

Mais alors que j'avais encore des images localement sur le serveur web, j'inclus le chemin de l'application dans le fichier XML et utilisé comme ceci:

<xsl:variable name="base_path" select="base-path"/> 
<xsl:variable name="logo" select="companies/company/logo"/> 
<fo:external-graphic src="url({$base_path}{logo})"/> 

Lorsque la structure XML pourrait être quelque chose comme ceci:

<?xml version="1.0" encoding="UTF-8"?> 
<base-path>/path/to/app/</base-path> 
<companies> 
    <company> 
    <logo>images/company1.jpg</logo> 
    </company> 
    <company> 
    <logo>images/company2.jpg</logo> 
    </company> 
</companies> 
+0

Merci pour votre réponse. Mais ce n'est pas ce que je cherche. Lorsque vous créez un fichier XML, la chaîne "/ path/to/app /" doit ressembler à quelque chose comme "C: \ Eclipse \ workspace \ monProjet \ .. etc" (si je comprends bien). Im rendant cette application pour être publiable et toutes les données et les images xml im accédant doivent être referencend dans la portée de l'application (désolé, n'a pas écrit cela explicitement dans ma question, je vais le modifier maintenant). – Nikola

10

J'ai trouvé une solution à mon problème. Je pensais avoir essayé, mais il semble que j'ai fait une petite erreur à l'époque. Quoi qu'il en soit, avec le code suivant

FacesContext facesContext = FacesContext.getCurrentInstance(); 
ExternalContext externalContext = facesContext.getExternalContext(); 
String basePath = externalContext.getRealPath("/"); 

FopFactory fopFactory = FopFactory.newInstance(); 
fopFactory.setBaseURL(basePath); 
FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); 
foUserAgent.setBaseURL(fopFactory.getBaseURL()); 

Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, output); // for some output 

vous pouvez accéder à vos images (et d'autres ressources) de votre fichier xslt en utilisant un chemin relatif à partir du dossier WebContent de votre application. Dans mon cas, je peux accéder logo.jpg comme celui-ci

<fo:external-graphic src="url('pdf_transform/xslt/logo.jpg')"/> 

Il m'a fallu du temps pour comprendre cela, je ne comprends pas pourquoi aucun exemple avec une telle chose de base sur le net (ou je ne peux pas trouver :) les

0

J'ai eu le même problème et ont essayé cette solution:

FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); 
    Request request = RequestCycle.get().getRequest(); 
    //sort of a hack to find the path to the files that are in /img folder. 
    String baseUrl = request.getUrl().getProtocol()+"://"+request.getUrl().getHost()+":"+request.getUrl().getPort(); 
    foUserAgent.setBaseURL(baseUrl); 

Puis, j'utilisé XSL:

<fo:external-graphic src="/img/image.png" /> 

à t Si cela fonctionne, vous devriez être en mesure de voir l'image sur le protocole: // lien: port/img/image.png