本文給大家講述的是如何使用jspdf生成pdf報表的方法和示例,十分的實用,有需要的小伙伴可以參考下。
由于前臺html已經動態生成報表,而且,前臺有一個功能,一個date range組件,當你拖動的時候,報表會在不提交到后臺的情況下動態變化。
因此需要用到js生成生報表:
用到的組件:
- 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轉換成canvas,再使用html2canvas將canvas轉換成圖片,最后將圖片寫入pdf.
table的話就使用:jspdf.plugin.autotable.js
firefox: html2canvas不能直接將svg+html轉換成canvas --> 先將svg元素轉換成canvas --> html+canvas轉換成canvas
chrome: html2canvas可以直接將svg+html轉換成canvas
- //將指定節點下面的所有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
- });
- };
以上所述就是本文的全部內容了,希望大家能夠喜歡。
新聞熱點
疑難解答
圖片精選