javascript 使用 html2canvas 将 highcharts 图表呈现为 pdf 在 IE 和 Firefox 上不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34042440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 17:10:41  来源:igfitidea点击:

Using html2canvas to render a highcharts chart to pdf doesn't work on IE and Firefox

javascriptpdfsvghighchartshtml2canvas

提问by Rob

We are using html2canvas.js and html2canvas.svg.js (version 0.5.0 beta1) and highcharts.js to download a donut chart into pdf.

我们正在使用 html2canvas.js 和 html2canvas.svg.js(版本 0.5.0 beta1)和 highcharts.js 将圆环图下载为 pdf。

This works as expected in Chrome, however in IE and Firefox this isnt working. In IE the chart is rendered incorrectly, and in Firefox it is not rendered at all.

这在 Chrome 中按预期工作,但是在 IE 和 Firefox 中这不起作用。在 IE 中,图表呈现不正确,而在 Firefox 中,它根本没有呈现。

Below are screenshots of the download in Chrome, IE and Firefox

以下是 Chrome、IE 和 Firefox 下载的截图

ChromeChrome

铬合金铬合金

IE(Edge) IE

IE(边缘) IE

Firefoxenter image description here

火狐在此处输入图片说明

The code i am using to do the html2canvas is as follows:

我用来做 html2canvas 的代码如下:

html2canvas($("#container"), {
    onrendered: function (canvas) {
      var imgData = canvas.toDataURL(
        'image/png');
      var doc = new jsPDF('p', 'mm');
      doc.addImage(imgData, 'PNG', 10, 10);
      doc.save('sample-file.pdf');
    }
  });

I have created a jsFiddle that demonstrates the issue here - http://jsfiddle.net/jko0rs5g/3/

我创建了一个 jsFiddle 来演示这里的问题 - http://jsfiddle.net/jko0rs5g/3/

Does anyone know what might be causing this issue, and how we can resolve it?

有谁知道可能导致此问题的原因,以及我们如何解决?

EDIT

编辑

Just to clarify why we are not using the built in Highcharts exporting, this for when we are adding additional html to the Highcarts, such as additional information above or below the chart, or a score inside the donut for example. I have updated the jsfiddle to reflect this.

只是为了澄清为什么我们不使用内置的 Highcharts 导出,这是为了当我们向 Highcarts 添加额外的 html 时,例如图表上方或下方的附加信息,或甜甜圈内的分数。我已经更新了 jsfiddle 以反映这一点。

回答by Rob

Thanks to Pawel Fus for the nod in the right direction, we got this working using canvg.js, which temporarily replaces the svg with a canvas before calling html2canvas.

感谢 Pawel Fus 向正确的方向点头,我们使用 canvg.js 完成了这项工作,它在调用 html2canvas 之前暂时用画布替换了 svg。

The final issue came when some of the html within the svg uses em's to size the font (which unfortunately a lot of our templates do). We got around this by updating the font size for anything using em's to the underlying pixel size before rendering the svg into a canvas (see Get computed font size for DOM element in JSfor how we calculated the actual font size)

当 svg 中的某些 html 使用 em 来调整字体大小时,最后一个问题就出现了(不幸的是,我们的许多模板都这样做)。我们通过在将 svg 渲染到画布之前将任何使用 em 的字体大小更新为底层像素大小来解决这个问题(有关我们如何计算实际字体大小的信息,请参阅获取 JS 中 DOM 元素的计算字体大小)

Below is the updated code for the download button click

以下是下载按钮单击的更新代码

$('#download').click(function() {
  var svgElements = $("#container").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();
  });


  html2canvas($("#container"), {
    onrendered: function(canvas) {
      var imgData = canvas.toDataURL(
        'image/png');
      var doc = new jsPDF('p', 'mm');
      doc.addImage(imgData, 'PNG', 10, 10);
      doc.save('sample-file.pdf');
    }
  });

  $("#container").find('.screenShotTempCanvas').remove();
  $("#container").find('.tempHide').show().removeClass('tempHide');
});

See an updated jsfiddle of it in action here - http://jsfiddle.net/zuvzcgvz/22/

在此处查看更新的 jsfiddle 操作 - http://jsfiddle.net/zuvzcgvz/22/