2016-05-10 10 views
10

Ich benutze jsPDF, um HTML in PDF zu konvertieren. In einigen Fällen, in denen HTML SVG-Diagramme enthält, werden einige der Daten in der generierten PDF-Datei dupliziert.Duplizieren von Inhalt in PDF erstellt mit jsPDF

z.B. Wenn die Diagramme Legenden enthalten, werden sie dupliziert. Siehe den Screenshot unten. Ortsnamen und Prozentsätze werden wiederholt.

enter image description here

Unten ist der Code von PDF zu erstellen.

pdf.addHTML($("#page1"), options, function(){ 
      pdf.addPage(); 
      pdf.addHTML($("#page2"), options, function(){ 
       pdf.addPage(); 
       pdf.output('dataurlnewwindow'); 
      }); 
     }); 

EDIT 1:

Das ist, was ich bisher herausgefunden haben.

<div id="outerDiv"> 
    <div id="pieChart"></div> 
</div> 

Wenn ich das tue, pdf.addHTML($("#pieChart"), keine hier Probleme.

Aber, wenn ich das tue, pdf.addHTML($("#outerDiv"), dann Etiketten wiederholt erhalten.

und das ist, wie ich meine c3js Charts erzeugen

var pieChart = c3.generate({ 
      bindto: '#pieChart', 

EDIT 2: -

Unter meinen ganzen Code.

<!DOCTYPE html> 
<html> 

<head> 
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script> 
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css"> 
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.js"></script> 
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script> 
    <script type="text/javascript" src="http://gabelerner.github.io/canvg/rgbcolor.js"></script> 
    <script type="text/javascript" src="http://gabelerner.github.io/canvg/StackBlur.js"></script> 
    <script type="text/javascript" src="http://gabelerner.github.io/canvg/canvg.js"></script> 
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.2.61/jspdf.min.js"></script> 
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.5.0-alpha1/html2canvas.js"></script> 

    <script type='text/javascript'> 
    function replaceAllSVGsWithTempCanvas(elemSelector) { 
     var svgElements = $(elemSelector).find('svg'); 

     //replace all svgs with a temp canvas 
     svgElements.each(function() { 
      var canvas, xml; 

      // canvg doesn't cope very well with em font sizes so find the calculated size in pixels and replace it in the element. 
      $.each($(this).find('[style*=em]'), function(index, el) { 
       $(this).css('font-size', getStyle(el, 'font-size')); 
      }); 

      canvas = document.createElement("canvas"); 
      canvas.className = "screenShotTempCanvas"; 

      //convert SVG into a XML string 
      xml = (new XMLSerializer()).serializeToString(this); 

      // Removing the name space as IE throws an error 
      xml = xml.replace(/xmlns=\"http:\/\/www\.w3\.org\/2000\/svg\"/, ''); 

      //draw the SVG onto a canvas 
      canvg(canvas, xml); 
      $(canvas).insertAfter(this); 

      //hide the SVG element 
      $(this).attr('class', 'tempHide'); 
      $(this).hide(); 
     }); 
    } 

    jQuery(document).ready(function($) { 
     genChart(); 
    }); 

    function genPDF() { 
     var options = { 
      background: '#fff' 
     }; 
     var pdf = new jsPDF('p', 'pt', 'a4'); 

     replaceAllSVGsWithTempCanvas(".content"); 

     pdf.addHTML($("#chartOuter"), options, function() { 
      pdf.output('dataurlnewwindow'); 

      $(".content").find('.screenShotTempCanvas').remove(); 
      $(".content").find('.tempHide').show().removeClass('tempHide'); 

     }); 
    } 

    function genChart() { 
     var chart = c3.generate({ 
      data: { 
       columns: [ 
        ['data1', 30], 
        ['data2', 120], 
       ], 
       type: 'pie' 
      } 
     }); 
    } 
    </script> 
</head> 

<body class="content"> 
    <table width="100%"> 
     <tr> 
      <td width="50%"> 
       <div id="chartOuter"> 
        <div id="chart"></div> 
       </div> 
      </td> 
     </tr> 
     <tr> 
      <td colspan="2" align="left"> 
       <input type="button" onclick="genPDF();" value="Generate PDF" /> 
      </td> 
     </tr> 
    </table> 
</body> 

</html> 

EDIT 3: -

Ich habe gerade versucht, die Umwandlung mit Hilfe von HTML html2canvas auf der Leinwand. Es gibt auch das gleiche Problem.

bearbeitet 4:

Ich konnte nun das doppelte Problem beheben. Aber die Diagramme und der Text, die in pdf geschrieben sind, sind ein wenig verschwommen. Im Grunde genommen habe ich die Funktion replaceAllSVGsWithTempCanvas hinzugefügt und verwende sie dann beim Schreiben in PDF. Aber es scheint, dass diese Funktion zum HTML schmilzt, das Inhalt zum pdf verschwommen macht. In der Tat sind Kreisdiagramme usw. keine Kreise mehr, sondern sehen wie eine ovale Form aus.

die Frage mit modifizierten js Bearbeitet.

+0

können Sie bitte Ihre HTML-Upload-Code JS – Raki

+0

@Raki ich die Frage bearbeitet habe Geige und hinzugefügt, um den ganzen HTML-und JS-Code. – ashishjmeshram

+0

Jus add $ (". C3 svg"). Css ({"font-size": "0px"}); vor pdf.addHTML (... wie mein anwer erklärt.;) –

Antwort

3

Sieht aus wie es ein Fehler in html2canvas ist. Sie sollten den unteren Code hinzufügen, nachdem html2canvas das zu beheben geladen (Credits geht an this guy):

NodeParser.prototype.getChildren = function(parentContainer) { 
    return flatten([].filter.call(parentContainer.node.childNodes, renderableNode).map(function(node) { 
     var container = [node.nodeType === Node.TEXT_NODE && node.parentElement.tagName !== "text" ? new TextContainer(node, parentContainer) : new NodeContainer(node, parentContainer)].filter(nonIgnoredElement); 
     return node.nodeType === Node.ELEMENT_NODE && container.length && node.tagName !== "TEXTAREA" ? (container[0].isElementVisible() ? container.concat(this.getChildren(container[0])) : []) : container; 
    }, this)); 
}; 

Fiddle

Da html2canvas Lasten als Modul direkt NodeParser.prototype.getChildren im Quellcode und bearbeiten finden sollten es oben zusammenpassen. Das heißt, Sie können es nicht von CDN laden.

+0

In welcher Datei sollte ich ändern? addhtml.js? oder jspdf.debug.js? – ashishjmeshram

+0

@anything Umm, html2canvas.js. –

+0

Das Problem für Tortendiagramme wurde behoben, das Problem bleibt jedoch für die Balkendiagramme der Balkendiagramme bestehen. Die Beschriftungen auf der x- und y-Achse werden wiederholt. Irgendwelche Ideen? – ashishjmeshram

1

Sie können versuchen, ChartJS anstelle von C3 zu verwenden.

Ich habe Ihren Code angepasst und es mit Erfolg versucht.

<!DOCTYPE html> 
<html> 
<head> 
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script> 
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css"> 

    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.js"></script> 
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.min.js"></script> 

    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script> 

    <!-- <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.2.61/jspdf.debug.js"></script> --> 
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.2.61/jspdf.min.js"></script> 
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.5.0-alpha1/html2canvas.js"></script> 
    <script type="text/javascript" src="https://raw.githubusercontent.com/MrRio/jsPDF/master/plugins/addhtml.js"></script> 

    <script type='text/javascript'> 

     jQuery(document).ready(function ($) { 
      genChart(); 
     }); 

     function genPDF() { 
      var options = { background: '#fff'}; 
      var pdf = new jsPDF('p', 'pt', 'a4'); 

      pdf.addHTML($("#chartOuter"), options, function() { 
       var string = pdf.output('datauristring'); 
       $('.preview-pane').attr('src', string) 
      }); 
     } 

     function genChart() { 
      var ctx = $("#chart"); 
      var options = {}; 

      var myPieChart = new Chart(ctx, { 
       type: 'pie', 
       data: { 
        labels: [ 
         "data1", 
         "data2" 
        ], 
        datasets: [{ 
          data: [30, 120], 
          backgroundColor: [ 
           "#FF6384", 
           "#36A2EB" 
          ], 
          hoverBackgroundColor: [ 
           "#FF6384", 
           "#36A2EB" 
          ] 
         }] 
       }, 
       options: options 
      }); 
     } 
    </script> 
</head> 
<body> 

    <table width="100%"> 
     <tr> 
      <td width="50%"> 
       <div id="chartOuter"> 
        <!-- <div id="chart"></div> --> 
        <canvas id="chart" width="400" height="400"></canvas> 
       </div> 
      </td> 
      <td> 
       <iframe height="550px" class="preview-pane" type="application/pdf" width="100%" frameborder="0" style="position:relative;z-index:999"></iframe> 
      </td> 
     </tr> 
     <tr> 
      <td colspan="2" align="left"> 
       <input type="button" onclick="genPDF();" value="Generate PDF"/> 
      </td> 
     </tr> 
    </table> 

</body> 
</html> 
+0

Wir können die Diagrammbibliothek jetzt nicht ändern, da wir bereits so viele Diagramme erstellt haben und wir alles neu schreiben müssen. Was zu diesem Zeitpunkt nicht möglich ist. – ashishjmeshram

2

Ich denke, es funktioniert in zwei Schritten richtig.
Zuerst bemerkte ich aus dem "addhtml Plugin", weil ich diesen Fehler in meiner Konsole hatte:

Refused to execute script from 'https://raw.githubusercontent.com/MrRio/jsPDF/master/plugins/addhtml.js' because its MIME type ('text/plain') is not executable, and strict MIME type checking is enabled. 

Zweitens ich die pdf Quelle von #chartOuter zu #chart geändert.

pdf.addHTML($("#chart"), options, function() { 
    var string = pdf.output('datauristring'); 
    $('.preview-pane').attr('src', string) 
}); 

Und es gibt keine mehr deboubling.

-----
EDIT
(da ich die Frage zunächst falsch verstanden)

sie den äußeren div zu verwenden ist erforderlich ... Und vielleicht die ganze Seite.

Okay ... Um ehrlich zu sein, ich weiß nicht, warum dieses Textproblem passiert.
Aber ich habe festgestellt, dass der doppelte Text Serif hat, auch wenn es "Sans-Serif" angegeben ist.
Also konzentrierte ich mich darauf.
Ich habe versucht, die Schriftgröße zu ändern ... Es betraf das Duplikat, aber der Text folgte nicht der CSS-Regel. Okay.

Dann habe ich versucht, nur den Text vor dem PDF-Erstellungsteil zu entfernen ... Und Magie!
;)

$(".c3 svg").css({"font-size":"0px"}); 

ist die komplette Skript, ich nicht den Rest des ursprünglichen Code berührt hat.

jQuery(document).ready(function ($) { 
     genChart(); 
    }); 

    function genPDF() { 
     var options = { background: '#fff'}; 
     var pdf = new jsPDF('p', 'pt', 'a4'); 

     $(".c3 svg").css({"font-size":"0px"}); // <-- This does the trick ! 

     pdf.addHTML($("#chartOuter"), options, function() { 
      var string = pdf.output('datauristring'); 
      $('.preview-pane').attr('src', string) 
     }); 
    } 

    function genChart() { 
     var chart = c3.generate({ 
      data: { 
       columns: [ 
        ['data1', 30], 
        ['data2', 120], 
       ], 
       type : 'pie' 
      } 
     }); 
    } 
+0

Bitte beachten Sie meine Kommentare in der ersten Bearbeitung. Es funktioniert, wenn ich #chart verwende, aber jetzt, wenn ich #chartOuter verwende. – ashishjmeshram

+0

Ok ... Aber warum brauchen Sie dann das äußere Div? –

+0

Sehen Sie, es gibt viele andere Sachen in der HTML, die ich in pdf schreiben muss. Ich kann sehr gut nur das Diagramm div auswählen und in pdf schreiben, aber dann müssen alle anderen css und html manuell gemacht werden. – ashishjmeshram