• html2canvas 踩坑总结


    需求:将html表格导出为图片,表格可以自己编辑数据,并适配各种屏幕大小。上网搜了下,找到了html2canvas,一开始使用的是最新版0.5.0,最终因为需要支持自定义div编辑框自动换行选择了v0.4.1 - 7.9.2013

    开始编辑框使用的是textarea,后来发现textarea不能自适应高度,内容一多就会出现滚动条。这对于要把表格转化成图片的需求来说是没法接受的,于是改为了

    div{ word-wrap: break-word; }
    <div contenteditable="true"></div>

    于是第一个坑出现了,html2canvas0.5不识别‘word-wrap: break-word;' ,内容一多就直接超出了编辑框。。。

    google后发现0.4版本支持‘word-wrap: break-word;' ,我也是醉了。当然新版本还是有进步的,比如就不会出现这个问题:IE下border为1px时不显示。

    解决方案:

    参考链接

    改动0.4版本源代码:

    function getCSSInt(element, attribute) {
        //var val = parseInt(getCSS(element, attribute), 10);
        /**
        * my-change liyimin
        */
        var val = parseFloat(getCSS(element, attribute), 10);
        /**
        * my-change end
        */
        return (isNaN(val)) ? 0 : val; // borders in old IE are throwing 'medium' for demo.html
      }

    其实上面都是小坑,真正的大坑是html2canvas默认以屏幕的宽为canvas的宽,当需要转化的html超出屏幕范围时就只能转化当前可视部分,

    一开始使用0.5版本的时候也找到了一个解决方案,焰尾迭的 使用html2canvas实现浏览器截图

    // return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) {
    //     if (typeof(options.onrendered) === "function") {
    //         log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
    //         options.onrendered(canvas);
    //     }
    //     return canvas;
    // });
    /**
    *my-change liyimin
    */
    var width = options.width != null ? options.width : window.innerWidth;
    var height = options.height != null ? options.height : window.innerHeight;
    return renderDocument(node.ownerDocument, options, width, height, index).then(function(canvas) {
        if (typeof(options.onrendered) === "function") {
          log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
          options.onrendered(canvas);
        }
        return canvas;
    });
    /**
    *my-change end
    */

    但是实际使用的时候也是各种问题。比如width和height设大了,渲染出来的canvas总是各种空白部分,设得和需要转化的html一样大又有可能渲染不全,无奈放弃。

    查找了两三天终于找到了一个解决方案,就快要放弃了啊。

    解决当内容超出屏幕范围无法全部截取问题:

    参考链接

    <div>
      <iframe id="previewIframe" src="/static/html/preview.html" frameborder="0"></iframe>
    </div>

    将需要转化的html放在preview.html里面,超出多少都无所谓了有木有啊。

    最终就是这样:

    var $previewIframe=$('#previewIframe');
    html2canvas($previewIframe.contents().find('#previewTabelDetail')[0], {
        onrendered: function(canvas) {
         var url = canvas.toDataURL();
         $previewIframe.contents().find('body').append($(<img>").attr("src", url));
       }
    });

    本来是打算直接下载图片的,这样:

    var $previewIframe=$('#previewIframe');
    html2canvas($previewIframe.contents().find('#previewTabelDetail')[0], {
      onrendered: function(canvas) {
         var triggerDownload = $("<a>").attr("href", url).attr("download", "表格.png").appendTo("body");
         triggerDownload[0].click();
         triggerDownload.remove();
       }
    });

    可惜安卓上不支持直接下载base64的图片链接,就改为生成图片让用户自己手动保存。

    补充:

    其实关于超出屏幕范围的截图没那么麻烦,根本不需要使用iframe,html2canvas之所以获取不到超出部分是因为对象element的父元素宽高不够,也就是说只要将父元素的宽高设为和需要转换为canvas的子元素的宽高一样大就不会出现这个问题啦

  • 相关阅读:
    SQL注入常见处理方式
    git操作常用
    crontab 基本参数
    替代PHP格式化成无符号数后精度不对问题
    替代PHP两个大数相乘会有精度损失
    排序算法
    迁移服务器资源到新服务器
    数据库分库分表思路
    drupal 常用表单元素
    drupal模块开发
  • 原文地址:https://www.cnblogs.com/zhengtulym/p/6092652.html
Copyright © 2020-2023  润新知