Rumah  >  Artikel  >  hujung hadapan web  >  Hasilkan laporan pdf menggunakan jspdf_jquery

Hasilkan laporan pdf menggunakan jspdf_jquery

WBOY
WBOYasal
2016-05-16 15:51:361949semak imbas

Memandangkan html bahagian hadapan telah menghasilkan laporan secara dinamik dan bahagian hadapan mempunyai fungsi, komponen julat tarikh, apabila anda menyeretnya, laporan akan berubah secara dinamik tanpa diserahkan ke latar belakang.
Oleh itu, js perlu digunakan untuk menjana laporan:

Komponen yang digunakan:

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

Carta yang dijana secara dinamik oleh meja depan biasanya menggunakan kanvas HTML5 atau svg Malangnya, saya menemui svg.

Memandangkan laporan masih perlu mengekalkan penampilan halaman html asal, tetapi ia bukan keseluruhan html, perkara yang benar-benar perlu ditukar kepada laporan pdf ialah: html svg

Premis: jsPDF menyokong HTML, tetapi sokongannya tidak begitu baik Apabila anda menggunakan HTML untuk menjana PDF secara langsung, sebenarnya, ia hanya mengekalkan teks, gaya dan struktur dalam HTML dan hilang.
Contohnya: meja hilang.
jsPDF tidak menyokong import svg.

Idea: Tukar svg kepada kanvas, kemudian tukarkan kanvas html kepada kanvas, kemudian gunakan html2canvas untuk menukar kanvas kepada gambar, dan akhirnya tulis gambar kepada pdf.
Untuk jadual, gunakan: jspdf.plugin.autotable.js

firefox: html2canvas tidak boleh menukar terus html svg kepada kanvas --> Tukar elemen svg kepada kanvas dahulu --> Tukar kanvas html kepada kanvas
chrome: html2canvas boleh terus menukar svg html kepada kanvas

//将指定节点下面的所有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
  });
  
};

Di atas adalah keseluruhan kandungan artikel ini, saya harap anda semua menyukainya.

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn