使用jspdf生成pdf報(bào)表
由于前臺(tái)html已經(jīng)動(dòng)態(tài)生成報(bào)表,而且,前臺(tái)有一個(gè)功能,一個(gè)date range組件,當(dāng)你拖動(dòng)的時(shí)候,報(bào)表會(huì)在不提交到后臺(tái)的情況下動(dòng)態(tài)變化。
因此需要用到j(luò)s生成生報(bào)表:
用到的組件:
jquery.js jspdf.js canvg.js html2canvas.js jspdf.plugin.autotable.js
前臺(tái)動(dòng)態(tài)生成的chart現(xiàn)在一般是用的html5的canvas或者是svg,很不幸運(yùn),我遇到的是svg, 如果是flash沒(méi)研究過(guò)。
由于報(bào)表還需要保持原h(huán)tml頁(yè)面的外觀,但是又不是整個(gè)html,真正需要轉(zhuǎn)換成pdf報(bào)表的是:html+svg
前提:jsPDF 支持html,但支持不是很好,當(dāng)你用一個(gè)html直接生成pdf的時(shí)候,其實(shí)他只保留了html里面文本,樣式,結(jié)構(gòu)都丟失了。
比如:table就丟失了。
jsPDF不支持svg導(dǎo)入。
思路:將svg轉(zhuǎn)換成canvas,再將html+canvas轉(zhuǎn)換成canvas,再使用html2canvas將canvas轉(zhuǎn)換成圖片,最后將圖片寫(xiě)入pdf.
table的話(huà)就使用:jspdf.plugin.autotable.js
firefox: html2canvas不能直接將svg+html轉(zhuǎn)換成canvas --> 先將svg元素轉(zhuǎn)換成canvas --> html+canvas轉(zhuǎn)換成canvas
chrome: html2canvas可以直接將svg+html轉(zhuǎn)換成canvas
//將指定節(jié)點(diǎn)下面的所有svg轉(zhuǎn)換成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(文本)在一個(gè)iframe里面打開(kāi) //主要是排除其它元素的干擾導(dǎo)致不成功,之前是一直輸出不成功,所示才使用iframe //這段代碼是官網(wǎng)摳下來(lái)的。 //還有個(gè)問(wèn)題就是:如果將頁(yè)面的chart轉(zhuǎn)換成canvas了,那web頁(yè)面報(bào)表動(dòng)態(tài)變化的功能將丟失。 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; //這里做是將報(bào)表使用到的css重新寫(xiě)入到iframe中,根據(jù)自身的需要 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(); /* //這里做一些微調(diào),根據(jù)自身的需要 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; }
//導(dǎo)出pdf function exportAsPDF(){ //得到要導(dǎo)出pdf的html根節(jié)點(diǎn) var chartCenter = document.getElementById("chart-center").outerHTML; var fbody = openWithIframe(chartCenter); svg2canvas(fbody); //html2canvas官網(wǎng)的標(biāo)準(zhǔn)方法 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"); */ //將圖片轉(zhuǎn)換成: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();//默認(rèn)是A4,由于我的報(bào)表比較大,所以專(zhuān)門(mén)設(shè)置了尺寸。 doc.setFontSize(22); doc.setFontType("bolditalic"); doc.text(500, 30, "Ticket Report"); //x:500, y:30 doc.addImage(imgData, 'jpeg', 10, 60); //寫(xiě)入位置:x:10, y:60 doc.addPage(); //新建一頁(yè) //這里就是把將table寫(xiě)入到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", //這里給生成的圖片默認(rèn)背景,不然的話(huà),如果你的html根節(jié)點(diǎn)沒(méi)有設(shè)置背景的話(huà),會(huì)用黑色填充。 allowTaint: true //避免一些不識(shí)別的圖片干擾,默認(rèn)為false,遇到不識(shí)別的圖片干擾則會(huì)停止處理html2canvas }); };
以上所述就是本文的全部?jī)?nèi)容了,希望大家能夠喜歡。
相關(guān)文章
jQuery使用中可能被XSS攻擊的一些危險(xiǎn)環(huán)節(jié)提醒
XSS指的是跨站腳本攻擊,比如人們常說(shuō)的向$傳入字符串或者字符串轉(zhuǎn)換可執(zhí)行函數(shù)等一些安全方面值得注意的細(xì)節(jié),下面就為大家整理了jQuery使用中可能被XSS攻擊的一些危險(xiǎn)環(huán)節(jié)提醒2016-05-05jquery下實(shí)現(xiàn)overlay遮罩層代碼
下面是個(gè)應(yīng)用的小例子用來(lái)統(tǒng)一處理ajax請(qǐng)求中利用完全透明遮罩層組織用戶(hù)和界面元素交換,當(dāng)ajax出錯(cuò)時(shí)提示用戶(hù)2010-08-08輕松學(xué)習(xí)jQuery插件EasyUI EasyUI實(shí)現(xiàn)拖動(dòng)基本操作
這篇文章主要幫大家輕松學(xué)習(xí)jQuery插件EasyUI,并利用EasyUI實(shí)現(xiàn)拖動(dòng)基本操作,文章并提供了一個(gè)學(xué)校課程表簡(jiǎn)單實(shí)例,感興趣的小伙伴們可以參考一下2015-11-11jQuery使用after()方法在元素后面添加多項(xiàng)內(nèi)容的方法
這篇文章主要介紹了jQuery使用after()方法在元素后面添加多項(xiàng)內(nèi)容的方法,實(shí)例分析了jQuery中after方法的功能及在元素后面添加內(nèi)容的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-03-03jQuery插件passwordStrength密碼強(qiáng)度指標(biāo)詳解
這篇文章主要為大家詳細(xì)介紹了jQuery插件passwordStrength密碼強(qiáng)度指標(biāo)實(shí)現(xiàn)代碼,感興趣的小伙伴們可以參考一下2016-06-06jquery結(jié)合html實(shí)現(xiàn)中英文頁(yè)面切換
這篇文章主要為大家詳細(xì)介紹了jquery結(jié)合html實(shí)現(xiàn)中英文頁(yè)面切換,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11jQuery插件ajaxFileUpload實(shí)現(xiàn)異步上傳文件效果
jQuery插件AjaxFileUpload用來(lái)實(shí)現(xiàn)ajax文件上傳,該插件使用非常簡(jiǎn)單,接下來(lái)我們來(lái)看下用AjaxFileUpload插件實(shí)現(xiàn)文件上傳的方法,有需要的小伙伴可以參考下2015-04-04jquery實(shí)現(xiàn)垂直和水平菜單導(dǎo)航欄
這篇文章主要為大家詳細(xì)介紹了jquery實(shí)現(xiàn)垂直和水平菜單導(dǎo)航欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08