首页 > 解决方案 > 在 JasperReports 中使用内联 base64 图像解析 Batik SVG

问题描述

我一直在尝试使用 JasperReports 中的蜡染渲染器解析以下 .svg 文件(在“Inkscape”上运行良好)(尽管我不知道这是否主要是蜡染问题)

我正在使用 Batik 1.13 和 JasperReports 6.13 以及它的“net.sf.jasperreports.renderers.SimpleDataRenderer”。此渲染器使用蜡染。

尝试使用 base64 图像渲染文件时收到以下错误代码:

java.io.IOException:字节数组不是可识别的图像格式。在 com.lowagie.text.Image.getInstance(Unknown Source) 在 net.sf.jasperreports.engine.export.JRPdfExporter$InternalImageProcessor.processImageRetainShape(JRPdfExporter.java:1992) 在 net.sf.jasperreports.engine.export.JRPdfExporter$ InternalImageProcessor.process(JRPdfExporter.java:1787) 在 net.sf.jasperreports.engine.export.JRPdfExporter$InternalImageProcessor.access$300(JRPdfExporter.java:1713) 在 net.sf.jasperreports.engine.export.JRPdfExporter.exportImage(JRPdfExporter .java:1653) 在 net.sf.jasperreports.engine.export.JRPdfExporter.exportElements(JRPdfExporter.java:1267) 在 net.sf.jasperreports.engine.export.JRPdfExporter.exportPage(JRPdfExporter.java:1210) 在 net. sf.jasperreports.engine.export.JRPdfExporter.exportReportToStream(JRPdfExporter.java:1074) 在 net.sf.jasperreports。106) 在 org.eclipse.net4j.signal.IndicationWithResponse.execute(IndicationWithResponse.java:75) 在 org.eclipse.net4j.signal.IndicationWithMonitoring 的 org.eclipse.net4j.signal.Signal.doOutput(Signal.java:346) .execute(IndicationWithMonitoring.java:66) at org.eclipse.net4j.signal.Signal.runSync(Signal.java:283) at org.eclipse.net4j.signal.Signal.run(Signal.java:162) at java。 util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 在 java.lang.Thread.run(Thread.java:745) 18: 01:22,388 错误 [ReportCommand] 导出到 java.io.ByteArrayOutputStream net.sf.jasperreports.engine.JRException 时发生错误:java.io.IOException:字节数组不是可识别的图像格式。在 net.sf.jasperreports.engine.export.JRPdfExporter$InternalImageProcessor。IndicationWithMonitoring.execute(IndicationWithMonitoring.java:66) at org.eclipse.net4j.signal.Signal.runSync(Signal.java:283) at org.eclipse.net4j.signal.Signal.run(Signal.java:162) at java .util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) 引起by:java.io.IOException:字节数组不是可识别的图像格式。at com.lowagie.text.Image.getInstance(Unknown Source) at net.sf.jasperreports.engine.export.JRPdfExporter$InternalImageProcessor.processImageRetainShape(JRPdfExporter.java:1992) ... 还有 23 个 [错误] net.sf.jasperreports .engine.JRException:java.io.IOException:字节数组不是可识别的图像格式。!ENTRY enco.sox2.cdo.server.reports 4 0 2020-08-14 18:01:22.390 !MESSAGE net.sf。jasperreports.engine.JRException:java.io.IOException:字节数组不是可识别的图像格式。!STACK 0 enco.sox2.reportmanager.ReportException:net.sf.jasperreports.engine.JRException:java.io.IOException:字节数组不是可识别的图像格式。在 enco.sox2.reportmanager.ReportCommand.export(ReportCommand.java:195) 在 enco.sox2.reportmanager.ReportCommand.export(ReportCommand.java:159) 在 enco.sox2.reportmanager.ReportManager.generateReportToStream(ReportManager.java:175) )在 enco.sox2.cdo.server.reports.service.CdoReportService.generateReportToStream(CdoReportService.java:87) 在 enco.sox2.workspace.cdo.server.internal.CreateReportIndication.responding(CreateReportIndication.java:103) 在组织。 eclipse.emf.cdo.server.internal.net4j.protocol.CDOServerIndicationWithMonitoring.responding(CDOServerIndicationWithMonitoring.java: 字节数组不是可识别的图像格式。在 net.sf.jasperreports.engine.export.JRPdfExporter$InternalImageProcessor.process(JRPdfExporter.java:1787) 在 net.sf 的 net.sf.jasperreports.engine.export.JRPdfExporter$InternalImageProcessor.processImageRetainShape(JRPdfExporter.java:1997) .jasperreports.engine.export.JRPdfExporter$InternalImageProcessor.access$300(JRPdfExporter.java:1713) 在 net.sf.jasperreports.engine.export.JRPdfExporter.exportImage(JRPdfExporter.java:1653) 在 net.sf.jasperreports.engine。 export.JRPdfExporter.exportElements(JRPdfExporter.java:1267) 在 net.sf.jasperreports.engine.export.JRPdfExporter.exportPage(JRPdfExporter.java:1210) 在 net.sf.jasperreports.engine.export.JRPdfExporter.exportReportToStream(JRPdfExporter. java:1074) 在 net.sf.jasperreports.engine.export.JRPdfExporter.exportReport(JRPdfExporter.java:691) 在 enco。sox2.reportmanager.ReportCommand.export(ReportCommand.java:192) ... 15 更多原因:java.io.IOException:字节数组不是可识别的图像格式。at com.lowagie.text.Image.getInstance(Unknown Source) at net.sf.jasperreports.engine.export.JRPdfExporter$InternalImageProcessor.processImageRetainShape(JRPdfExporter.java:1992) ... 还有 23 个

这里的 .svg 文件供参考。

    <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN'
          'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'>
<svg fill-opacity="1" xmlns:xlink="http://www.w3.org/1999/xlink" color-rendering="auto" color-interpolation="auto" text-rendering="auto" stroke="black" stroke-linecap="square" width="1000" stroke-miterlimit="10" shape-rendering="auto" stroke-opacity="1" fill="black" stroke-dasharray="none" font-weight="normal" stroke-width="1" height="385" xmlns="http://www.w3.org/2000/svg" font-family="&apos;Dialog&apos;" font-style="normal" stroke-linejoin="miter" font-size="12" stroke-dashoffset="0" image-rendering="auto"
><!--Generated by the Batik Graphics2D SVG Generator--><defs id="genericDefs"
  /><g
  ><defs id="defs1"
    ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath1"
      ><path d="M659 58 L701 58 L701 91 L659 91 L659 58 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath2"
      ><path d="M659 88 L701 88 L701 121 L659 121 L659 88 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath3"
      ><path d="M319 88 L361 88 L361 91 L319 91 L319 88 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath4"
      ><path d="M19 52 L321 52 L321 128 L19 128 L19 52 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath5"
      ><path d="M24 57 L38 57 L38 89 L24 89 L24 57 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath6"
      ><path d="M-1 -8 L9 -8 L9 24 L-1 24 L-1 -8 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath7"
      ><path d="M-1 -8 L17 -8 L17 24 L-1 24 L-1 -8 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath8"
      ><path d="M55 57 L289 57 L289 89 L55 89 L55 57 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath9"
      ><path d="M298 57 L316 57 L316 89 L298 89 L298 57 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath10"
      ><path d="M24 87 L316 87 L316 123 L24 123 L24 87 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath11"
      ><path d="M26 89 L40 89 L40 121 L26 121 L26 89 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath12"
      ><path d="M54 89 L297 89 L297 121 L54 121 L54 89 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath13"
      ><path d="M699 39 L1001 39 L1001 81 L699 81 L699 39 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath14"
      ><path d="M704 44 L718 44 L718 76 L704 76 L704 44 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath15"
      ><path d="M735 44 L991 44 L991 76 L735 76 L735 44 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath16"
      ><path d="M699 99 L1001 99 L1001 141 L699 141 L699 99 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath17"
      ><path d="M704 104 L718 104 L718 136 L704 136 L704 104 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath18"
      ><path d="M735 104 L985 104 L985 136 L735 136 L735 104 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath19"
      ><path d="M359 69 L661 69 L661 111 L359 111 L359 69 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath20"
      ><path d="M364 74 L378 74 L378 106 L364 106 L364 74 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath21"
      ><path d="M395 74 L632 74 L632 106 L395 106 L395 74 Z"
      /></clipPath
      ><clipPath clipPathUnits="userSpaceOnUse" id="clipPath22"
      ><path d="M638 74 L656 74 L656 106 L638 106 L638 74 Z"
      /></clipPath
    ></defs
    ><g fill="silver" font-family="&apos;Segoe UI&apos;" stroke-linecap="butt" stroke="silver"
    ><line y2="59" fill="none" x1="660" clip-path="url(#clipPath1)" x2="699" y1="89"
      /><line y2="119" fill="none" x1="660" clip-path="url(#clipPath2)" x2="699" y1="89"
      /><line y2="89" fill="none" x1="320" clip-path="url(#clipPath3)" x2="359" y1="89"
      /><rect x="20" y="53" clip-path="url(#clipPath4)" fill="white" width="300" rx="4" ry="4" height="74" stroke="none"
      /><rect x="20" y="53" clip-path="url(#clipPath4)" fill="none" width="299" rx="4" ry="4" height="73" stroke="black"
      /><rect x="25" y="58" clip-path="url(#clipPath5)" fill="white" width="12" height="30" stroke="none"
      /><image x="0" y="0" transform="matrix(1,0,0,1,27,65)" clip-path="url(#clipPath6)" fill="white" width="8" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAQCAYAAAArij59AAAAXklEQVR42mP8//8/
Az7AxEAADFoFBw4c+N/Z2fkfq4J9+/b9z8nJYZg3bx6mCSDJvLw8Bl1dXUwrkCUZ
GRlRFeCSBAEWEHH69GmG379/M5w7dw4ukZCQAKYZB0FcAADWfSpLwQBSHgAAAABJRU5ErkJggg==" height="16" stroke="white" preserveAspectRatio="none"
      /><rect x="27" y="58" clip-path="url(#clipPath5)" fill="none" width="7" height="29" stroke="black"
      /><image x="0" y="0" transform="matrix(1,0,0,1,37,65)" clip-path="url(#clipPath7)" fill="black" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACq0lEQVR42pWTXUhT
YRjH/+/Z2dnmx5riMKeVJUsoTcsSJENliWAXeWFU0EUgBEFREEVfN14UDEESpGAZ
JF1ESoiEZk3TmoXkB1oZ5pxihLra3If7cOfM83YWDuZAof/dec///J7/85znJViX
6DYVI7hUTQPzCqxYB2SFH94gTgsNXG1a+ZkTjDoThFOBhoUu8u9j56MbxG25D8+g
DGEfQAn8Tp/J8Tt0Mfs8xChg6BIe5B5Mv6JQawCFGiBMEyvajcXE1WP8PJKAzvF6
iCJF+Z4ulGa8vLC4SD5JtNYoIMQjKCzbwQXsgCoJNCE1yFDfbA1cAxj/lY+xmcwI
Fab+U2BZwG6ntbEthAWIgQDgkkJ6PTzWfB4VC980h7AXCjaMZb8G1j/JyM14ByZS
0aPOpi8e10G3o/fqE5O/eeZjSenSQuNulX+FYXnoc/hBlnomzSD0WsDvh2HXM5ws
mUTD6zpMTBLo51Py0Nragqoqhz5Na+v/rjN2WKwdsalkl6uDs/ZF6HTcSNGx3FFo
lbPIEnvgMgs4anGDmbYCw8MJRwoOpJ7dm3PdaLH4NgAa2imaOvGqbGfYNj21RqeG
6Yq2V8g6PiG9jM4/GATxeORKt/tr/dzcRCyAxP/rFqCsGBjIX3+mUZNcLg1ROC0H
2mL9TDxgWQo8CnxxxlQQIkvEcQ5bQWF3vF8Wf2CW/EXAextwOARkRUA/gLGH+/Ns
gTt3A93tbd+2bCGqW1I6aRUOSTsnSwFGm7enJ9cUZXTcPFchUo2WEmUiqMA/3wCo
qKwk/WYz3Qz6tkR1b58+7bYiKREkSQOGUzZumAEjisRgMGyaimVYRgxJjXkdgM8F
8EGejTX09fWJ2EIBnsoXnAI4OYHM60LKtlU5i/9QiBeHftpXnzJSRlYav3Sdh/4C
CCwZRQKg7fwAAAAASUVORK5CYII=" height="16" stroke="black" preserveAspectRatio="none"
      />
    ></g
  ></g
></svg
>

如果有人有任何想法,我会很高兴听到它!谢谢!

标签: svgjasper-reportsbatik

解决方案


SVG 无法渲染,因为 Batik 依赖于java.net.URL加载嵌入的图像,并且data:Java 中不支持该方案。

要渲染 SVG,您需要URLStreamHandler为该方案添加一个实现,并通过系统属性data:注册它。java.protocol.handler.pkgs

URL 处理程序可以使用例如jdatauri(您也可以在 Maven 上找到)。

要注册它,您需要运行 Java-Djava.protocol.handler.pkgs=net.myself.handlers

package net.myself.handlers.data;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.nio.charset.StandardCharsets;

import com.github.ooxi.jdatauri.DataUri;

public class Handler extends URLStreamHandler {
    public Handler() {
    }

    @Override
    protected URLConnection openConnection(URL u) throws IOException {
        DataUri dataUri = DataUri.parse(u.toString(), StandardCharsets.UTF_8);
        byte[] data = dataUri.getData();
        return new URLConnection(u) {
            @Override
            public void connect() {             
            }

            @Override
            public InputStream getInputStream() {
                return new ByteArrayInputStream(data);
            }
        };
    }
}

推荐阅读