Как экспортировать графики и таблицы html внутри фреймов в одном и том же PDF? - PullRequest
0 голосов
/ 10 января 2020

У меня есть страница html с несколькими iframe, некоторые из которых содержат графики старших диаграмм (svg), а некоторые содержат HTML таблицы. Мне нужно экспортировать эту страницу с графиками и таблицей html div. Я смог получить элементы svg изнутри iframes и экспортировать их в pdf, используя библиотеку svg2pdf. PDF идет очень хорошо. Но я не могу найти какой-либо способ извлечь таблицу и экспортировать ее в pdf вообще.

Я пытался преобразовать ее в base64, а затем добавить, но svg2pdf выдает мне эту ошибку:

svg2pdf. js: 3140 svg2pdf js: Изображения со ссылкой на внешний ресурс не поддерживаются! ("undefined")

Я также пытался преобразовать hmtl в svg, но обнаружил, что это бесполезно. .

Как мне к этому подойти?

<html>
   <head>
      <meta charset="utf-8"/>
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
         integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
      <title></title>
      <script data-require="jquery" data-semver="3.1.1"
         src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
      <script src="https://code.highcharts.com/highcharts.js"></script>
      <script src="https://code.highcharts.com/highcharts-3d.js"></script>
      <script src="https://code.highcharts.com/modules/exporting.js"></script>
      <script src="https://code.highcharts.com/modules/offline-exporting.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/canvg/1.5/canvg.js"
         integrity="sha256-gS9x7L+zPeuIJQi5Ozx6nkmnAKegHZGdx/Zy/jOs/Ao=" crossorigin="anonymous"></script>
   </head>
   <body>
      <header class="header" id="canvas_div_pdf">
         <div class="header-toolbar">
            <form role="form" method="get" action="" style="width: 100%">
               <div class="row">
                  <div style="padding-left: 2%; padding-top: 0.5%; padding-bottom: 0.5%; width: 98%; border-bottom: 1px solid #cccccc">
                     <div style="width:30%; float: left; font-size: 2.2rem; ">Test Board ( Global
                        )
                     </div>
                     <div style="width:45%; float: left">
                        <div style="float:left;border:solid 1pt black;">
                           <button id="export-pdf" onclick="return false">Export to PDF</button>
                           <input id="btn-Preview-Image" type="button" value="Preview"/>
                           <a id="btn-Convert-Html2Image" href="#">Download</a>
                           <br/>
                           <h3>Preview :</h3>
                           <div id="previewImage">
                           </div>
                        </div>
                        <a id="pdf-download">Creating PDF...</a>
                        <div style="float: right">
                           <label>Date Range</label>
                           <input type="text" class="form-control datepicker hasDatepicker" name="boardStartDate"
                              id="inputstartdate" placeholder="Start Date" value="20-12-2020">&nbsp;
                           <input type="text" class="form-control datepicker hasDatepicker" name="boardEndDate"
                              id="inputenddate" placeholder="End Date" value="20-12-2020">
                           <button type="submit" class="btn btn--small btn--icon btn--success"><span
                              class="icon icon-check"></span></button>
                        </div>
                     </div>
                     <div style="width:25%; float: right">
                        <div style="width:15%; min-width:32px; float: right">
                           <a class="btn btn--small btn--icon btn--primary" onclick="return showAddAnotherPopup(this);"
                              title="Dashboard Settings" target="popup" href="/admin/pivot_table/genericboard/1/">
                           <span class="icon-cog"></span>
                           </a>
                        </div>
                        <div style="width:15%; min-width:32px; float: right">
                           <a class="btn btn--small btn--icon btn--primary" onclick="updateBoardDefault()"
                              title="Set this dashboard as default" target="_blank">
                           <span class="icon-check-square-o"></span>
                           </a>
                        </div>
                        <div style="width:15%; min-width:32px; float: right">
                           <a class="btn btn--small btn--icon btn--primary" id="editBoard" title="Edit Panels on Board"
                              target="_blank">
                           <span class="icon-pencil"></span>
                           </a>
                        </div>
                        <div style="width:15%; min-width:32px; float: right">
                           <a class="btn btn--small btn--icon btn--primary" onclick="exportBoard()"
                              title="Export board to Excel">
                           <span class="icon-file-excel-o"></span>
                           </a>
                        </div>
                        <!--                                <div style="width:15%; min-width:32px; float: right">-->
                        <!--                                    <button class="btn btn&#45;&#45;small btn&#45;&#45;icon btn&#45;&#45;primary" id="export-pdf" onclick="return false" title="Export board to PDF">-->
                        <!--                                        <span class="icon-file-pdf-o"></span>-->
                        <!--                                    </button>-->
                        <!--                                </div>-->
                        <div style="width:15%; min-width:32px; float: right;border: 1px solid black">
                           <button class="btn btn--small btn--icon btn--primary" id="export-div" onclick="return false"
                              title="Export board to PDF">
                           <span class="icon-file-pdf-o">download divs</span>
                           </button>
                        </div>
                     </div>
                  </div>
               </div>
            </form>
         </div>
      </header>
      <div>
         <span>
            <h4 id="graph1title">Graph one title</h4>
            <iframe id="ifrm1" src="chart.html" width="250" height="250"></iframe>
         </span>
         <span>
            <h4 id="graph2title">Graph two title</h4>
            <iframe id="ifrm2" src="chart2.html" width="250" height="250"></iframe>
         </span>
         <span>
            <h4>Table two title</h4>
            <iframe id="ifrm3" src="table.html" width="500" height="300"></iframe>
         </span>
      </div>
      <div id="buttonrow">
         <button id="set-charts">Set Charts</button>
         <button id="export-png">Export to PNG</button>
         <button id="export-pdf">Export to PDF</button>
      </div>
      <script>
         $(function() {

            var element = $("#ifrm3"); // global variable
         var getCanvas; // global variable
         var imageData;

         $("#btn-Preview-Image").on('click', function () {
         html2canvas(element, {
            onrendered: function (canvas) {
                $("#previewImage").append(canvas);
                getCanvas = canvas;
                var imageData = getCanvas.toDataURL("image/png");
                console.log("html div",imageData);
            // Now browser starts downloading it instead of just showing it
                var newData = imageData.replace(/^data:image\/png/, "data:application/octet-stream");
                $("#btn-Convert-Html2Image").attr("download", "your_pic_name.png").attr("href", newData);
            }
         });
         });

         $("#btn-Convert-Html2Image").on('click', function () {
         var imageData = getCanvas.toDataURL("image/png");
         console.log("html div",imageData);
            // Now browser starts downloading it instead of just showing it
            var newData = imageData.replace(/^data:image\/png/, "data:application/octet-stream");
            $("#btn-Convert-Html2Image").attr("download", "your_pic_name.png").attr("href", newData);


         });




         var ifrmChart = undefined;
         var chartArray = [];


         Highcharts.getSVG = function(charts) {
         var svgArr = [],
         top = 0,
         line = false,
         count = 0,
         width = 0;
         graphCount = charts.length;
                     // console.log(graphCount);

                     Highcharts.each(charts, function(chartArray,tableObject) {
                        console.log("@137",tableObject);
                        chart = chartArray.chart;
                        var tableSVG;
                        var xpos = chartArray.xPos;
                        var ypos = chartArray.yPos;
                       //console.log('typeof' + typeof(xpos));
                       //console.log(xpos,ypos);
                       var svg = chart.getSVG(),
                         // Get width/height of SVG for export
                         svgWidth = +svg.match(
                            /^<svg[^>]*\swidth\s*=\s*\"?(\d+)\"?[^>]*>/
                            )[1],
                         svgHeight = +svg.match(
                            /^<svg[^>]*height\s*=\s*\"?(\d+)\"?[^>]*>/
                            )[1];

                         svg = svg.replace('<svg', '<g><path style="padding: 20px"></path></g><g style="padding: 20px" transform="translate(' + ypos + ',' + xpos + ')" ');



                         svg = svg.replace('</svg>', '</g>');

                        var iframe = $('#ifrm3'); // or some other selector to get the iframe
                        var temp = $('#tableContainer', iframe.contents());

                        // html2canvas(tableObject).then(canvas => {
                            // tableSVG = canvas;
                            // console.log(tableSVG);
                        // });


                        svg = svg + '<text x="' + $(document).width()/2 + ' " text-anchor="middle" class="highcharts-title" style="color:#333333;font-size:24px;font-family:Arial;fill:#333333;;border:0px none rgb(51, 51, 51);border-block-end:0px none rgb(51, 51, 51);border-block-end-color:rgb(51, 51, 51);border-block-start:0px none rgb(51, 51, 51);border-block-start-color:rgb(51, 51, 51);border-bottom:0px none rgb(51, 51, 51);border-bottom-color:rgb(51, 51, 51);border-color:rgb(51, 51, 51);border-inline-end:0px none rgb(51, 51, 51);border-inline-end-color:rgb(51, 51, 51);border-inline-start:0px none rgb(51, 51, 51);border-inline-start-color:rgb(51, 51, 51);border-left:0px none rgb(51, 51, 51);border-left-color:rgb(51, 51, 51);border-right:0px none rgb(51, 51, 51);border-right-color:rgb(51, 51, 51);border-top:0px none rgb(51, 51, 51);border-top-color:rgb(51, 51, 51);caret-color:rgb(51, 51, 51);color:rgb(51, 51, 51);column-rule:0px none rgb(51, 51, 51);column-rule-color:rgb(51, 51, 51);font-family:Arial;outline:rgb(51, 51, 51) none 0px;outline-color:rgb(51, 51, 51);text-decoration:none solid rgb(51, 51, 51);text-decoration-color:rgb(51, 51, 51);webkit-border-after:0px none rgb(51, 51, 51);webkit-border-after-color:rgb(51, 51, 51);webkit-border-before:0px none rgb(51, 51, 51);webkit-border-before-color:rgb(51, 51, 51);webkit-border-end:0px none rgb(51, 51, 51);webkit-border-end-color:rgb(51, 51, 51);webkit-border-start:0px none rgb(51, 51, 51);webkit-border-start-color:rgb(51, 51, 51);webkit-column-rule:0px none rgb(51, 51, 51);webkit-column-rule-color:rgb(51, 51, 51);webkit-perspective-origin:113px 0px;webkit-text-emphasis-color:rgb(51, 51, 51);webkit-text-fill-color:rgb(51, 51, 51);webkit-text-stroke-color:rgb(51, 51, 51);" y="19" fill="rgb(51, 51, 51)"><tspan>Board Title Report</tspan></text>' + tableSVG;




                        svg = svg + '<image width="500" height="300" xlink:href="' + imageData +  '">'




                         //replace 'Column charts' with chart title element text



                         svgArr.push(svg);
                     });


                     return "<svg height='" + $(document).height() + "' width='" + $(document).width() + "' version='1.1' xmlns='http://www.w3.org/2000/svg'>" +
                     svgArr.join('') + '</svg>';
                 };

                 Highcharts.exportCharts = function(charts, options) {

                     //Highcharts.setOptions({ });
                     // Merge the options
                     options = Highcharts.merge(Highcharts.getOptions().exporting, options);
                     svgContent = Highcharts.getSVG(charts);
                     console.log(svgContent);
                     console.log($(svgContent));


                     // Post to export server
                     // Highcharts.post(options.url, {
                     //     filename: options.filename || 'chart',
                     //     type: options.type,
                     //     width: options.width,
                     //     svg: Highcharts.getSVG(charts),
                     // });


                     var svgString = svgContent;
                     var htmlObject = document.createElement('div');
                     htmlObject.setAttribute("id", "svgexport");
                     htmlObject.innerHTML = svgString;
                     console.log(htmlObject);
                     // htmlObject.getElementById("myDiv").style.marginTop = something;




                     var svg = htmlObject.querySelector('svg'),
                     pdf = new jsPDF('p', 'pt', [$(document).height(), $(document).width()]);




                     setTimeout(function() {

                        svg2pdf(svg, pdf, {
                            removeInvalid: true,
                            scale: 72 / 96, // this is the ratio of px to pt units
                        });






                        var data = pdf.output('datauristring');
                        var dl = document.getElementById('pdf-download');



                        dl.innerHTML = 'Download PDF';
                        dl.href = data;
                        dl.download = 'mychart.pdf';
                     }, 1000);
                 };
                 $('#export-png').click(function() {
                    Highcharts.exportCharts(chartArray);
                 });

                 $('#export-pdf').click(function() {

                    chartArray = [];
                    tableArray = [];

                    $("iframe").each(function(index) {
                        console.log(index + ": " + $(this).attr('id'));
                        var iFrameId = "#" + $(this).attr('id');
                        if($(iFrameId)[0].contentWindow.getChart()){

                            var chartObj = $(iFrameId)[0].contentWindow.getChart();
                           var xPosition = $(iFrameId).parent().offset().top; // added some arbitrary padding
                           var yPosition = $(iFrameId).parent().offset().left;
                           //$("div #ifrm1div > iframe").offset()
                           //var xPosition = $("#ifrm"+index+"div > iframe").offset().top;
                           //var yPosition =  $("#ifrm"+index+"div > iframe").offset().left;
                           console.log("x " + xPosition + "y " + yPosition);
                           //console.log(xPosition + "ypos "+ yPosition);
                           var divChartObj = {
                            xPos: xPosition,
                            yPos: yPosition,
                            chart: chartObj
                           };
                           console.log(divChartObj,"@328");
                           chartArray.push(divChartObj);
                       }
                       else
                       {


                        var tableObj = $('#tableContainer', $(iFrameId).contents()).html();
                           var xPosition = $(iFrameId).parent().offset().top; // added some arbitrary padding
                           var yPosition = $(iFrameId).parent().offset().left;
                           console.log("x " + xPosition + "y " + yPosition);
                           var divTableObj = {
                            xPos: xPosition,
                            yPos: yPosition,
                            chart: tableObj
                           };
                           tableArray.push(divTableObj);
                           var tableObject = $(divTableObj.chart);



                           console.log($(divTableObj.chart),"@272");


                       }
                   });

                    Highcharts.exportCharts(chartArray, {
                        type: 'application/pdf'
                    });
                 });
             });
      </script>
      <script src="https://rawgit.com/yWorks/jsPDF/master/dist/jspdf.debug.js"></script>
      <script src="https://rawgit.com/yWorks/svg2pdf.js/master/dist/svg2pdf.js"></script>
      <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script> -->
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
      <script src="https://files.codepedia.info/files/uploads/iScripts/html2canvas.js"></script>
      <script>
         // $(document).ready(function(){


         // var element = $("#ifrm3"); // global variable
         // var getCanvas; // global variable

         // $("#btn-Preview-Image").on('click', function () {
         //     html2canvas(element, {
         //         onrendered: function (canvas) {
         //             $("#previewImage").append(canvas);
         //             getCanvas = canvas;
         //         }
         //     });
         // });

         // $("#btn-Convert-Html2Image").on('click', function () {
         //     var imgageData = getCanvas.toDataURL("image/png");
         //     // Now browser starts downloading it instead of just showing it
         //     var newData = imgageData.replace(/^data:image\/png/, "data:application/octet-stream");
         //     $("#btn-Convert-Html2Image").attr("download", "your_pic_name.png").attr("href", newData);
         // });

         // });

      </script>
      <!-- <script src="https://code.jquery.com/jquery-1.12.4.js"></script> -->
      <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.3/jspdf.min.js"></script> -->
      <!--  <script>
         $(function() {
             var ifrmChart = undefined;
             var chartArray = [];


             Highcharts.getSVG = function(charts) {
                 var svgArr = [],
                 top = 0,
                 line = false,
                 count = 0,
                 width = 0;
                 graphCount = charts.length;
                  // console.log(graphCount);

                  Highcharts.each(charts, function(chartArray) {
                     chart = chartArray.chart;
                     var xpos = chartArray.xPos;
                     var ypos = chartArray.yPos;
                    //console.log('typeof' + typeof(xpos));
                    //console.log(xpos,ypos);
                    var svg = chart.getSVG(),
                      // Get width/height of SVG for export
                      svgWidth = +svg.match(
                         /^<svg[^>]*\swidth\s*=\s*\"?(\d+)\"?[^>]*>/
                         )[1],
                      svgHeight = +svg.match(
                         /^<svg[^>]*height\s*=\s*\"?(\d+)\"?[^>]*>/
                         )[1];

                      svg = svg.replace('<svg', '<g><path style="padding: 20px"></path></g><g style="padding: 20px" transform="translate(' + ypos + ',' + xpos + ')" ');



                      svg = svg.replace('</svg>', '</g>');



                      svgArr.push(svg);
                  });

                  // return '<svg style="padding:20px; display:inline-block;" height="' + top + '" width="' + width +
                  // '" version="1.1" xmlns="http://www.w3.org/2000/svg">' +
                  // svgArr.join('') + '</svg>';


                  return "<svg height='" + $(document).height() + "' width='" + $(document).width() + "' version='1.1' xmlns='http://www.w3.org/2000/svg'>" +
                  svgArr.join('') + '</svg>';
              };

              Highcharts.exportCharts = function(charts, options) {

                  //Highcharts.setOptions({ });
                  // Merge the options
                  options = Highcharts.merge(Highcharts.getOptions().exporting, options);
                  svgContent = Highcharts.getSVG(charts);
                  console.log(svgContent);
                  console.log($(svgContent));


                  // Post to export server
                  // Highcharts.post(options.url, {
                  //     filename: options.filename || 'chart',
                  //     type: options.type,
                  //     width: options.width,
                  //     svg: Highcharts.getSVG(charts),
                  // });


                  var svgString = svgContent;
                  var htmlObject = document.createElement('div');
                  htmlObject.setAttribute("id", "svgexport");
                  htmlObject.innerHTML = svgString;
                  console.log(htmlObject);
                  // htmlObject.getElementById("myDiv").style.marginTop = something;




                  var svg = htmlObject.querySelector('svg'),
                  pdf = new jsPDF('p', 'pt', [$(document).height(), $(document).width()]);


                  setTimeout(function() {

                     svg2pdf(svg, pdf, {
                         removeInvalid: true,
                         scale: 72 / 96, // this is the ratio of px to pt units
                     });

                     var data = pdf.output('datauristring');
                     var dl = document.getElementById('pdf-download');

                     dl.innerHTML = 'Download PDF';
                     dl.href = data;
                     dl.download = 'mychart.pdf';
                 }, 1000);
              };
              $('#export-png').click(function() {
                 Highcharts.exportCharts(chartArray);
             });

              $('#export-pdf').click(function() {

                 chartArray = [];
                 <!-- console.log("Frame1 Chart: "); -->
      <!-- console.log($('#ifrm1')[0].contentWindow.getChart()); -->
      <!-- chartArray.push($('#ifrm1')[0].contentWindow.getChart()); -->
      <!-- console.log("Frame2 Chart: "); -->
      <!-- console.log($('#ifrm2')[0].contentWindow.getChart()); -->
      <!-- chartArray.push($('#ifrm2')[0].contentWindow.getChart()); -->
      <!-- console.log(chartArray.length); -->
      <!-- console.log($('#ifrm3')[0].contentWindow.getChart()); -->
      <!-- chartArray.push($('#ifrm3')[0].contentWindow.getChart()); -->
      <!-- console.log($('#ifrm4')[0].contentWindow.getChart()); -->
      <!-- chartArray.push($('#ifrm4')[0].contentWindow.getChart()); -->
      <!-- console.log($('#ifrm5')[0].contentWindow.getChart()); -->
      <!-- chartArray.push($('#ifrm5')[0].contentWindow.getChart()); -->
      <!--  $("iframe").each(function(index) {
         console.log(index + ": " + $(this).attr('id'));
         var iFrameId = "#" + $(this).attr('id');
         console.log(iFrameId);
         var chartObj = $(iFrameId)[0].contentWindow.getChart();

         var xPosition = $(iFrameId).parent().offset().top; // added some arbitrary padding
         var yPosition = $(iFrameId).parent().offset().left;
         //$("div #ifrm1div > iframe").offset()
         //var xPosition = $("#ifrm"+index+"div > iframe").offset().top;
         //var yPosition =  $("#ifrm"+index+"div > iframe").offset().left;
         console.log("x " + xPosition + "y " + yPosition);
         //console.log(xPosition + "ypos "+ yPosition);
         var divChartObj = {
         xPos: xPosition,
         yPos: yPosition,
         chart: chartObj
         };
         console.log(divChartObj,"@328");
         getPDF(divChartObj);
         chartArray.push(divChartObj);
         });

         Highcharts.exportCharts(chartArray, {
         type: 'application/pdf'
         });
         });
         });

         function getPDF(divChartObj) {

         var HTML_Width = $(".canvas_div_pdf").width();
         var HTML_Height = $(".canvas_div_pdf").height();
         var top_left_margin = 15;
         var PDF_Width = HTML_Width + (top_left_margin * 2);
         var PDF_Height = (PDF_Width * 1.5) + (top_left_margin * 2);
         var canvas_image_width = HTML_Width;
         var canvas_image_height = HTML_Height;

         var totalPDFPages = Math.ceil(HTML_Height / PDF_Height) - 1;


         html2canvas($(".canvas_div_pdf")[0], {
         allowTaint: true
         }).then(function (canvas) {
         canvas.getContext('2d');

         console.log(canvas.height + "  " + canvas.width);

         var imgData = canvas.toDataURL("image/jpeg", 1.0);

         // var graphimgData = new XMLSerializer().serializeToString(svgContent);
         var encodedData = window.btoa(graphimgData);
         console.log("@520 encodedData",encodedData);
         var pdf = new jsPDF('p', 'pt', [PDF_Width, PDF_Height]);
         pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin,canvas_image_width,canvas_image_height);
         // pdf.addSVG(svgContent, 0,0, 1000, 1000);
         // pdf.addImage(divChartObj, 'svgContent', top_left_margin, top_left_margin,canvas_image_width,canvas_image_height);
         console.log("svgContent is", svgContent);

         // var img = canvas.toDataURL("image/png");
         // var doc = new jsPDF('l', 'mm', [50, 120]);
         // pdf.addImage(img, 'PNG', 0, 0, 120, 50);

         var htmlObject = document.createElement('div');
         htmlObject.setAttribute("id", "svgexport");
         htmlObject.innerHTML = svgContent;
         var canvas = document.createElement('canvas');
         canvg(canvas, svgContent);
         var graphimgData = canvas.toDataURL('image/png');
         console.log("@533 graphimgData",graphimgData)
         pdf.addImage(graphimgData, 'PNG', 10, 10, 25, 25);
         <!--              var svgContentForExport = new XMLSerializer().serializeToString(htmlObject);-->
      <!--  // pdf.addSVG(divChartObj, 140, 140, 1400, 1400);
         console.log("svgContent is ", svgContent);
               console.log("divChartObj is ", divChartObj);

               console.log("pdf is",pdf);
               <!--            addSvgAsImage(svgContentForExport, 0, 0, 1000, 1000, NONE, 0)-->
      <!-- for (var i = 1; i <= totalPDFPages; i++) {
         pdf.addPage(PDF_Width, PDF_Height);
         pdf.addImage(imgData, 'JPG', top_left_margin, -(PDF_Height * i) + (top_left_margin * 4), canvas_image_width, canvas_image_height);
         pdf.addSVG(svgContent, 140, 140, 1400, 1400);
         }

         pdf.save("HTML-Document.pdf");
         }); -- -->
      <!-- };
         $('#export-div').click(function () {
            getPDF();
         }); -->
      <!-- </script> -->
   </body>
</html>

Как вы можете видеть, я использую функцию highcharts getsvg для получения кода svg изнутри фреймов. 'Tablearray' содержит код для таблицы, находящейся внутри iframe. Я также могу экспортировать PDF.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...