繁体   English   中英

显示数据库中的图像。 获取 net.sf.jasperreports.engine.JRException:图像读取失败

[英]Show image from database. Getting net.sf.jasperreports.engine.JRException: Image read failed

我正在尝试从我的数据库中提取图像作为二进制数据并将其插入到Jasper Reports报告中。

使用Jaspersoft Studio ,我在我的领域中阅读并将其类型更改为 java.awt.Image。 然后,我将一个图像元素添加到我的报告中并将表达式更改为 ${Attr1_icon} 当我尝试编译时,我得到:

net.sf.jasperreports.engine.JRException: net.sf.jasperreports.engine.JRException: Unable to get value for field 'Attr1_icon' of class 'java.awt.Image'
at com.jaspersoft.studio.editor.preview.view.control.ReportControler.fillReport(ReportControler.java:482)
at com.jaspersoft.studio.editor.preview.view.control.ReportControler.access$18(ReportControler.java:457)
at com.jaspersoft.studio.editor.preview.view.control.ReportControler$4.run(ReportControler.java:347)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Caused by: net.sf.jasperreports.engine.JRException: Unable to get value for field 'Attr1_icon' of class 'java.awt.Image'
at net.sf.jasperreports.engine.JRResultSetDataSource.getFieldValue(JRResultSetDataSource.java:319)
at net.sf.jasperreports.engine.fill.JRFillDataset.setOldValues(JRFillDataset.java:1356)
at net.sf.jasperreports.engine.fill.JRFillDataset.next(JRFillDataset.java:1257)
at net.sf.jasperreports.engine.fill.JRFillDataset.next(JRFillDataset.java:1233)
at net.sf.jasperreports.engine.fill.JRBaseFiller.next(JRBaseFiller.java:1577)
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:149)
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:932)
at net.sf.jasperreports.engine.fill.BaseFillHandle$ReportFiller.run(BaseFillHandle.java:120)
at java.lang.Thread.run(Unknown Source)
Caused by: net.sf.jasperreports.engine.JRException: Image read failed.
at net.sf.jasperreports.engine.util.JRJdk14ImageReader.readImage(JRJdk14ImageReader.java:73)
at net.sf.jasperreports.engine.util.JRImageLoader.loadAwtImageFromBytes(JRImageLoader.java:167)
at net.sf.jasperreports.engine.JRResultSetDataSource.getFieldValue(JRResultSetDataSource.java:309)
Caused by: net.sf.jasperreports.engine.JRException: Image read failed.
at net.sf.jasperreports.engine.util.JRJdk14ImageReader.readImage(JRJdk14ImageReader.java:73)
at net.sf.jasperreports.engine.util.JRImageLoader.loadAwtImageFromBytes(JRImageLoader.java:167)
at net.sf.jasperreports.engine.JRResultSetDataSource.getFieldValue(JRResultSetDataSource.java:309)

导致此异常的源代码来自 JRJdk14ImageReader.java 中的这里:

public Image readImage(byte[] bytes) throws JRException {
    InputStream bais = new ByteArrayInputStream(bytes);

    Image image = null;
    try {
        image = ImageIO.read(bais);
    } catch (Exception e) {
        throw new JRException(e);
    } finally {
        try {
            bais.close();
        } catch (IOException e) {
        }
    }

    if (image == null) {
        throw new JRException("Image read failed."); // Line 73
    }

    return image;
}

因此,您可以看到图像为空。 但我不明白为什么。 我已经验证数据确实存在。 如果我将数据类型更改为字符串并将其添加到普通文本字段,它会打印二进制数据。 所以,我不认为它是空的,因为传入的数据是空的。

Javadoc

Returns a BufferedImage as the result of decoding a supplied InputStream with an
ImageReader chosen automatically from among those currently registered. The InputStream
is wrapped in an ImageInputStream. If no registered ImageReader claims to be able to
read the resulting stream, null is returned.

所以我猜没有注册ImageReader? 我怎么能通过Jaspersoft Studio解决类似的问题?

编辑:我已经尝试按照此处的建议将 java.io.InputStream 用于类类型,但这会导致相同的错误。 的种类。 一个很大的区别是,在Jaspersoft Studio 中,您可以将图像设置为在出现错误时显示为空白。 如果我使用 java.awt.Image,则此设置不执行任何操作。 我仍然收到错误并且报告没有建立。 如果我使用 java.io.InputStream,报告会生成,但图像是空白的。 如果我打开错误报告,我会得到类似的堆栈跟踪,但并不完全相同:

net.sf.jasperreports.engine.JRRuntimeException: net.sf.jasperreports.engine.JRException: Image read failed.
at net.sf.jasperreports.engine.export.draw.PrintDrawVisitor.visit(PrintDrawVisitor.java:143)
at net.sf.jasperreports.engine.export.draw.PrintDrawVisitor.visit(PrintDrawVisitor.java:1)
at net.sf.jasperreports.engine.fill.JRTemplatePrintImage.accept(JRTemplatePrintImage.java:451)
at net.sf.jasperreports.engine.export.draw.FrameDrawer.draw(FrameDrawer.java:251)
at net.sf.jasperreports.engine.export.draw.FrameDrawer.draw(FrameDrawer.java:199)
at net.sf.jasperreports.engine.export.JRGraphics2DExporter.exportPage(JRGraphics2DExporter.java:273)
at net.sf.jasperreports.engine.export.JRGraphics2DExporter.exportReportToGraphics2D(JRGraphics2DExporter.java:246)
at net.sf.jasperreports.engine.export.JRGraphics2DExporter.exportReport(JRGraphics2DExporter.java:184)
at net.sf.jasperreports.eclipse.viewer.ViewerCanvas.renderPage(ViewerCanvas.java:369)
at net.sf.jasperreports.eclipse.viewer.ViewerCanvas.refresh(ViewerCanvas.java:344)
at net.sf.jasperreports.eclipse.viewer.ViewerCanvas$2.viewerStateChanged(ViewerCanvas.java:118)
at net.sf.jasperreports.eclipse.viewer.ReportViewer.fireViewerModelChanged(ReportViewer.java:383)
at net.sf.jasperreports.eclipse.viewer.ReportViewer.setPageIndex(ReportViewer.java:297)
at com.jaspersoft.studio.editor.preview.view.report.swt.SWTViewer.setJRPRint(SWTViewer.java:125)
at com.jaspersoft.studio.editor.preview.view.report.swt.SWTViewer.setJRPRint(SWTViewer.java:112)
at com.jaspersoft.studio.editor.preview.PreviewJRPrint.switchRightView(PreviewJRPrint.java:226)
at com.jaspersoft.studio.editor.preview.PreviewContainer.switchRightView(PreviewContainer.java:247)
at com.jaspersoft.studio.editor.preview.PreviewJRPrint$3.switchView(PreviewJRPrint.java:194)
at com.jaspersoft.studio.editor.preview.PreviewJRPrint$1.run(PreviewJRPrint.java:153)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4144)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3761)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at com.jaspersoft.studio.rcp.intro.Application.start(Application.java:97)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
Caused by: net.sf.jasperreports.engine.JRException: Image read failed.
at net.sf.jasperreports.engine.util.JRJdk14ImageReader.readImage(JRJdk14ImageReader.java:73)
at net.sf.jasperreports.engine.util.JRImageLoader.loadAwtImageFromBytes(JRImageLoader.java:167)
at net.sf.jasperreports.engine.JRImageRenderer.getImage(JRImageRenderer.java:407)
at net.sf.jasperreports.engine.JRImageRenderer.getDimension(JRImageRenderer.java:482)
at net.sf.jasperreports.engine.RenderableUtil.getOnErrorRendererForDimension(RenderableUtil.java:264)
at net.sf.jasperreports.engine.export.draw.ImageDrawer.draw(ImageDrawer.java:116)
at net.sf.jasperreports.engine.export.draw.PrintDrawVisitor.visit(PrintDrawVisitor.java:134)

不过,正如您所看到的,根本原因仍然来自 JRJdk14ImageReader.java 第 73 行。

其他一些可能有用的信息:

数据作为 LONG BINARY 存储在数据库中(使用 Sybase)。
图像是 base64 编码的。

这个问题阻碍了我完成我的项目,截止日期很快。 任何帮助都会很棒。

编辑 2:我将我的Jaspersoft Studio版本从 5.5 更新到 5.6,但这没有任何作用。

同样,对于我尝试的表达式 javax.imageio.ImageIO.read($F{Attr1_icon}) 这实际上不会产生任何错误,但图像是空白的。

尽管我在问题中发布了它,但我完全忽略了图像是 Base64 编码的事实,这意味着它是一个字符串。 照原样,Jasper 无法使用此值,因此必须对其进行解码。 这可以通过以下两种方式之一完成:

将表达式更改为:

new java.io.ByteArrayInputStream(javax.xml.DatatypeConverter.parseBase64Binary($F{ImageField}))

或者简单地将字符串转换为数据库中的二进制。 在 Sybase 中,这是 base64_decode 函数。 转换后,您只需将类型更改为 java.io.InputStream 即可。

net.sf.jasperreports.engine.jreexception:图像读取失败。
我正在使用 jasperreports 6.1.0。
对于这个错误,我对图像属性进行了更改:

 lazy : checked,
 Using cache : false,
 on Error Type: Blank

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM