如何在jasper报告上显示图像?

时间:2010-04-30 17:53:22

标签: java jasper-reports

我想在碧玉报告上显示图像。我在.jrxml上有以下内容:

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

图像logo.jpg与.jrxml位于同一目录中。只是说它对我不起作用。我google了一下,发现jasper报告考虑我放在.jrxml上作为JVM目录的相对路径,并且为了改变这一点,我需要传递一个返回文件的FileResolver作为“REPORT_FILE_RESOLVER”参数。所以,我在.java中做了以下内容(位于与.jrxml和图像相同的位置)

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);
...

哪个应该返回预期的文件,但我仍然得到

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)
...

我做错了什么?

谢谢!

4 个答案:

答案 0 :(得分:22)

我通过传递一个指定文件绝对位置的参数来完成这项工作:

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

答案 1 :(得分:21)

我这样做 - 图像通过路径传递:

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>

...或图片以InputStream传递(我不知道原因,但<image>需要将onErrorType属性设置为"Blank",否则会不工作 - 抛出异常):

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>

答案 2 :(得分:13)

问题在于:

正如我之前所说,我在同一目录中有.jrxml,logo.jpg和使用.jrxml的.java。

问题是fileResolver

FileResolver fileResolver = new FileResolver() {

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

未返回图像文件。我发现它映射到一个不同的目录而不是我期待的目录。所以,我把它改成了:

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;
        }
    }
};

这就成功了。我忘记了:

  相反,

相对路径名   必须按照解释来解释   从其他人那里获取的信息   路径名。默认情况下,类在   java.io包始终解析   相对于当前的路径名   用户目录。这个目录是   由系统属性user.dir命名,   并且通常是中的目录   Java虚拟机是哪个   调用

(摘自java api - File (Java Platform SE 6)

调用JVM的目录不是我拥有所有这些数据的目录。

谢谢!

答案 3 :(得分:9)

在报告页面中尝试declaring一个参数,例如myImg的InputStream类型。在页面上为param和image占位符声明此类型。然后,使用类似的东西从类路径中获取图像(假设图像名称为'imgName.ext',它位于名为'your.package'的包中)

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