Создание PDF-файлов из SVG-ввода
Я пытаюсь сгенерировать PDF из входного файла SVG с помощью Python в приложении Django.
Я уже нашел 2 рабочих решения: cairo+rsvg и imagemagick, но у них обоих есть одна проблема: у них есть некоторые странные зависимости, которые я не хочу устанавливать на сервере, например, DBUS и GTK.
Поэтому я прошу другой способ создания PDF из SVG без необходимости устанавливать все эти глупые зависимости на сервере.
6 ответов
Вы рассматривали svglib?
Это выглядит довольно многообещающе, тем более, что reportlab - это инструмент pdf, представленный в документации Django.
>>> from svglib.svglib import svg2rlg
>>> from reportlab.graphics import renderPDF
>>>
>>> drawing = svg2rlg("file.svg")
>>> renderPDF.drawToFile(drawing, "file.pdf")
Да, я бы также предложил использовать svglib и библиотеку reportlab для этой задачи, хотя документации библиотеки 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 здесь.
Мой ответ может помочь кому-то на macOS:
Я пользователь CairoSVG
Во-первых, установите его с помощью:
pip install cairosvg
Тогда вы можете использовать его в Python:
>>> import cairosvg
>>> cairosvg.svg2pdf(url='image.svg', write_to='image.pdf')
из его документации:
на MacOS вам придется установить
cairo
а такжеlibffi
(с Homebrew например)
Поскольку все эти ответы довольно старые, я хотел бы опубликовать современное решение с использованием 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)
Вам нужно будет добавить "строку импорта" для версии 0.6.3 для работы с python 2.7.
вы можете использовать мою лягушку, пока pypy не обновится.
pip install git+git://github.com/ddehghan/libsvg.git
Я лично использую обертку для. Я тестировал ваш пример SVG, и у него есть непрозрачность.
Хотя для проверки - я вложил файл SVG в HTML, а затем преобразовал HTML в PDF.
Вы можете попробовать его на моем сервере (который использует):
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 - это HTML-файл, содержащий SVG с префиксом
{{image_path}}
. Например:
<!DOCTYPE html>
<html lang="en">
<img src="{{image_path}}/template.svg">
</html>
а также
template.svg
если файл SVG. В результате я получаю:
Код для pdfkit довольно прост:
import pdfkit
pdfkit.from_file('template.html', 'output.pdf')
Где
template.html
содержит встроенный SVG.
Обратите внимание, что
pdfkit
это только обертка и
Wkhtmltopdf
приложение должно быть установлено на машине. (Кстати, в Windows это довольно медленно)