2016-05-10 2 views
10

Я использую jsPDF для преобразования html в pdf. В некоторых случаях, когда html имеет svg-диаграммы, некоторые данные дублируются в сгенерированном PDF-файле.Повторяющийся контент в pdf, созданный с помощью jsPDF

например. Если в диаграммах есть легенды, они дублируются. См. Снимок экрана ниже. Имена городов и проценты повторяются.

enter image description here

Ниже приведен код для создания PDF.

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

EDIT 1:

Это то, что я понял до сих пор.

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

Когда я делаю это, pdf.addHTML($("#pieChart"), никаких вопросов здесь.

Но, когда я это делаю, pdf.addHTML($("#outerDiv"), затем метки повторяются.

и это, как я генерировать мои c3js диаграммы

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

EDIT 2: -

Ниже весь мой код.

<!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: -

Я пытался просто преобразовывая HTML на холст с помощью html2canvas. Это также дает ту же проблему.

Редактировать 4:

я мог исправить дубликата вопрос сейчас. Но диаграммы и текст, написанный в формате pdf, немного размыты. В принципе, я добавил функцию replaceAllSVGsWithTempCanvas, а затем использовал это при записи в pdf. Но, похоже, эта функция делает что-то плохое для html, что делает контент, написанный в формате pdf, размытым. На самом деле круговые диаграммы и т. Д. Больше не кругах, а овальной форме.

Отредактированный вопрос с измененным js.

+0

пожалуйста, вы можете загрузить HTML, JS код поиграться – Raki

+0

@Raki Я редактировал вопрос и добавил все HTML и JS код. – ashishjmeshram

+0

Jus add $ (". C3 svg"). Css ({"font-size": "0px"}); перед pdf.addHTML (... Как объясняет мой андер.;) –

ответ

3

Похоже, что это ошибка в html2canvas. Вы должны добавить нижний код после html2canvas загружен, чтобы исправить, что (Credits идет к 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

Поскольку html2canvas нагрузок в качестве модуля, вы должны непосредственно найти NodeParser.prototype.getChildren в исходном коде и редактировать он должен соответствовать выше. Это означает, что вы не можете загрузить его из CDN.

+0

В каком файле следует изменить? addhtml.js? или jspdf.debug.js? – ashishjmeshram

+0

@anything Umm, html2canvas.js. –

+0

Он исправил проблему для круговых диаграмм, но проблема все еще остается для линейных диаграмм линейных диаграмм. Метки на оси x и y повторяются. Есть идеи? – ashishjmeshram

1

Вы можете попробовать использовать ChartJS вместо C3.

Я адаптировал ваш код и пробовал его с успехом.

<!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

Мы не можем изменить библиотеку диаграмм прямо сейчас, поскольку мы создали так много диаграмм уже, и нам придется переписать все. В настоящее время это невозможно. – ashishjmeshram

2

Я думаю, что он работал правильно в два этапа.
Во-первых, я закомментировал «addhtml плагин», потому что у меня была эта ошибка в моей консоли:

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. 

Во-вторых, я изменил источник в формате PDF из #chartOuter в #chart.

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

И больше нет дедублирования.

-----
EDIT
(так как я понял этот вопрос на первом)

Нужно использовать внешний DIV ... А может быть, полная страница.

Хорошо ... Честно говоря, я не знаю, почему этот текст возникает.
Но я заметил, что дублирующийся текст имеет засечку, даже если он указан «sans-serif».
Итак, я сосредоточился на этом.
Я попытался изменить размер шрифта ... Это повлияло на дубликат, но текст не соответствовал правилу css. Хорошо.

Затем я попытался просто удалить текст перед частью создания pdf ... И магия!
;)

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

Вот полный сценарий, я не трогал остальную часть исходного кода.

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

Пожалуйста, ознакомьтесь с комментариями к первой редакции. Он работает, когда я использую #chart, но теперь, когда я использую #chartOuter. – ashishjmeshram

+0

Хорошо ... Но зачем вам тогда использовать внешний div? –

+0

Посмотрите, есть много других вещей в html, которые мне нужно написать в формате pdf. Я могу очень просто выбрать диаграмму div и написать в pdf, но тогда все остальные css и html нужно будет сделать вручную. – ashishjmeshram

Смежные вопросы