16

I am having trouble in rendering svg element to pdf using jspdf . Iam using plugin https://github.com/CBiX/svgToPdf.js/ to do this.

Below is my code

// I recommend to keep the svg visible as a preview
var tmp = document.getElementById("chartContainer");
var svgDoc = tmp.getElementsByTagName("svg")[0];
var pdf = new jsPDF('p', 'pt', 'a4');
svgElementToPdf(svgDoc, pdf, {
scale: 72 / 96, // this is the ratio of px to pt units
removeInvalid: false // this removes elements that could not be translated to pdf from the source        svg
});
pdf.output('datauri'); // use output() to get the jsPDF buffer

It is generarting blank pdf. Please help

Priyesh Tiwari
  • 331
  • 1
  • 3
  • 13

3 Answers3

13

You can do that using canvg.

Step1: Get "SVG" markup code from DOM

var svg = document.getElementById('svg-container').innerHTML;

  if (svg)
    svg = svg.replace(/\r?\n|\r/g, '').trim();

Step 2: Use canvg to create canvas from svg.

  var canvas = document.createElement('canvas');
  canvg(canvas, svg);

Step 3: Create image from canvas using .toDataURL()

  var imgData = canvas.toDataURL('image/png');
  // Generate PDF
  var doc = new jsPDF('p', 'pt', 'a4');
  doc.addImage(imgData, 'PNG', 40, 40, 75, 75);
  doc.save('test.pdf');

Check the demo here http://jsfiddle.net/Purushoth/hvs91vpq/193/

Canvg Repo: https://github.com/gabelerner/canvg

Purushoth
  • 2,673
  • 3
  • 22
  • 36
  • Your JSFiddle doesn't work on Firefox (I tried with FF47 Windows) – Basj Nov 25 '16 at 09:14
  • 2
    Nothing happens when I click on "Get PDF" @Purushoth, here is the error `ReferenceError: canvg is not defined`. It seems that the link is not set correctly in your jsfiddle : https://gabelerner.github.io/canvg/canvg.js doesn't exist. Could you update it? Thanks in advance! – Basj Mar 14 '17 at 10:42
  • The external resources has been removed/moved it seems. But the code will work with correct external references. Check here for more details,https://github.com/gabelerner/canvg. – Purushoth Mar 14 '17 at 10:45
  • It is fixed now, http://jsfiddle.net/Purushoth/hvs91vpq/ @Basj. Thanks for pointing out. – Purushoth Mar 14 '17 at 10:52
  • Thanks, it's working now! Another problem for which I would donate 500 points at least :) If you open https://josephernest.github.io/Writing/, and write `$$x^2+1$$` it's rendering into math using "MathJax". Then it seems impossible to turn this into PDF with usual JS PDF libraries. Do you have an idea? https://github.com/josephernest/Writing – Basj Mar 14 '17 at 11:27
  • If the answer is helpful, you can upvote :) MathJax is a js engine for LaTex and MathML. MathML is an application of XML. We can export to PDF if it is in SVG or Canvas format. Here is a fiddle that shows to display Math formulas in SVG format. Then we can export the SVG to PDF. http://jsfiddle.net/p3wuu2pw/7/ You can write a new question explaining your problems. So it will be helpful to discuss. @Basj – Purushoth Mar 14 '17 at 11:50
  • Yes, it seems so... I spent days on this, with no success... Do you see if you can manage to export to PDF with https://github.com/josephernest/Writing/ ? It's 100% open source, and having PDF export would be amazing, and a great contribution to open source community :) – Basj Mar 14 '17 at 11:52
  • Yes it is possible to export. Please write another question so that it will be helpful for others. – Purushoth Mar 14 '17 at 11:56
  • Here is the question @Purushoth : http://stackoverflow.com/questions/42785850/render-mathjax-into-pdf. I'll start a big bounty because this question would be really helpful for the whole open-source community! – Basj Mar 14 '17 at 12:22
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/138014/discussion-between-purushoth-and-basj). – Purushoth Mar 14 '17 at 12:35
  • Thanks for showing a solution on _how one could get the visible part accordingly in your pdf_, but technically it isn't SVG and comes with all the downsides of a rasterized image. – Thomas Junk Jun 28 '19 at 08:42
  • Technically it is not possible to embedded a SVG to jsPDF document. You have to rasterize it , https://github.com/MrRio/jsPDF/issues/1740 @ThomasJunk – Purushoth Jul 02 '19 at 10:42
  • @Purushoth I know, because I am having just this problem of putting d3 as SVG in a PDF. But There is https://github.com/yWorks/svg2pdf.js/tree/master which uses https://github.com/yWorks/jsPDF (their own fork). And they are working on a fusion with upstream. – Thomas Junk Jul 02 '19 at 14:11
  • What if you have dozens of SVGs on a given page? – Kirk Ross Sep 04 '20 at 04:07
  • @KirkRoss For all SVG the `id` should be unique so you can get whichever you want. ``` var svg1 = document.getElementById('svg-container-1').innerHTML; var svg2 = document.getElementById('svg-container-2').innerHTML; ``` Then follow the same procedure mentioned above. You can loop it too. – Purushoth Sep 08 '20 at 08:51
3

I've tried both svg2pdf.js and addSvgAsImage using canvg internally. Both didn't work well for me, the resulting images in the pdf where either incorrectly positioned or displayed.

I've ended up doing the following which works very well:

  1. convert the SVG to PNG without any libraries, see my answer to "Convert SVG to image (JPEG, PNG, etc.) in the browser".
  2. just add the result to the pdf using the normal addImage method
klues
  • 847
  • 12
  • 21
2

I think the current jspdf version (2.3.1) has an addSvgAsImage method, but it takes the svg as a string. I guess you could use an ajax call to retrieve the SVG content, but I just have the SVG in my code and pass it in that way.

cmzmuffin
  • 181
  • 1
  • 5
  • Thanks, this is way more better approach. Rather then converting svg to images back or converting svg to canvas which is not at all efficient if one want to achieve the sharpness in pdf. – Jawand Singh Aug 05 '21 at 14:30