自定义图像转码器
编写一个自定义的图像转码器,它可以读取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);
}
}
导入转码器
在JRXML文件中,导入完整限定类:
<import value="com.company.jasper.ImageTranscoder"/>
应用图像转码器
像往常一样,从调色板中拖拽一个图像并放置在报表中。将其表达式设置为:
ImageTranscoder.asSVG($P{IMAGES_PATH} + $P{IMAGE_FILENAME} + ".svg")
如果你确实需要一个PNG版本,那么可以即时转码:
ImageTranscoder.asPNG($P{IMAGES_PATH} + $P{IMAGE_FILENAME} + ".svg")
HTML vs PDF
在 HTML 中,通常仍然优先使用 PNG 图像。有许多方法可以区分 HTML(PNG)和 PDF(SVG)。一种简单的方法是为两个不同的图像元素分配两个不同的关键值。例如:
<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>
然后您可以根据导出类型排除其中一个:
<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库使用Batik引擎渲染图像,所以在生成报表时利用它将SVG文件转换为PNG。
这样,SVG作为所有格式的单一来源,无论报告中使用的是PNG还是SVG文件。
请确保根据需要设置IMAGES_PATH
和IMAGE_FILENAME
参数。
HTML和Base64
使用以下方法强制嵌入图像:
<property name="net.sf.jasperreports.export.html.embed.image" value="true"/>
PNG图像变成Base64编码的字符串:
<img src="data:image/png;base64,..."/>
这将使报告加载速度更快(无需额外的图像HTTP请求),并简化架构,因为它消除了外部依赖项。也就是说,不再需要Web服务器提供图像,因为它完全嵌入。