js生成pdf報表

因爲前臺html已經動態生成報表,並且,前臺有一個功能,一個date range組件,當你拖動的時候,報表會在不提交到後臺的狀況下動態變化。
所以須要用到js生成生報表:

用到的組件:css

jquery.js
jspdf.js
canvg.js
html2canvas.js
jspdf.plugin.autotable.js


前臺動態生成的chart如今通常是用的html5的canvas或者是svg,很不幸運,我遇到的是svg, 若是是flash沒研究過。
因爲報表還須要保持原html頁面的外觀,可是又不是整個html,真正須要轉換成pdf報表的是:html+svg

前提:jsPDF 支持html,但支持不是很好,當你用一個html直接生成pdf的時候,其實他只保留了html裏面文本,樣式,結構都丟失了。
好比:table就丟失了。
jsPDF不支持svg導入。

思路:將svg轉換成canvas,再將html+canvas用hmlt2canvas插件轉換成canvas,再將canvas轉換成圖片,最後將圖片寫入pdf.
table的話就使用:jspdf.plugin.autotable.jshtml

首先將要導入的部分html單獨提取出來,寫入到一個iframe裏面,爲了保持外觀,還須要將這部分用的css也要寫入,再將iframe裏面的body標籤下面的全部內容轉換成canvas. 若是html裏面有svg,則先將svg轉換成canvas。html5

table須要單獨導入, jspdf.plugin.autotable.js插件支持json數組,支持table標籤的html元素。本文就是用table標籤。java


firefox:   html2canvas不能直接將svg+html轉換成canvas  --> 先將svg元素轉換成canvas --> html+canvas轉換成canvasnode


chrome:  html2canvas能夠直接將svg+html轉換成canvasjquery

 

//將指定節點下面的全部svg轉換成canvas
//這裏須要:canvg.js
function svg2canvas (targetElem) {
    var nodesToRecover = [];
    var nodesToRemove = [];

    var svgElem = targetElem.find('svg');

    svgElem.each(function(index, node) {
        var parentNode = node.parentNode;
        
        var svg = node.outerHTML;

        var canvas = document.createElement('canvas');
        
        canvg(canvas, svg);
        
        nodesToRecover.push({
            parent: parentNode,
            child: node
        });
        parentNode.removeChild(node);
        
        nodesToRemove.push({
            parent: parentNode,
            child: canvas
        });
        
        parentNode.appendChild(canvas);
    });
    
}

 

//這裏是將html(文本)在一個iframe裏面打開
//主要是排除其它元素的干擾致使不成功,以前是一直輸出不成功,所示才使用iframe
//這段代碼是官網摳下來的。
//還有個問題就是:若是將頁面的chart轉換成canvas了,那web頁面報表動態變化的功能將丟失。
function openWithIframe(html){ var iframe = document.createElement('iframe'); iframe.setAttribute("id", "myFrmame"); var $iframe = $(iframe); $iframe.css({ 'visibility': 'hidden', 'position':'static', 'z-index':'4' }).width($(window).width()).height($(window).height()); $('body').append(iframe); var ifDoc = iframe.contentWindow.document;
  //這裏作是將報表使用到的css從新寫入到iframe中,根據自身的須要
var style = "<link href='/javax.faces.resource/css/auth.css.jsf' rel='stylesheet' type='text/css'>"; style+="<link href='/javax.faces.resource/css/common.css.jsf' rel='stylesheet' type='text/css'>"; style+="<link href='/javax.faces.resource/css/dc.css.jsf' rel='stylesheet' type='text/css'>"; html = "<!DOCTYPE html><html><head>"+style+"</head><body>"+html+"</body></html>" ifDoc.open(); ifDoc.write(html); ifDoc.close(); /* //這裏作一些微調,根據自身的須要 var fbody = $iframe.contents().find("body"); fbody.find("#chart-center").removeAttr("width"); fbody.find(".page-container").css("width", "370px"); fbody.find(".center-container").css("width", "600px"); fbody.find("#severity-chart svg").attr("width", "370"); fbody.find("#status-chart svg").attr("width", "300"); */ return fbody; }

 

//導出pdf
function exportAsPDF(){
    //獲得要導出pdf的html根節點    
    var chartCenter = document.getElementById("chart-center").outerHTML;
    
    var fbody = openWithIframe(chartCenter);
    svg2canvas(fbody);
    
    //html2canvas官網的標準方法
    html2canvas(fbody, {
        onrendered: function(canvas) {
            //var myImage = canvas.toDataURL("image/png");
            //alert(myImage);
            //window.open(myImage);
            
            /*
            canvas.toBlob(function(blob) {
                saveAs(blob, "report.png");
            }, "image/png");
            */
            
            //將圖片轉換成:base64編碼的jpg圖片。
            var imgData = canvas.toDataURL('image/jpeg');
            //alert(imgData);
                        
            //l:橫向, p:縱向
            var doc = new jsPDF('l', 'pt', 'a3');
            //var doc = new jsPDF('p', 'mm', [290, 210]);
            //var doc = new jsPDF();//默認是A4,因爲個人報表比較大,因此專門設置了尺寸。
            doc.setFontSize(22);
            doc.setFontType("bolditalic");
            doc.text(500, 30, "Ticket Report");  //x:500, y:30
            
            doc.addImage(imgData, 'jpeg', 10, 60);  //寫入位置:x:10, y:60
            
            doc.addPage();    //新建一頁
            
            //這裏就是把將table寫入到pdf裏面。
            var res = doc.autoTableHtmlToJson(document.getElementById("tickets-summary-table"), true);
            doc.autoTable(res.columns, res.data);
            
            doc.save('ticket.report_'+new Date().getTime()+'.pdf');
            $('#myFrmame').remove(); //最後將iframe刪除
        },
        background:"#fff",  //這裏給生成的圖片默認背景,否則的話,若是你的html根節點沒有設置背景的話,會用黑色填充。
        allowTaint: true    //避免一些不識別的圖片干擾,默認爲false,遇到不識別的圖片干擾則會中止處理html2canvas
    });
    
};
相關文章
相關標籤/搜索