在使用D3.js(IE,safari和chrome)创建SVG后,如何保存/导出SVG文件?

Van*_*iza 54 javascript jquery svg d3.js

我目前有一个使用D3的网站,我希望用户可以选择将SVG保存为SVG文件.我正在使用crowbar.js来做这件事,但它只适用于chrome.safari没有任何反应,IE click()在crowbar.js中使用的方法提供了访问权限,无法下载文件.

var e = document.createElement('script'); 

if (window.location.protocol === 'https:') { 
    e.setAttribute('src', 'https://raw.github.com/NYTimes/svg-crowbar/gh-pages/svg-crowbar.js'); 
} else { 
    e.setAttribute('src', 'http://nytimes.github.com/svg-crowbar/svg-crowbar.js'); 
}

e.setAttribute('class', 'svg-crowbar'); 
document.body.appendChild(e);
Run Code Online (Sandbox Code Playgroud)

如何在safari,IE和chrome中基于我网站上的SVG元素下载SVG文件?

def*_*977 55

有5个步骤.我经常使用这种方法输出内联svg.

  1. 获取内联svg元素输出.
  2. 通过XMLSerializer获取svg源代码.
  3. 添加svg和xlink的名称空间.
  4. 通过encodeURIComponent方法构造svg的url数据方案.
  5. 将此url设置为某个"a"元素的href属性,然后右键单击此链接以下载svg文件.

//get svg element.
var svg = document.getElementById("svg");

//get svg source.
var serializer = new XMLSerializer();
var source = serializer.serializeToString(svg);

//add name spaces.
if(!source.match(/^<svg[^>]+xmlns="http\:\/\/www\.w3\.org\/2000\/svg"/)){
    source = source.replace(/^<svg/, '<svg xmlns="http://www.w3.org/2000/svg"');
}
if(!source.match(/^<svg[^>]+"http\:\/\/www\.w3\.org\/1999\/xlink"/)){
    source = source.replace(/^<svg/, '<svg xmlns:xlink="http://www.w3.org/1999/xlink"');
}

//add xml declaration
source = '<?xml version="1.0" standalone="no"?>\r\n' + source;

//convert svg source to URI data scheme.
var url = "data:image/svg+xml;charset=utf-8,"+encodeURIComponent(source);

//set url value to a element's href attribute.
document.getElementById("link").href = url;
//you can download svg file by right click menu.
Run Code Online (Sandbox Code Playgroud)

  • 请参阅http://www.w3.org/TR/SVG11/styling.html#ReferencingExternalStyleSheets所以,添加<?xml-stylesheet href ="xxx.css"type ="text/css"?>并转换,但在此如果svg文件不是独立的. (4认同)
  • 注意:这不再适用于Chrome或Firefox,因为它们现在都会在顶层使用时阻止SVG的数据URI. (4认同)
  • 这个示例是简单的案例。如果您通过链接元素通过外部 css 文件使用 css 样式,则 svg 和样式表的链接已损坏。因此,这个问题将通过将样式数据附加到内联 svg 来解决。 (2认同)

Dav*_*ist 44

我知道这已经得到了回答,这个答案在大多数时候都很有用.但是我发现如果svg图像很大(大约1MB),它在Chrome(但不是Firefox)上失败了.如果您回到使用Blob构造,它就可以工作,如此此处所述.唯一的区别是类型参数.在我的代码中,我想按一下按钮为用户下载svg,我完成了:

var svgData = $("#figureSvg")[0].outerHTML;
var svgBlob = new Blob([svgData], {type:"image/svg+xml;charset=utf-8"});
var svgUrl = URL.createObjectURL(svgBlob);
var downloadLink = document.createElement("a");
downloadLink.href = svgUrl;
downloadLink.download = "newesttree.svg";
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
Run Code Online (Sandbox Code Playgroud)

  • 看起来它可以正常工作,而无需在`document.body`中附加和删除`downloadLink` (3认同)

sen*_*enz 20

结合Dave和defghi1977的答案.这是一个可重用的函数:

function saveSvg(svgEl, name) {
    svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
    var svgData = svgEl.outerHTML;
    var preface = '<?xml version="1.0" standalone="no"?>\r\n';
    var svgBlob = new Blob([preface, svgData], {type:"image/svg+xml;charset=utf-8"});
    var svgUrl = URL.createObjectURL(svgBlob);
    var downloadLink = document.createElement("a");
    downloadLink.href = svgUrl;
    downloadLink.download = name;
    document.body.appendChild(downloadLink);
    downloadLink.click();
    document.body.removeChild(downloadLink);
}
Run Code Online (Sandbox Code Playgroud)

调用示例:

saveSvg(svg, 'test.svg')
Run Code Online (Sandbox Code Playgroud)