简体   繁体   中英

Export SVG elements to PDF?

I have a visualization generated by d3 (a javascript visualization library similar to Protovis or Raphael, which draws stuff using SVG elements). The vis is interactive, so the user can interact with and edit it. Once the user is satisfied with his/her visualization, I would like the user to be able to export this visualization as a PDF. I've tried several HTML to PDF libraries and they don't work with SVG elements.

It is okay if the solution is either client side or server side. I'm using PHP server side but Python or Java implementations might also work.

Browser support: Ideally it would support all modern browsers, but minimally I'd like to support latest versions of both Firefox and webkit browsers.

I do not know of any strong PDF libraries on the client side.

A quick possible way would be to send the svg content to a server, and use something like batik for java to turn the svg to pdf and then send the response to the client again.

Here is a related SO for the converstion .

There's also wkhtml2pdf, which can render anything webkit can as a PDF. If you want to render a combination of SVG and HTML, or want to have some JavaScript run before the PDF snapshot is taken, it's great for that.

PhantomJS can also rasterize url/html to PDF. Same backend (QTWebKit) with wkhtml2pdf.

I did not try d3, but I achieved the effect you are looking for like this in Python3.6:

# Pdf library
from reportlab.pdfgen import canvas
from reportlab.graphics import renderPDF, renderPM

# Svg library
import svgwrite

# Svg to reportlab
from svglib.svglib import svg2rlg, SvgRenderer

# Xml parser
from lxml import etree

# Create the svg
dwg = svgwrite.Drawing('test.svg', profile='tiny')
dwg.add(dwg.line((0, 0), (10, 10), stroke=svgwrite.rgb(10, 10, 16, '%')))
dwg.add(dwg.text('Test', insert=(0, 0.2)))

# Create canvas for pdf
c = canvas.Canvas("output.pdf")

# Parse the xml of the svg
parser = etree.XMLParser(remove_comments=True, recover=True)
root = etree.fromstring(dwg.tostring())

# Render the svg itself
svgRenderer = SvgRenderer()
drawing = svgRenderer.render(root)

# Now render the drawing in the pdf
renderPDF.draw(drawing , c, 10, 10)

# End page and save pdf file
c.showPage()
c.save()

# Or render to a seperate png
renderPM.drawToFile(drawing, "file.png", fmt="PNG")

Reportlab is an open source pdf library and svglib is a library that is able to convert svg's to reportlab Drawings. Rendering svg's directly from the xml is not supported out of the box, that is why I use the SvgRenderer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM