Я хочу показать изображение на отчете о яшме. У меня есть следование .jrxml:
<image>
<reportElement x="181" y="0" width="209" height="74"/>
<imageExpression class="java.lang.String"><![CDATA["logo.jpg"]]></imageExpression>
</image>
Изображение logo.jpg находится в том же каталоге как .jrxml. Просто поместив это это не работало на меня. Я погуглил немного и узнал, что отчет о яшме рассматривает то, что я поставил .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);
...
Который должен возвратить ожидаемый файл, но я все еще получаю 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)
...
Что я делаю неправильно?
Спасибо!
Вот в чем была проблема:
Как я уже говорил, у меня есть в одной директории .jrxml, логотип.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 - File (Java Platform SE 6))
Директория, в которой вызвана JVM, не та, в которой у меня все эти данные.
Спасибо!
Я выполнил эту работу, передав параметр, определяющий абсолютное расположение файла:
<imageExpression class="java.lang.String">
<![CDATA[$P{REPORTS_DIR} + "/images/logo.jpg"]]>
</imageExpression>