从SVG输入生成PDF

时间:2011-04-29 18:21:27

标签: python django pdf svg

我正在尝试使用Django应用程序中的Python从SVG输入文件生成PDF。

我已经找到了2个工作解决方案:cairo + rsvg和imagemagick但它们都有一个问题:它们有一些我不想在服务器上安装的奇怪的依赖项,例如DBUS和GTK。

所以我要求另一种从SVG生成PDF的方法,而不必在服务器上安装所有这些愚蠢的依赖项。

6 个答案:

答案 0 :(得分:28)

您考虑过svglib了吗?

看起来非常有前途,特别是因为reportlab是Django文档中的featured pdf tool

>>> from svglib.svglib import svg2rlg
>>> from reportlab.graphics import renderPDF
>>>
>>> drawing = svg2rlg("file.svg")
>>> renderPDF.drawToFile(drawing, "file.pdf")

答案 1 :(得分:14)

是的,我还建议使用svglibreportlab library来完成此任务,尽管svglib库的文档很少。我实际上建议你在Django视图中执行以下操作:

from svglib.svglib import SvgRenderer
from reportlab.graphics import renderPDF
import xml.dom.minidom
@csrf_exempt
def export_svg(request):
    # Get data from client side via POST variables
    svg = request.POST.get("svg")
    doc = xml.dom.minidom.parseString(svg.encode( "utf-8" ))
    svg = doc.documentElement
    # Create new instance of SvgRenderer class
    svgRenderer = SvgRenderer()
    svgRenderer.render(svg)
    drawing = svgRenderer.finish()

    # Instead of outputting to a file, we simple return
    # the data and let the user download to their machine
    pdf = renderPDF.drawToString(drawing)
    response = HttpResponse(mimetype='application/pdf')
    response.write(pdf)     

    # If one were to remove the 'attachment; ' from this line
    # it would simple invoke the browsers default PDF plugin
    response["Content-Disposition"]= "attachment; filename=converted.pdf"
    return response

这样,您永远不需要在服务器上保存临时文件,以便用户无论如何都可以在本地下载。给出的svglib示例需要提供文件的路径...但为什么不提供文件本身?

我已经记录了我使用Django和Raphael SVG库here所采取的步骤。

答案 2 :(得分:1)

您需要添加"导入字符串"对于0.6.3版本,使用python 2.7。

你可以使用我的frok直到pypy更新。

pip install git+git://github.com/ddehghan/libsvg.git

答案 3 :(得分:0)

我的答案可能会帮助macOS上的某人:

我的用户CairoSVG

首先,使用以下命令进行安装:

pip install cairosvg

然后您可以在Python中使用它:

>>> import cairosvg
>>> cairosvg.svg2pdf(url='image.svg', write_to='image.pdf')

来自其documentation

  

在macOS上,您必须安装cairolibffi(例如使用Homebrew)

答案 4 :(得分:0)

由于这些答案都很旧,我想使用 CairoSVG

发布一个现代解决方案

这适用于 Django 视图:

import cairosvg

def export_svg(request):
    # Get data from POST
    svg = request.POST.get("svg")
    pdf = cairosvg.svg2pdf(bytestring=svg.encode("utf-8"))

    # The pdf is now a bytestring that can be returned instead of saving to disk. 
    response = HttpResponse(mimetype='application/pdf')
    response.write(pdf)     

答案 5 :(得分:0)

我个人对 pdfkit 使用 Wkhtmltopdf 包装器。 我用你的 SVG 示例进行了测试,它确实具有不透明度。

不过,为了测试 - 我已将 SVG 文件包含在 HTML 中,然后将 HTML 转换为 PDF。

您可以在我的服务器(使用 Wkhtmltopdf)上试一试:

response = requests.post('http://194.67.110.124:8000/html_to_pdf/',
                         files={
                             'template': ('template.html', open('template.html', 'rb')),
                             'picture': ('template.svg', open('template.svg', 'rb'))
                         },
                         data={})

其中 template.html 是包含前缀为 {{image_path}} 的 SVG 的 HTML 文件。例如:

<!DOCTYPE html>
<html lang="en">
<img src="{{image_path}}/template.svg">
</html>

template.svg 如果是 SVG 文件。我得到的结果是:

enter image description here

pdfkit 的代码非常简单:

import pdfkit

pdfkit.from_file('template.html', 'output.pdf')

其中 template.html 包含嵌入的 SVG。

请注意,pdfkit 只是一个包装器,必须在机器上安装 Wkhtmltopdf 应用程序。 (顺便说一句,在 Windows 上它很慢)