方案一:svg保存下载为图片,总体思路就是svg转码--->画在canvas上--->下载
第一种是使用serializer将获取的svg转换为字符串,然后通过encodeURIComponent()转码
var svg = document.getElementById('mainsvg') // 获取svg
var serializer = new XMLSerializer()
var toExport = svg.cloneNode(true); // 克隆
var bb = svg.getBBox(); // getBBox方法返回一个包含svg元素的最小矩形的坐标对象。 包含(x,y)、width、height 需要用来解决svg中的图超出边界时无法全部完整保存问题
toExport.setAttribute('viewBox', (bb.x-20) + ' ' + (bb.y-20) + ' ' + (bb.width+40) + ' ' + (bb.height+40)); // 重新设置svg目前的视口
toExport.setAttribute('width', bb.width); // 重新设置svg目前的宽度
toExport.setAttribute('height', bb.height); // 重新设置svg目前的高度
var source = '<?xml version="1.0" standalone="no"?>\r\n' + serializer.serializeToString(toExport)
var image.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(source)
第二种是转为base64
var svg = document.getElementById('mainsvg')
// 这里一定要给svg设置这两个命名空间,包含了image 则也需要加上xmlns:xlink 否则浏览器会报错不能下载图片
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg")
svg.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink")
// 这里用来解决当svg中图超出边界时,需要全部完整保存下来的功能
var toExport = svg.cloneNode(true);
var bb = svg.getBBox();
toExport.setAttribute('viewBox', (bb.x-20) + ' ' + (bb.y-20) + ' ' + (bb.width+40) + ' ' + (bb.height+40));
toExport.setAttribute('width', bb.width);
toExport.setAttribute('height', bb.height);
// 转为base64 一定要加上unescape(encodeURIComponent,否则浏览器会报错
var imgsrc = 'data:image/svg+xml;base64,'+ window.btoa(unescape(encodeURIComponent(toExport.outerHTML)))
这两种随便哪一种转码都可以,然后画在canvas上下载即可
var canvas = document.createElement("canvas") // 定义画布
canvas.width = bb.width // 定义宽高为当前svg的大小
canvas.height = bb.height
var context = canvas.getContext("2d");
context.fillStyle = '#fff' // 把图画在canvas上背景为白色的矩形上
context.fillRect(0, 0, bb.width, bb.height)
var image = new Image;
image.src = imgsrc;
image.onload = function() {
context.drawImage(image, 0, 0);
var a = document.createElement("a"); // 定义a链接后自动下载
a.download = "sample.png";
a.href = canvas.toDataURL("image/png")
a.click();
};
完整代码
// 第一种
var svg = document.getElementById('mainsvg')
var serializer = new XMLSerializer()
var toExport = svg.cloneNode(true);
var bb = svg.getBBox();
toExport.setAttribute('viewBox', (bb.x-20) + ' ' + (bb.y-20) + ' ' + (bb.width+40) + ' ' + (bb.height+40));
toExport.setAttribute('width', bb.width);
toExport.setAttribute('height', bb.height);
var source = '<?xml version="1.0" standalone="no"?>\r\n' + serializer.serializeToString(toExport)
var image = new Image
image.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(source)
var canvas = document.createElement("canvas")
canvas.width = bb.width
canvas.height = bb.height
var context = canvas.getContext("2d")
context.fillStyle = '#fff'
context.fillRect(0, 0, bb.width, bb.height)
image.onload = function () {
context.drawImage(image, 0, 0)
var a = document.createElement("a")
a.download = "graph.png"
a.href = canvas.toDataURL("image/png")
a.click()
}
// 第二种
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg")
svg.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink")
var toExport = svg.cloneNode(true);
var bb = svg.getBBox();
toExport.setAttribute('viewBox', (bb.x-20) + ' ' + (bb.y-20) + ' ' + (bb.width+40) + ' ' + (bb.height+40));
toExport.setAttribute('width', bb.width);
toExport.setAttribute('height', bb.height);
var imgsrc = 'data:image/svg+xml;base64,'+ window.btoa(unescape(encodeURIComponent(toExport.outerHTML)))
var canvas = document.createElement("canvas")
canvas.width = bb.width
canvas.height = bb.height
var context = canvas.getContext("2d");
context.fillStyle = '#fff'
context.fillRect(0, 0, bb.width, bb.height)
var image = new Image;
image.src = imgsrc;
image.onload = function() {
context.drawImage(image, 0, 0);
var a = document.createElement("a");
a.download = "sample.png";
a.href = canvas.toDataURL("image/png")
a.click();
};
方案二:使用插件saveSvgAsPng 也是最简单直接的
按照官网的提示,一步步操作。
github:https://github.com/exupero/saveSvgAsPng
翻译版本:https://www.helplib.com/GitHub/article_110596
1.用npm把插件装上
npm install save-svg-as-png
2.在需要使用的vue文件中把js文件import进来
import saveSvg from 'save-svg-as-png'
3.直接调用函数下载即可,还有各种方法可调用
handleImg() {
var svg = document.getElementById('mainsvg')
saveSvg.saveSvgAsPng(svg, 'graph.png')
// 还可以加上各种样式参数
// saveSvg.saveSvgAsPng(svg, 'graph.png', {backgroundColor: 'white', width:bb.width+60, height: bb.height+60, left: bb.x-40, top: bb.y-40})
}