如何将 SVG 元素下载为 SVG 文件

4
在过去几个月里,我一直在处理椭球地球相关的代码,最近我已经完成了它。现在我的教授要求我把我做的图表发送给他,以SVG文件的形式。我知道在Python中,你可以将几行代码放入项目中来下载图像,但我不确定在JavaScript中该怎么做。我应该如何在JavaScript中实现呢?或者是否有更简单的方法?

亲爱的 @Paankey56,当你编写这段代码时,请将其插入到这里,我们想看看具体的代码。 - AmerllicA
我没有意识到,你的意思是你只想将SVG转换为JPG或PNG文件以发送给你的主人吗? - AmerllicA
嗯,我可能没有理解你的上下文,但是你不能把SVG文件发送给他吗? - Armen Michaeli
你的教授是否希望你的代码包括保存JavaScript?如果不是,那么为什么不直接进入浏览器的控制台工具(按F12键),然后将SVG剪切并粘贴到新文件中呢? - Paul LeBeau
@Paankey56 请查看我的演示(并在下面回答),以下载为 .svg 或 .png(请注意,.svg 可以从检查 DOM 并按照注释建议进行复制粘贴获取)- https://codepen.io/Alexander9111/pen/VwLaaPe - Alex L
1个回答

6

请查看此演示:https://codepen.io/Alexander9111/pen/VwLaaPe?editors=1010

代码(修改自https://dev59.com/OGIj5IYBdhLWcg3wx38x#19885344):

function downloadSVGasTextFile() {
  const base64doc = btoa(unescape(encodeURIComponent(document.querySelector('svg').outerHTML)));
  const a = document.createElement('a');
  const e = new MouseEvent('click');

  a.download = 'download.svg';
  a.href = 'data:text/html;base64,' + base64doc;
  a.dispatchEvent(e);
}

downloadSVGasTextFile();

你需要将svg编码为64位字符串,然后将其用作锚标签的href,并通过分派点击事件来下载svg文本文件作为download.svg。
如果要保存图像,例如.png,则可以先将svg图像绘制到画布中,然后将其下载为.png文件。
更新:
我修改了答案和演示,现在包括下载为文本文件.svg或下载为图像文件.png https://codepen.io/Alexander9111/pen/VwLaaPe:
HTML:
<svg>
 ...
</svg>
<br/>
<button id="downloadPNG">Download .png</button>
<button id="downloadSVG">Download .svg</button>

JS:

function downloadSVGAsText() {
  const svg = document.querySelector('svg');
  const base64doc = btoa(unescape(encodeURIComponent(svg.outerHTML)));
  const a = document.createElement('a');
  const e = new MouseEvent('click');
  a.download = 'download.svg';
  a.href = 'data:image/svg+xml;base64,' + base64doc;
  a.dispatchEvent(e);
}

function downloadSVGAsPNG(e){
  const canvas = document.createElement("canvas");
  const svg = document.querySelector('svg');
  const base64doc = btoa(unescape(encodeURIComponent(svg.outerHTML)));
  const w = parseInt(svg.getAttribute('width'));
  const h = parseInt(svg.getAttribute('height'));
  const img_to_download = document.createElement('img');
  img_to_download.src = 'data:image/svg+xml;base64,' + base64doc;
  console.log(w, h);
  img_to_download.onload = function () {    
    canvas.setAttribute('width', w);
    canvas.setAttribute('height', h);
    const context = canvas.getContext("2d");
    //context.clearRect(0, 0, w, h);
    context.drawImage(img_to_download,0,0,w,h);
    const dataURL = canvas.toDataURL('image/png');
    if (window.navigator.msSaveBlob) {
      window.navigator.msSaveBlob(canvas.msToBlob(), "download.png");
      e.preventDefault();
    } else {
      const a = document.createElement('a');
      const my_evt = new MouseEvent('click');
      a.download = 'download.png';
      a.href = dataURL;
      a.dispatchEvent(my_evt);
    }
    //canvas.parentNode.removeChild(canvas);
  }  
}

const downloadSVG = document.querySelector('#downloadSVG');
downloadSVG.addEventListener('click', downloadSVGAsText);
const downloadPNG = document.querySelector('#downloadPNG');
downloadPNG.addEventListener('click', downloadSVGAsPNG);

不确定这里使用 unescapeencodeURIComponent 的目的。 - artidataio
这感觉现在已经过去了一辈子,哈哈。我会看一下并尝试理解为什么。 - Alex L
"msSaveBlob" 也已被弃用 - artidataio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接