我有一个由d3生成的可视化(类似于Protovis或Raphael的javascript可视化库,它使用SVG元素绘制内容)。 vis是交互式的,因此用户可以与之交互并对其进行编辑。一旦用户对他/她的可视化感到满意,我希望用户能够将该可视化导出为PDF。我已经尝试了几个HTML到PDF库,它们不能与SVG元素一起使用。
如果解决方案是客户端或服务器端,那也没关系。我正在使用PHP服务器端,但Python或Java实现也可能有效。
浏览器支持:理想情况下它支持所有现代浏览器,但最低限度我想支持Firefox和webkit浏览器的最新版本。
我不知道客户端有任何强大的PDF库。
一种快速的方法是将svg内容发送到服务器,并使用类似batik for java的东西将svg转换为pdf,然后再将响应发送到客户端。
这是一个相关的 对于转换而言。
还有wkhtml2pdf,它可以渲染 任何webkit都可以 作为PDF。如果您想要渲染SVG和HTML的组合,或者想要在拍摄PDF快照之前运行一些JavaScript,那么它非常适合。
PhantomJS还可以将url / html光栅化为PDF。与wkhtml2pdf相同的后端(QTWebKit)。
我没有尝试过d3,但是我在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是一个开源的pdf库,svglib是一个能够将svg转换为reportlab Drawings的库。直接从xml渲染svg不支持开箱即用,这就是我使用SvgRenderer的原因。