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的子元素的寬高一樣大就不會出現這個問題啦

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM