svg - 在 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="'Dialog'" 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="'Segoe UI'" 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
>
如果有人有任何想法,我会很高兴听到它!谢谢!
解决方案
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);
}
};
}
}
推荐阅读
- actions-on-google - 在 Google Home 设备上,下一个 MediaObject 一秒钟后停止播放
- javascript - 在同一个组件内多次集成 Ng-Survey
- javascript - 对于 React Native 应用程序的以下代码示例,Jest 中的单元/组件/快照测试将是什么
- django - 使用 Nginx 部署 Django 后,将图片上传到 admin 后台并看到 PermissionError
- c# - 在 Unity3D 场景中更改 Android 状态栏颜色
- r - (Excel) 函数根据条件从表中返回特定值
- docker - devops:如何在 yaml 脚本中从 docker hub 拉取和运行 docker 映像?
- swift - 当 UITextView 需要滚动时,是否可以以某种方式跟踪状态?迅速
- jenkins - 计划构建 x 次
- ruby-on-rails - 需要从另一个表添加列