Подтвердить что ты не робот

Как показать изображение в отчете о яшме?

Я хочу показать изображение в отчете о яшме. У меня есть следующее:.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, и что для его изменения мне нужно передать параметр REPORT_FILE_RESOLVER FileResolver, который возвращает файл. Итак, я сделал следующее в моей .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)
...

Что я делаю неправильно?

Спасибо!

4b9b3361

Ответ 1

Вот проблема:

Как я уже говорил ранее, у меня есть тот же каталог .jrxml, logo.jpg и .java, который использует .jrxml.

Дело в том, что 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 - Файл (платформа Java SE 6))

Каталог, в котором вызывается JVM, не является тем, у меня есть все эти данные.

Спасибо!

Ответ 2

Я выполнил эту работу, передав параметр, определяющий абсолютное расположение файла:

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

Ответ 3

Я делаю это так: изображение передается по пути:

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>

Ответ 4

Попробуйте объявить параметр, например myImg типа InputStream, на странице отчета. Объявите этот тип как для заполнитель параметров, так и для изображения на странице. Затем возьмите изображение из пути к классам, используя что-то вроде (если имя изображения является "imgName.ext", и оно находится в пакете с именем "your.package" )

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