jspdfを使用してpdfレポートを生成する

5494 ワード

フロントhtmlはレポートを動的に生成しているため、フロントにはdate rangeコンポーネントという機能があり、ドラッグするとバックグラウンドにコミットせずにレポートが動的に変化します.したがって、jsを使用して生レポートを生成する必要があります.
使用するコンポーネント:

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


フロントで動的に生成されたchartは現在html 5のcanvasかsvgを使用しているのが一般的で、ラッキーではありませんが、私が出会ったのはsvgで、flashなら研究したことがありません.
レポートは元のhtmlページの外観を維持する必要がありますが、html全体ではありません.本当にpdfレポートに変換する必要があるのはhtml+svgです.
前提:jsPDFはhtmlをサポートしていますが、サポートはあまりよくありません.htmlで直接pdfを生成すると、実はhtmlの中のテキスト、スタイル、構造が失われています.例えば、tableが失われました.jsPDFではsvgインポートはサポートされていません.
構想:svgをcanvasに変換し、html+canvasをcanvasに変換し、html 2 canvasを使用してcanvasをピクチャに変換し、最後にpdfにピクチャを書き込む.tableなら:jspdf.plugin.autotable.js
firefox:html 2 canvas svg+htmlをcanvasに直接変換することはできません-->svg要素をcanvasに変換-->html+canvasをcanvas chromeに変換します:html 2 canvasは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 = "";
  style+="";
  style+="";
  
  html = ""+style+""+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
  });
  
};

以上が本文のすべてですが、お好きになってください.