web-dev-qa-db-fra.com

Comment afficher une image sur le rapport Jasper?

Je veux montrer une image sur un rapport jaspe. J'ai ce qui suit sur le .jrxml:

<image>
  <reportElement x="181" y="0" width="209" height="74"/>
  <imageExpression class="Java.lang.String"><![CDATA["logo.jpg"]]></imageExpression>
</image>

L'image logo.jpg se trouve dans le même répertoire que le .jrxml. En disant simplement que cela n'a pas fonctionné pour moi. J'ai googlé un peu et découvert que le rapport Jasper considère ce que j'ai mis sur le .jrxml comme un chemin relatif vers le répertoire JVM et que pour changer cela, je dois passer en paramètre "REPORT_FILE_RESOLVER" un FileResolver qui renvoie le fichier. J'ai donc fait ce qui suit dans mon .Java (est situé au même endroit que le .jrxml et l'image)

FileResolver fileResolver = new FileResolver() {

 @Override
 public File resolveFile(String fileName) {
  return new File(fileName);
 }
};
HashMap<String, Object> parameters = new HashMap<String, Object>();

parameters.put("REPORT_FILE_RESOLVER", fileResolver);
...

Ce qui devrait retourner le fichier attendu, mais je reçois toujours un

net.sf.jasperreports.engine.JRException: Error loading byte data : logo.jpg
    at net.sf.jasperreports.engine.util.JRLoader.loadBytes(JRLoader.Java:301)
    at net.sf.jasperreports.engine.util.JRLoader.loadBytesFromLocation(JRLoader.Java:479)
    at net.sf.jasperreports.engine.JRImageRenderer.getInstance(JRImageRenderer.Java:180)
...

Qu'est-ce que je fais mal?

Merci!

29
user297339

Voici le problème:

Comme je l'ai dit précédemment, j'ai dans le même répertoire le .jrxml, le logo.jpg et le .Java qui utilise le .jrxml.

Le truc c'est que le fileResolver

FileResolver fileResolver = new FileResolver() {

 @Override
 public File resolveFile(String fileName) {
  return new File(fileName);
 }
};

n'a pas renvoyé le fichier image. J'ai découvert qu'il était mappé sur un répertoire différent et non celui que j'attendais. Donc, je l'ai changé en:

FileResolver fileResolver = new FileResolver() {

     @Override
     public File resolveFile(String fileName) {
        URI uri;
        try {
          uri = new URI(this.getClass().getResource(fileName).getPath());
          return new File(uri.getPath());
        } catch (URISyntaxException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          return null;
        }
    }
};

Et cela a fonctionné. J'ai oublié le fait que:

Un chemin d'accès relatif, en revanche, doit être interprété en termes d'informations tirées d'un autre nom de chemin. Par défaut, les classes du package Java.io résolvent toujours les chemins d'accès relatifs par rapport au répertoire utilisateur actuel. Ce répertoire est nommé par la propriété système user.dir et est généralement le répertoire dans lequel la machine virtuelle Java a été invoquée).

(extrait de Java api - File (Java Platform SE 6) )

Le répertoire dans lequel la JVM est invoquée n'est pas celui dans lequel j'ai toutes ces données.

Merci!

13
user297339

J'ai fait ce travail en passant un paramètre spécifiant l'emplacement absolu du fichier:

<imageExpression class="Java.lang.String">
      <![CDATA[$P{REPORTS_DIR} + "/images/logo.jpg"]]>
</imageExpression>
22
Bozho

Je le fais de cette façon - l'image est passée par chemin:

HashMap<String, Object> params = new HashMap<String, Object>();
params.put("logo", ClassLoader.getSystemResource("logo.jpg").getPath());

.jrxml

<parameter name="logo" class="Java.lang.String"/>
...
<image>
    <reportElement x="0" y="1" width="100" height="37"/>
    <imageExpression><![CDATA[$P{logo}]]></imageExpression>
</image>

... ou l'image est passée comme InputStream (je ne sais pas pourquoi, mais <image> doit avoir l'attribut onErrorType défini sur "Blank", sinon cela ne fonctionne pas - lève une exception):

HashMap<String, Object> params = new HashMap<String, Object>();
params.put("logo", ClassLoader.getSystemResourceAsStream("logo.jpg"));

.jrxml

<parameter name="logo" class="Java.io.InputStream"/>
...
<image onErrorType="Blank">
    <reportElement x="0" y="1" width="100" height="37"/>
    <imageExpression><![CDATA[$P{logo}]]></imageExpression>
</image>
21
marioosh

Essayez declaring un paramètre tel que myImg de type InputStream dans votre page de rapport. Déclarez ce type à la fois pour les paramètres et les espaces réservés d'image à la page. Ensuite, récupérez l'image dans classpath en utilisant quelque chose comme (en supposant que le nom de l'image est 'imgName.ext' et qu'il se trouve dans le package nommé 'your.package')

InputStream imgInputStream = 
    this.getClass().getResourceAsStream("/your/package/imgName.ext");
parameters.put("myImg", imgInputStream);
10
Cristian