使用Batik将SVG DOM结构保存为SVG文件

时间:2018-01-23 20:23:13

标签: java dom svg batik

我使用Java中的batik动态创建和修改SVG DOM结构。 我可以在JSVGCanvas上显示创建的结构。 当进程完成时,我想导出这个DOM结构并将其保存为SVG文件。

为了创建DOM我使用了这样的东西:

DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
SVGDocument doc = (SVGDocument) impl.createDocument(svgNS, "svg", null);
Element svgRoot = doc.getDocumentElement();
svgRoot.setAttributeNS(null, "width", "300");
svgRoot.setAttributeNS(null, "height", "300");

我可以在此文档中添加内容并使用以下代码在JSVGCanvas上显示:

Element rect = doc.createElementNS(signs, "rect");
rect.setAttributeNS(null, "x", "20");
rect.setAttributeNS(null, "y", "50");
rect.setAttributeNS(null, "width", "140");
rect.setAttributeNS(null, "height", "210");
rect.setAttributeNS(svgNS, "fill", "grey");
rect.setAttributeNS(svgNS, "stroke", "black");
svgRoot.appendChild(rect);

JSVGCanvas canvas = new JSVGCanvas();
canvas.setDocumentState(ALWAYS_DYNAMIC);
canvas.setDocument(doc);

代码显示JSVGCanvas上的文档。

我的最后一步是尝试将文档另存为SVG文件。我使用SVGGraphics2D在线阅读了很多线程并在那里绘图。然后可以使用Writer导出该文件。

SVGGraphics2D graphics = new SVGGraphics2D(doc);


// Finally, stream out SVG to the standard output using UTF-8
// character to byte encoding
boolean useCSS = true; // we want to use CSS style attribute
Writer out;
try {
    out = new OutputStreamWriter(new FileOutputStream(path), "UTF-8");
graphics.stream(out, useCSS);
out.flush();
out.close();
} catch (UnsupportedEncodingException | FileNotFoundException e) {
    e.printStackTrace();
} catch (SVGGraphics2DIOException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

写入的文件缺少我修改过的DOM结构,看起来像下面的代码:

<?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 style="stroke-dasharray:none; shape-rendering:auto; font-family:'Dialog'; text-rendering:auto; fill-opacity:1; color-interpolation:auto; color-rendering:auto; font-size:12px; fill:black; stroke:black; image-rendering:auto; stroke-miterlimit:10; stroke-linecap:square; stroke-linejoin:miter; font-style:normal; stroke-width:1; stroke-dashoffset:0; font-weight:normal; stroke-opacity:1;"
xmlns="http://www.w3.org/2000/svg" 
contentScriptType="text/ecmascript" preserveAspectRatio="xMidYMid meet" 
xmlns:xlink="http://www.w3.org/1999/xlink" zoomAndPan="magnify" version="1.0" contentStyleType="text/css">
<!--Generated by the Batik Graphics2D SVG Generator-->
<defs id="genericDefs"/><g/></svg>

我是否有办法让SVGGraphics2D使用我修改后的svgRootdoc。或者还有其他方法可以保存JSVGCanvas上显示的文档。

2 个答案:

答案 0 :(得分:3)

您可以尝试将文档保存为纯xml,因为svg基本上是xml。

// you will need these imports.
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

// these 4 lines take your document doc and save it as output.svg
Transformer transformer = TransformerFactory.newInstance().newTransformer();
Result output = new StreamResult(new File("C:\\output.svg"));
Source input = new DOMSource(doc);
transformer.transform(input, output);

您可能会遇到奇怪的错误:java.lang.NoClassDefFoundError: org/apache/xml/serializer/TreeWalker解决方法是在尝试创建Transformer实例之前设置系统属性,如下所示

System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");

答案 1 :(得分:0)

根据this source而不是

try {
    out = new OutputStreamWriter(new FileOutputStream(path), "UTF-8");
    graphics.stream(out, useCSS);
}

尝试导出整个文档:

try (Writer out = new OutputStreamWriter(new FileOutputStream(path), "UTF-8")) {
    graphics.stream(doc.getDocumentElement(), out, useCSS, false);
}

确保已将矩形( Element rect )添加到svg根文档( SVGDocument doc

相关问题