0

I'm trying to convert via javascript an svg file to a pdf file. I thought it would be simple.

But everything I've seen online rasterizes the svg and the resulting pdf looks blurry. For example:

http://ihaochi.com/svg_to_pdf/ (which converts svg to a png then puts it into a pdf document via jspdf)

But shouldn't pdf have vector capabilities? Ie, I don't want an image inside a pdf. I want numeric values kind of the way svg works, because it prints better that way.

Shai UI
  • 50,568
  • 73
  • 204
  • 309

2 Answers2

4

I have tested many JavaScript libraries that convert SVG to PDF for my web project including the above-mentioned one, and experienced over and over the same thing that the pdf gets produced at only screen-resolution. Finally, I have made very good experience with css2pdf (http://www.cloudformatter.com/css2pdf). It uses a small JavaScript library called "XEPOnline javascript" to extract the content of the svg including all the css-styling on the client-side, and sends this information to a XEP rendering engine on amazon cloud for generating the pdf. The output pdf file is high-resolution, please check out my example fiddle where I export Plotly.js and C3.js svg charts to pdf: http://jsfiddle.net/3hs7cs4f/10/

Here is the corresponding code to the fiddle:

<link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css" rel="stylesheet" />
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script src="http://www.cloudformatter.com/Resources/Pages/CSS2Pdf/Scrip /xeponline.jqplugin.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.js"></script>

<script>
function addnsandprint(){
$('#c3_chart').find('svg').attr('xmlns','http://www.w3.org/2000/svg');
xepOnline.Formatter.Format('c3_chart',{pageWidth:'11in', pageHeight:'8.5in',render:'download', srctype:'svg'});
}
</script>

<body>
<br><br>
<!-- Source and on-click event for plotly.js -->
<div id="plotly_chart" style="width: 90%; height: 270px"></div>
<button onclick="return xepOnline.Formatter.Format('plotly_chart',{pageWidth:'11in', pageHeight:'8.5in',render:'download', srctype:'svg'});">Get plotly_PDF</button>

<!-- Source and on-click event for c3.js-->
<div id="c3_chart" style="width: 90%; height: 270px"></div>
<button onclick="return addnsandprint()">Get c3_PDF</button>

<!-- JAVASCRIPT for plotly.js chart -->
<script type="text/javascript">
 Chart = document.getElementById('plotly_chart');
 Plotly.plot( Chart, [{
   x: [1, 2, 3, 4, 5],
   y: [1, 2, 4, 8, 16] }], { 
   margin: { t: 0 } } );
</script>

<!-- JAVASCRIPT for j3.js chart -->
<script type="text/javascript">
   var chart = c3.generate({
   bindto: '#c3_chart',
   padding: {
       top: 10,
       right: 70,
       bottom: 50,
       left: 75,
   },
   data: {
       columns: [
           ['data1', 100, 200, 150, 300, 200],
           ['data2', 400, 500, 250, 700, 300],
       ]
   }});
</script>

I would like to thank Kevin Brown (https://stackoverflow.com/users/2491227/kevin-brown) for his great help on getting everything running, please also have a look at my previous post SVG to PDF conversion working for Plotly.js but not for C3.js

schustischuster
  • 743
  • 9
  • 29
  • 1
    Does XEPonline still work? Running your fiddle i get The web page at http://xep.cloudformatter.com/Chandra.svc/genfile might be temporarily down or it may have moved permanently to a new web address. Thanks for this post though – Shane G Feb 08 '19 at 12:24
  • 1
    Yes, it does still work. I am using it for one of my projects that I am currently working on. Click on the second button "Get c3_PDF" in the fiddle example. It did work for the plotly chart as well when I created the fiddle, but now it does not anymore. Must be something wrong with the plotly SVG properties. – schustischuster Feb 08 '19 at 23:01
2

Actually, PDF is not a "vector" format. Its closest technical relative is "EPS = Encapsulated PostScript®."

I would not assume that PDF contains vector-drawing primitives that would be expected to "map one-to-one" with those in SVG.

Mike Robinson
  • 8,490
  • 5
  • 28
  • 41
  • https://en.wikipedia.org/wiki/Portable_Document_Format#Vector_graphics – Kaiido Aug 09 '16 at 11:07
  • To clarify: "the vector-graphic capabilities of PDF are not necessarily 'directly compatible' or 'one-to-one convertible' *vis-a-vis* those of SVG." – Mike Robinson Aug 09 '16 at 14:03
  • so can I put an eps inside a pdf? (and maybe I could convert svg to eps?) – Shai UI Aug 09 '16 at 18:27
  • It took about 3.5 many years of development for the current RenderX XEP server side rendering of SVG to PDF. As stated above it is not 1 to 1 especially in masks, gradients and some other areas that require complex calculations to map between. – Kevin Brown Aug 10 '16 at 16:57
  • So, OP, I really *do* think that "you're stuck with what you've got," and all you can hope to do is to tweak it a little. That SVG is going to get rasterized, and the raster is going to be inserted into that (now, "big, phat") PDF. You can probably control the DPI resolution of the raster but that's probably about the extent of it. – Mike Robinson Aug 10 '16 at 17:02