41

The starting points: I don't have a server that can provide anything but static files. And I have an SVG element (dynamically created) in my <body> that I want to export to a vector format, preferrably PDF or SVG.

I started looking at using the already existing lib jsPDF along with downloadify. It worked fine. Unfortunately, this does not support SVG, only text.

I've read about the PDF format's possiblities to embed SVG images, and it seems to have been enabled since Acrobat Reader 5 (along with the ImageViewer plugin). But it doesn't work. I've tried with 3 different PDF readers without success.

Does this mean that PDFs has dropped SVG embedding support? I haven't found anything on this.

I have two questions; can this be solved? And if yes, what are the specifications for embedding SVG inside of a PDF? With that info, I can build that support in jsPDF myself.

The browser support demands are Safari, Chrome and Firefox. The versions that supports SVG.

Simeon
  • 5,519
  • 3
  • 29
  • 51

6 Answers6

38

For anyone looking for a JS-only solution: PDFKit seems to be the superior solution to generate PDF from JS these days, and it supports all SVG geometry primitives (including interpreting path geometry strings) out of the box. All that would be needed to render existing SVG content would be a DOM-walker that keeps track of CSS styling and inheritance, if you do not require complex stuff like symbols etc.

I wasn't successful with the sketchy SVG support of the jsPDF/svgToPdf combo mentioned in the other answer, and the source code of these two didn't look very well-crafted and complete to me.

Edit: Usage example JSFiddle

Klesun
  • 12,280
  • 5
  • 59
  • 52
Florian Ledermann
  • 3,187
  • 1
  • 29
  • 33
  • One question. 1. Open http://pdfkit.org/demo/browser.html. 2. Open Chrome Inspect Window. 3. Click "Toggle Device Toolbar" icon on the top menu. 4. Refresh the page. 5. I CANNOT see the pdf on the right window in the mobile view. 6. Do anyone know why the mobile view is not rendering the PDF. ? Is it this PDFKit specific or general problem with opening pdf on mobile ? – Arun Kandregula Mar 04 '18 at 19:40
  • 3
    PDFKit in conjunction with https://github.com/alafr/SVG-to-PDFKit seems to be the way to go. – James M Apr 11 '19 at 08:30
  • cant convert html to pdf directly – Mustkeem K Nov 28 '19 at 14:18
  • It doesn't support the image tag!? – Shmack Oct 28 '20 at 23:07
7

I'll reply to my own question. I ended up using DocRaptor that can be called client-side from JavaScript. This technically solves my problem, even though it is a non-free solution. If I the answer could be a server-side-solution, I could use wkhtmltopdf as proposed by Mic.

Community
  • 1
  • 1
Simeon
  • 5,519
  • 3
  • 29
  • 51
  • 1
    Thanks for the link to DocRaptor. If you go the route of hosting something, you can use WKHTMLTOPDF, as it is free and open sourced – Mic May 09 '11 at 13:35
  • 1
    Added your answer and removed Prince XML as an alternative, thanks! – Simeon May 09 '11 at 14:45
6

jsPDF has a plugin for that: svgToPdf:

https://github.com/ahwolf/jsPDF/blob/master/jspdf.plugin.svgToPdf.js

I haven't tried it, but this could allow discarding the use of an external API and/or having to rely on a server-side solution.

stackex
  • 643
  • 10
  • 11
  • 2
    I'm currently trying this approach but I only seem to get a blank pdf from it. Do you know of any examples out there that use this plugin? – BelgoCanadian Sep 13 '17 at 15:40
4

Did you try WKHTMLTOPDF? It's a free tool based on webkit.
We wrote a small tutorial here.

On a Mac, with Safari or Chrome, you can save an HTML page with embedded SVG to a PDF.
Since these browsers use WKHTMLTOPDF internally, may be this will work for you as well.

Mic
  • 24,812
  • 9
  • 57
  • 70
  • 1
    I'm asking for a client-side solution here. However, you are right in that I've not specified what browser support I'm going for. So I've now edited my answer to include that – Simeon May 06 '11 at 16:32
  • I, unfortunately, still can't make wkhtmltopdf work. It only produces blank pages for me. – art-solopov Jun 30 '15 at 17:07
  • @art-solopov, times have changed, as mentionned above, you could switch to pdfkit: http://pdfkit.org/docs/vector.html – Mic Jun 30 '15 at 20:33
0

Minimal example using pdfkit, svg-to-pdfkit and blob-stream, that downloads an SVG DOM element as a PDF.

  1. Import packages in your index.html.
<script src="https://cdn.jsdelivr.net/npm/pdfkit@0.10.0/js/pdfkit.standalone.js"></script>
<script src="https://bundle.run/blob-stream@0.1.3"></script>
<script src="https://cdn.jsdelivr.net/npm/svg-to-pdfkit@0.1.8/source.js"></script>
  1. Run this function, where svg is an SVG DOM element, or SVG string.
function downloadPDF(svg, outFileName) {
    let doc = new PDFDocument({compress: false});
    SVGtoPDF(doc, svg, 0, 0);
    let stream = doc.pipe(blobStream());
    stream.on('finish', () => {
      let blob = stream.toBlob('application/pdf');
      const link = document.createElement('a');
      link.href = URL.createObjectURL(blob);
      link.download = outFileName + ".pdf";
      link.click();
    });
    doc.end();
}
Ulf Aslak
  • 7,876
  • 4
  • 34
  • 56
  • shapes are correct but all color and text is blacked out. – Frank Apr 28 '22 at 19:40
  • @Frank hmmm.. can't reproduce. What browser and version? Anyone else getting this? – Ulf Aslak Apr 29 '22 at 11:49
  • 1
    I created a minimal example here and linked to your answer in the post https://stackoverflow.com/questions/72061301/strange-output-when-converting-svg-to-pdf-javascript-mermaid-js-example – Frank Apr 29 '22 at 16:55
-1

EVO HTML to PDF Converter has support for converting the SVG embedded in HTML to PDF. You can see an example for this feature here : http://www.evopdf.com/demo/HTML_to_PDF/HTML5_Features/SVG_to_PDF.aspx . The sample code for this is:

// Create a HTML to PDF converter object with default settings
HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter();

// Convert the HTML page with SVG to a PDF document in a memory buffer
byte[] outPdfBuffer = htmlToPdfConverter.ConvertUrl(urlHtmlWithSVG);

// Send the PDF as response to browser

// Set response content type
Response.AddHeader("Content-Type", "application/pdf");

// Instruct the browser to open the PDF file as an attachment or inline
Response.AddHeader("Content-Disposition", String.Format("attachment; filename=SVG_to_PDF.pdf; size={0}", outPdfBuffer.Length.ToString()));

// Write the PDF document buffer to HTTP response
Response.BinaryWrite(outPdfBuffer);

// End the HTTP response and stop the current page processing
Response.End();
EvoPdf
  • 523
  • 3
  • 9
  • 2
    EVO pdf doesn't fit the svg image on entire pdf page. There is lot of blank space on all the sides of the image. I have tried all the option like FitWidth, FitHeight, StretchToFit etc. But couldn't solve the issue. – Arpit Gupta Oct 12 '18 at 04:40
  • 1
    I'm experiencing the same issue as ArpitGupta where the layout around the SVG is completely wrong when using @EvoPdf I have a container div wrapping an SVG and I'm using flexbox to vertically & horizontally center the container. When converted to PDF, the layout/alignment is the same as if I completely remove the flexbox styles. – Jameson Jun 18 '19 at 12:17