前言:最近需要将网页或者网页的一个元素导出成png图片,从网上搜索了一些信息,但是针对嵌套svg的网页,没有很好的解决方案。经过自己整理,完美解决了网页导出png图片的问题。其中需要使用的js插件有jquery.js, html2canvas.js, canvg.js,rgbcolor.js。
步骤:1.将所有svg转为canvas替换原来的svg Dom对象。2.将没有svg的网页保存为canvas,3.保存网页为png图片,4.替换回原来的svg Dom对象。
具体实现代码:
function outerHTML(node) {
var chating=node.cloneNode(true)
var myDiv=document.createElement("div");
myDiv.appendChild(chating);
var str= myDiv.innerHTML;
chating=null;
$(myDiv).remove();
return str;
};
/**
* 说明:解决嵌套svg的网页导出问题,一般网页可以直接使用html2canvas函数解决。
* @param containerId 需要截取成图片的dom的id
* @param backcall 转换为canvas后的回调函数
* @returns
*/
function MyHtml2Canvas(containerId, backcall)
{
scrollTo(0, 0);
var container = "#"+containerId;//为需要截取成图片的dom的id
var tmpDiv = "divCanvasTempContainer_"; //临时div
$("body").append("<div id='"+tmpDiv+"' style='display:none;'></div>");
if (typeof html2canvas !== 'undefined') {
//以下是对svg的处理
var nodesToRecover = [];
var nodesToRemove = [];
var svgElem = $(container).find('svg');
var lstSvgHtml = [];
svgElem.each(function (index, node) {
var parentNode = node.parentNode;
//$(node).find(".highcharts-background").attr("fill", "white");
var svg = outerHTML(node).trim();
//svg = svg.replace(/fill="transparent"/g, 'fill="white"');
lstSvgHtml.push(svg);
//var svg = parentNode.html().trim();
//创建临时的canvas
$("#"+tmpDiv).html('<canvas class="tempCanvas"></canvas>');
var canvas = $("#"+tmpDiv+" canvas")[0];
canvg(canvas, svg);
if (node.style.position) {
canvas.style.position += node.style.position;
canvas.style.left += node.style.left;
canvas.style.top += node.style.top;
}
nodesToRecover.push({
parent: parentNode,
child: node
});
// $("#divCanvas").append(svg);
parentNode.removeChild(node);
nodesToRemove.push({
parent: parentNode,
child: canvas
});
parentNode.appendChild(canvas);
//$("#divCanvas").append(canvas);
});
//$("#divCanvas").show();
html2canvas(document.querySelector(container), {
onrendered: backcall
});
}
//把添加的删除掉,再把删除掉的添加回来
for( var i = 0; i < nodesToRecover.length; ++i)
{
var $parent = $(nodesToRecover[i].parent);
$parent.find(".tempCanvas").remove();
//console.log(nodesToRecover[i].child);
$parent.append(nodesToRecover[i].child);
}
//删除临时div
$("#"+tmpDiv).remove();
}
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type:mime});
}
/**
* 导出网页为png,直接调用exportData即可
* @param containerId 需要截取成图片的dom的id
* @returns
*/
//导出png图片
function exportData(containerId) {
MyHtml2Canvas(containerId, function(canvas){
//导出
var fileName = 'export.png';
if (window.navigator.msSaveOrOpenBlob) {
// var blob = new Blob([canvas.toDataURL('image/png')], {
// type: "image/png"
// });
// var blob = dataURLtoBlob(canvas.toDataURL('image/png'));
var blob = canvas.msToBlob(null, 'image/png', 1.0);
navigator.msSaveBlob(blob, fileName);
}
else{
var link = document.createElement("a");
link.setAttribute("href", canvas.toDataURL());
link.setAttribute("download", fileName);
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
});
}
备注:其中创建了一个默认的div,而不是直接用document直接创建canvas,是因为canvg.js转换svg成canvas时出错。
兼容浏览器chrome,firefox,ie11,ie edge等浏览器,其中ie edge偶尔会出现svg部分为黑色。