iframe嵌套下svg图形导出(Downloadify兼容IE浏览器)

承接上一篇,上一篇的内容在谷歌和火狐下运行完好,IE(世界上为什么会有IE的存在😭😭)下毫无反应,是因为IE下不支持a标签helf值为base64格式的下载

IE10及以上浏览器的msSaveBlob和 msSaveOrOpenBlob方法允许用户在客户端上保存文件,可以利用此特性

所以在上一篇的基础上js代码做如下修改

<script src="html2canvas.js"></script>
<script src="canvas2image.js"></script>
// 引入canvg.js 用于将svg转化成canvas
<script src="https://cdn.bootcss.com/canvg/1.5/canvg.js"></script>

js代码

document.getElementById('bnt').onclick = function() {
    // 获取iframe 嵌套下需要导出的内容
    var iframeContent = window.frames["iframe"].document.getElementById("box");
    // 在父页面创建一个容器
    var fillContent = document.createElement('div')
    fillContent.style.position = 'absolute';
    fillContent.style.top = "-99999px";
    // 把需要转换成图片的元素内容赋给创建的元素
    fillContent.innerHTML = iframeContent.outerHTML;
    document.body.appendChild(fillContent);

    var width = iframeContent.offsetWidth;
    var height = iframeContent.offsetHeight;
    var canvas = document.createElement("canvas");
    var scale = 2;
    //将 canvas 的宽高设置成容器宽高的 2 倍
    canvas.width = width * scale;
    canvas.height = height * scale;
    //将画布缩放,将图像放大两倍画到画布上,提高清晰度
    canvas.getContext("2d").scale(scale, scale);

    //html2canvas参数
    var opts = {
        scale: scale,
        canvas: canvas,
        logging: true,
        width: width,
        height: height
    };
 // 将svg图片转化成canvas图片,解决ie下iframe嵌套svg图片导出为空白的问题
    var nodesToRecover = [];
    var nodesToRemove = [];
    var svgElem = $(fillContent).find('svg'); 
    svgElem.each(function(index, node) {
        var parentNode = node.parentNode;
        var svg = node.outerHTML.trim();
        var canvas = document.createElement('canvas');
        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
        });
        parentNode.removeChild(node);
        nodesToRemove.push({
            parent: parentNode,
            child: canvas
        });
        parentNode.appendChild(canvas);
    });

    html2canvas(fillContent, opts).then(function(canvas) {
        var url = canvas.toDataURL('image/png');
        if (window.navigator.msSaveOrOpenBlob) {
            // 经过 base-64 编码的字符串进行解码
            var bstr = atob(url.split(',')[1])
            var n = bstr.length
            //创建初始化为0的,包含n个元素的无符号整型数组
            var u8arr = new Uint8Array(n)
            while (n--) {
                // 赋值给数组
                u8arr[n] = bstr.charCodeAt(n)
            }
            // 创建blob对象
            var blob = new Blob([u8arr])
            window.navigator.msSaveOrOpenBlob(blob, 'chart-download' + '.' + 'png')
        } else {
            // 生成一个a元素
            var a = document.createElement('a')
            a.download = name || 'myChart'
            // 将生成的URL设置为a.href属性
            a.href = url
            // 触发a的点击事件
            if (document.all) {
                a.click();
            } else if (document.createEvent) {
                var ev = document.createEvent('MouseEvents');
                ev.initEvent('click', false, true);
                a.dispatchEvent(ev);
            }
        }
        document.body.removeChild(fillContent);
    });
};
//  给svg元素对象添加outerHTML方法
Object.defineProperty(SVGElement.prototype, 'outerHTML', {
        get: function () {
            var $node, $temp;
            $temp = document.createElement('div');
            $node = this.cloneNode(true);
            $temp.appendChild($node);
            return $temp.innerHTML;
        },
        enumerable: false,
        configurable: true
    });

此方法适用于IE10及以上浏览器,iE9及以下浏览器不支持navigator.msSaveOrOpenBlob方法,若要实现纯前端导出,可使用Downloadify进行下载

基于Flash的导出插件,纯js实现,可以跨浏览器,需要FLASH PLAYER 10或更高版本

// 引入Downloadify
<script src="Downloadify.js"></script>
// IE浏览器判断
function isIE(){
      if (!!window.ActiveXObject || "ActiveXObject" in window){
          return true; 
       }else{
          return false; 
       }
  }  

父页面html结构修改

<body>
    <iframe name='iframe' src="001.html" width="100%" height="600"></iframe>
    <div id = "Downloadify">
      <input type="button"  id="bnt" value="导出图片" />
    </div>  
</body>

js部分做如下修改

document.getElementById('bnt').onclick = function() {
    // 获取iframe 嵌套下需要导出的内容
    var iframeContent = window.frames["iframe"].document.getElementById("box");
    // 在父页面创建一个容器
    var fillContent = document.createElement('div')
    fillContent.style.position = 'absolute';
    fillContent.style.top = "-99999px";
    // 把需要转换成图片的元素内容赋给创建的元素
    fillContent.innerHTML = iframeContent.outerHTML;
    document.body.appendChild(fillContent);

    var width = iframeContent.offsetWidth;
    var height = iframeContent.offsetHeight;
    var canvas = document.createElement("canvas");
    var scale = 2;
    //将 canvas 的宽高设置成容器宽高的 2 倍
    canvas.width = width * scale;
    canvas.height = height * scale;
    //将画布缩放,将图像放大两倍画到画布上,提高清晰度
    canvas.getContext("2d").scale(scale, scale);

    //html2canvas参数
    var opts = {
        scale: scale,
        canvas: canvas,
        logging: true,
        width: width,
        height: height
    };

    var nodesToRecover = [];
    var nodesToRemove = [];
    // 将svg图片转化成canvas图片,解决ie下iframe嵌套svg图片导出为空白的问题
    var svgElem = $(fillContent).find('svg');
    svgElem.each(function(index, node) {
        var parentNode = node.parentNode;
        var svg = node.outerHTML.trim();

        var canvas = document.createElement('canvas');
        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
        });
        parentNode.removeChild(node);

        nodesToRemove.push({
            parent: parentNode,
            child: canvas
        });
        parentNode.appendChild(canvas);
    });

    html2canvas(fillContent, opts).then(function(canvas) {
        var url = canvas.toDataURL('image/png');
        if (isIE()) {
            Downloadify.create('downloadify', {
                filename: function() {
                    return 'myChar.pngt';
                },
                data: function() {
                    return url.split('base64,')[1]
                },
                onComplete: function() {
                    alert('保存成功')
                },
                onCancel: function() {
                    alert('取消保存')
                },
                onError: function() {
                    alert('保存出错')
                },
                swf: '/js/load/media/downloadify.swf',
                downloadImage:'/js/load/images/download.png',
                width: 100,
                height: 30,
                dataType: "base64",
                transparent: true,
                append: false
            });
        } else {
            // 生成一个a元素
            var a = document.createElement('a')
            a.download = name || 'myChart'
            // 将生成的URL设置为a.href属性
            a.href = url
            // 触发a的点击事件
            if (document.all) {
                a.click();
            } else if (document.createEvent) {
                var ev = document.createEvent('MouseEvents');
                ev.initEvent('click', false, true);
                a.dispatchEvent(ev);
            }
        }
        document.body.removeChild(fillContent);
    });
};

Downloadify用法可以参考 http://www.github.com/dcneiner/Downloadify

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容