在JasperReport中将字节数组显示为图像 [英] Display a byte array as an image in a JasperReport

查看:311
本文介绍了在JasperReport中将字节数组显示为图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将图像保存为 byte [] ,我想将其显示为JasperReport中的图像。我尝试从Java方法获取数据:

I have an image saved as a byte[] and I would like to display it as an image in a JasperReport. I have tried getting the data from Java methods:

public InputStream getImage(){
  return new ByteArrayInputStream(getImageByteArray());
}

public Image getImage() throws IOException{
    return ImageIO.read(new ByteArrayInputStream(getImageByteArray()));
}

public String getImage(){
  return new String((new org.apache.commons.codec.binary.Base64()).encode(getImageByteArray()));
}

但它们似乎都没有工作。

but none of them seem to be working.

jrxml如下所示:

The jrxml looks like this:

<image hAlign="Center" vAlign="Middle" isUsingCache="true" isLazy="true">
   <reportElement positionType="Float" x="0" y="0" width="164" height="32" isRemoveLineWhenBlank="true" isPrintWhenDetailOverflows="true" uuid="c63c84a8-41c7-4ca3-8451-751d43fa8a9e"/>
   <imageExpression><![CDATA[$P{paramObject}.getImage()]]></imageExpression>
</image>

我尝试的一些事情得到异常,有些打印JasperReport但是图像所在的区域是空白。
我知道图像数据存在,因为我可以在JSF页面中显示它。
图像数据是SVG数据。

Some of things I try get exceptions and some print the JasperReport but the area where the image is supposed to be is blank. I know the image data is there because I can display it in a JSF page. The image data is SVG data.

推荐答案

自定义图像转码器



编写一个自定义图像转码器,它可以读取SVG文件并将该资源转换为PNG或SVG文件。以PDF格式导出时,可以直接使用SVG文件。考虑:

Custom Image Transcoder

Write a custom image transcoder that can read an SVG file and transform that resource into a PNG or SVG file. When exporting as PDF, it is okay to use an SVG file directly. Consider:

import java.awt.Color;
import java.io.*;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.util.JRLoader;
import org.apache.batik.transcoder.*;
import static org.apache.batik.transcoder.image.ImageTranscoder.*;
import org.apache.batik.transcoder.image.PNGTranscoder;

public class ImageTranscoder {
    public static InputStream asSVG(final String file) throws JRException {
        return new ByteArrayInputStream(load(file));
    }

    public static InputStream asPNG(final String file)
            throws TranscoderException, JRException {
        return asPNG(load(file));
    }

    public static InputStream asPNG(final byte[] svg)
            throws TranscoderException {
        final ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
        final ByteArrayInputStream inBytes = new ByteArrayInputStream(svg);

        final TranscoderInput input = new TranscoderInput(inBytes);
        final TranscoderOutput output = new TranscoderOutput(outBytes);
        final PNGTranscoder transcoder = new PNGTranscoder();

        transcoder.addTranscodingHint(KEY_BACKGROUND_COLOR, Color.white);
        transcoder.addTranscodingHint(KEY_FORCE_TRANSPARENT_WHITE, true);
        transcoder.transcode(input, output);

        final byte[] bytes = outBytes.toByteArray();
        return new ByteArrayInputStream(bytes);
    }

    private static byte[] load(final String file) throws JRException {
        return JRLoader.loadBytesFromResource(file);
    }
}



导入转码器



在JRXML文件中,导入完全限定的类:

Import Transcoder

In the JRXML file, import the fully qualified class:

<import value="com.company.jasper.ImageTranscoder"/>



应用图像转码器



拖放按照惯例,从调色板到报告的图像。将表达式设置为:

ImageTranscoder.asSVG($P{IMAGES_PATH} + $P{IMAGE_FILENAME} + ".svg")

如果你绝对需要一个PNG版本,那么在它上面进行转码-fly:

If you absolutely need a PNG version, then transcode it on-the-fly:

ImageTranscoder.asPNG($P{IMAGES_PATH} + $P{IMAGE_FILENAME} + ".svg")



HTML与PDF



使用HTML,通常是PNG图像仍然是首选。您可以采用多种方法来区分HTML(PNG)和PDF(SVG)。一种简单的方法是将两个不同的键值分配给两个不同的Image元素。例如:

HTML vs PDF

With HTML, typically PNG images are still preferred. There are a number of approaches you can take to differentiate HTML (PNG) from PDF (SVG). A simple way is to assign two different key values to two different Image elements. For example:

<image scaleImage="RetainShape" onErrorType="Blank">
    <reportElement key="IMAGE_PNG"/>
    <imageExpression><![CDATA[ImageTranscoder.asPNG(...)]]></imageExpression>
</image>
<image scaleImage="RetainShape" onErrorType="Blank">
    <reportElement key="IMAGE_SVG"/>
    <imageExpression><![CDATA[ImageTranscoder.asSVG(...)]]></imageExpression>
</image>

然后您可以根据导出类型排除其中一个:

Then you can exclude one or the other based on the export type:

<property name="net.sf.jasperreports.export.html.exclude.key.IMAGE_SVG"/>
<property name="net.sf.jasperreports.export.pdf.exclude.key.IMAGE_PNG"/>



摘要



虽然它更简单包括PNG图像,从SVG转换PNG图像是可以避免的额外步骤。由于JasperReports Library使用Batik引擎渲染图像,因此在生成报告时利用它将SVG文件转换为PNG。

Summary

While it is simpler to include a PNG image, converting that PNG image from SVG is an additional step that can be avoided. Since the JasperReports Library uses the Batik engine for rendering images, leverage it to convert an SVG file to PNG when the report is generated.

这样,SVG就像一个所有格式的单一来源,无论报告中是否使用了PNG或SVG文件。

This way, the SVG serves as a single source for all formats, regardless of whether a PNG or SVG file is used in the report.

请务必设置 IMAGES_PATH IMAGE_FILENAME 适当的参数。

Be sure to set the IMAGES_PATH and IMAGE_FILENAME parameters as appropriate.

强制图像嵌入使用:

<property name="net.sf.jasperreports.export.html.embed.image" value="true"/>

PNG图像成为Base64编码的字符串:

The PNG image becomes a Base64-encoded String:

<img src="data:image/png;base64,..."/>

这将使报告加载速度更快(对图像没有额外的HTTP请求)并简化体系结构,因为它消除了外部依赖。也就是说,不再需要Web服务器来提供图像,因为它是完全嵌入的。

This will make the report load a bit faster (no extra HTTP request for the image) and simplify the architecture as it eliminates an external dependency. That is, a web server is no longer required to serve the image, since it is wholly embedded.

这篇关于在JasperReport中将字节数组显示为图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆