【问题标题】:How to show an image on jasper report?如何在碧玉报告中显示图像?
【发布时间】:2011-02-14 08:24:29
【问题描述】:

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

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

图像 logo.jpg 与 .jrxml 位于同一目录中。只是说它对我不起作用。我用谷歌搜索了一下,发现 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)
...

我做错了什么?

谢谢!

【问题讨论】:

标签: java jasper-reports


【解决方案1】:

我是这样做的——图像是通过路径传递的:

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 传递(我不知道为什么,但&lt;image&gt; 需要将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】:

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

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

【讨论】:

    【解决方案3】:

    这就是问题所在:

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

    问题是文件解析器

    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被调用的目录并不是我拥有所有这些数据的那个目录。

    谢谢!

    【讨论】:

      【解决方案4】:

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

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

      【讨论】: