java 如何在 JasperReport 中将 svg 字节数组显示为图像?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33547588/
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
How to display a svg byte array as an image in a JasperReport?
提问by cbender
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:
我有一个保存为 a 的图像byte[]
,我想将它显示为 JasperReport 中的图像。我尝试从 Java 方法中获取数据:
public InputStream getImage(){
return new ByteArrayInputStream(getImageByteArray());
}
and
和
public Image getImage() throws IOException{
return ImageIO.read(new ByteArrayInputStream(getImageByteArray()));
}
and
和
public String getImage(){
return new String((new org.apache.commons.codec.binary.Base64()).encode(getImageByteArray()));
}
but none of them seem to be working.
但他们似乎都没有工作。
The jrxml looks like this:
jrxml 看起来像这样:
<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>
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.
我尝试的某些事情会出现异常,有些事情会打印 JasperReport,但图像应该是空白的区域。我知道图像数据在那里,因为我可以在 JSF 页面中显示它。图像数据是SVG数据。
回答by Dave Jarvis
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:
编写一个自定义图像转码器,可以读取 SVG 文件并将该资源转换为 PNG 或 SVG 文件。导出为 PDF 时,可以直接使用 SVG 文件。考虑:
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);
}
}
Import Transcoder
导入转码器
In the JRXML file, import the fully qualified class:
在 JRXML 文件中,导入完全限定的类:
<import value="com.company.jasper.ImageTranscoder"/>
Apply Image Transcoder
应用图像转码器
Drag and drop an Image from the palette onto the report, as per usual. Set its Expressionto:
像往常一样,将图像从调色板拖放到报告上。将其表达式设置为:
ImageTranscoder.asSVG($P{IMAGES_PATH} + $P{IMAGE_FILENAME} + ".svg")
If you absolutely need a PNG version, then transcode it on-the-fly:
如果您绝对需要 PNG 版本,请即时对其进行转码:
ImageTranscoder.asPNG($P{IMAGES_PATH} + $P{IMAGE_FILENAME} + ".svg")
HTML vs PDF
HTML 与 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:
对于 HTML,通常仍首选 PNG 图像。您可以采用多种方法来区分 HTML (PNG) 和 PDF (SVG)。一种简单的方法是将两个不同的键值分配给两个不同的 Image 元素。例如:
<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"/>
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.
虽然包含 PNG 图像更简单,但从 SVG 转换该 PNG 图像是一个可以避免的附加步骤。由于 JasperReports 库使用 Batik 引擎来渲染图像,因此在生成报告时利用它来将 SVG 文件转换为 PNG。
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.
这样,无论报告中使用的是 PNG 文件还是 SVG 文件,SVG 都可以作为所有格式的单一来源。
Be sure to set the IMAGES_PATH
and IMAGE_FILENAME
parameters as appropriate.
请务必适当设置IMAGES_PATH
和IMAGE_FILENAME
参数。
HTML and Base64
HTML 和 Base64
Force the image to embed using:
使用以下命令强制嵌入图像:
<property name="net.sf.jasperreports.export.html.embed.image" value="true"/>
The PNG image becomes a Base64-encoded String:
PNG 图像变成 Base64 编码的字符串:
<img src="data:image/png;base64,..."/>
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.
这将使报告加载速度更快(没有对图像的额外 HTTP 请求)并简化架构,因为它消除了外部依赖性。也就是说,不再需要网络服务器来提供图像,因为它是完全嵌入的。
回答by Aram Arabyan
Assuming that you have image bytes encoded base64, you can use following
假设您有 base64 编码的图像字节,您可以使用以下
<image>
<reportElement/>
<imageExpression>
<![CDATA[javax.imageio.ImageIO.read(new java.io.ByteArrayInputStream(new sun.misc.BASE64Decoder().decodeBuffer("/9j/4AAQ .... "))) ]]>
</imageExpression>
</image>
回答by Madushan Perera
You can try this :
你可以试试这个:
Set your image parameter (here it is img) to InputStream
将您的图像参数(这里是img)设置为InputStream
<parameter name="img" class="java.io.InputStream">
<parameterDescription><![CDATA[]]></parameterDescription>
</parameter>
Then set onErrorType="Blank"to your image element(Actually dont know the reason to this :) )
然后将onErrorType="Blank" 设置为您的图像元素(实际上不知道这样做的原因:))
<image onErrorType="Blank">
<reportElement x="2" y="4" width="119" height="62" uuid="66857471-6aa2-4ff0-be59-e2e1b0214bfc"/>
<imageExpression><![CDATA[$P{img}]]></imageExpression>
</image>
回答by cesAR
I propose a simple solution. It works, I'm using it. This way we avoid intermediate code and modifications to our application.
我提出了一个简单的解决方案。它有效,我正在使用它。这样我们就可以避免中间代码和对应用程序的修改。
We must establish the following Import:
我们必须建立以下导入:
<import value="javax.swing.ImageIcon"/>
The definition of our field for the image must be of type Objet:
图像字段的定义必须是 Objet 类型:
<field name="myImage" class="java.lang.Object"/>
And then in the body of the report, we must place the image with the following expression:
然后在报告正文中,我们必须放置具有以下表达式的图像:
<image>
<reportElement x="10" y="10" width="100" height="100" uuid="a791129e-a20d-4be3-bdcd-27528bf2edc4"/>
<imageExpression><![CDATA[(new ImageIcon((byte[])$F{foto})).getImage()]]></imageExpression>
</image>
That is all. How does the solution work? We import the javax.swing.ImageIcon
library, which allows us to create a new ImageIcon from a byte[]
, then we can convert an ImageIcon
to Image
using getImage()
.
就这些。解决方案如何运作?我们导入javax.swing.ImageIcon
库,它允许我们从 a 创建一个新的 ImageIcon byte[]
,然后我们可以将 an 转换ImageIcon
为Image
using getImage()
。
回答by whoisacat
getImage() should return byte[]
getImage() 应该返回 byte[]
I can't see what type is paramObject in your jasperreports template, but it should be String
我看不到你的 jasperreports 模板中的 paramObject 是什么类型,但它应该是 String
And the easiest way to deserialize pic without any unavailable oracle libraries is:
在没有任何不可用的 oracle 库的情况下反序列化 pic 的最简单方法是:
<imageExpression><![CDATA[javax.imageio.ImageIO.read(new java.io.ByteArrayInputStream(java.util.Base64.getDecoder().decode($F{paramObject})))]]></imageExpression>
回答by tamkhade mahesh
The definition of our field for the image must be of type Objet:
图像字段的定义必须是 Objet 类型:
And then in the body of the report, we must place the image with the following expression:
然后在报告正文中,我们必须放置具有以下表达式的图像:
this code is work for me....
这段代码对我有用....