Java 如何在碧玉报告上显示图像?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2746561/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 12:23:23  来源:igfitidea点击:

How to show an image on jasper report?

javajasper-reports

提问by

I want to show an image on a jasper report. I have the following on the .jrxml:

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

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

The image logo.jpg is in the same directory as the .jrxml. By just putting that it didn't work for me. I googled a bit and found out that jasper report considers what i put on the .jrxml as a relative path to the JVM directory and that to change this I need to pass as a "REPORT_FILE_RESOLVER" parameter a FileResolver that returns the file. So, I did the following in my .java (is located in same place as the .jrxml and the 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);
...

Which should return the expected file, but I still get a

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

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

What am I doing wrong?

我究竟做错了什么?

Thanks!

谢谢!

采纳答案by Bozho

Here was the problem:

这是问题:

As I said previously I have in the same directory the .jrxml, the logo.jpg and the .java that uses the .jrxml.

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

The thing is that the fileResolver

问题是 fileResolver

FileResolver fileResolver = new FileResolver() {

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

didn't returned the image file. I found out it mapped on to a different directory and not the one I was expecting. So, I changed it to:

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

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

And that worked out. I forgot the fact that:

这成功了。我忘记了一个事实:

A relative pathname, in contrast, must be interpreted in terms of information taken from some other pathname. By default the classes in the java.io package always resolve relative pathnames against the current user directory. This directory is named by the system property user.dir, and is typically the directory in which the Java virtual machine was invoked.

相反,相对路径名必须根据取自其他路径名的信息进行解释。默认情况下,java.io 包中的类总是针对当前用户目录解析相对路径名。该目录由系统属性 user.dir 命名,通常是调用 Java 虚拟机的目录。

(taken from the java api - File (Java Platform SE 6))

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

The directory in which the JVM is invoked is not the one I have all this data.

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

Thanks!

谢谢!

回答by Bozho

I've made this work by passing a parameter specifying the absolute location of the file:

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

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

回答by Cristian

Try declaringa param such as myImg of type InputStreamin your report page. Declare this type both for param and image placeholder on page. Then, grab the image from classpath using something like (assuming image name is 'imgName.ext' and it is in the package named 'your.package')

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

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

回答by marioosh

I do it this way - image is passed by path:

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

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

.jrxml

.jrxml

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

...or image is passed as InputStream(I don't know why, but <image>need to have onErrorTypeattribute set to "Blank", otherwise it does not work - throws exception):

...或图像被传递为InputStream(我不知道为什么,但<image>需要将onErrorType属性设置为"Blank",否则它不起作用 - 抛出异常):

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

.jrxml

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