Преобразование SVG с встроенным CSS в PDF в Python

Я пытаюсь создать PDF-образ из SVG-изображения с помощью Python. Я пробовал как CairoSVG, так и svglib. Проблема в том, что в обоих случаях сгенерированные PDF файлы не имеют каких-либо внедренных стилей CSS.

Вот простой SVG файл, который должен отображать синий прямоугольник с черной рамкой:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="200" height="200" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <style type="text/css"><![CDATA[
      rect {
        fill: #1f77b4;
        stroke: black;
        stroke-width: 1;
        shape-rendering: crispEdges;
      }
    ]]></style>
  </defs>
  <rect x="50" y="50" width="100" height="100"></rect>
</svg>

При рендеринге PDF этого SVG с использованием CairoSVG изображение в формате PDF отображается как черный прямоугольник. Используя svglib, для прямоугольника не применяется штрих или стиль, чтобы он не был виден. Кто-нибудь знает, как преобразовать SVG с стилями CSS в PDF-образ в Python?

Ответ 1

(С помощью @MonkeyWrench, так как он не отправил ответ.)

В соответствии с documentation,

CairoSVG может использовать lxml для анализа SVG файла, а tinycss plus cssselect - применять CSS, не включенный в атрибут стиля тегов. Если эти пакеты недоступны, CSS будет поддерживаться только в атрибутах стиля.

Чтобы начать работу, я установил все зависимости,

$ pip3 install cairosvg lxml tinycss cssselect

Затем я создал image.svg со следующим содержимым:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="200" height="200" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <style type="text/css"><![CDATA[
      rect {
        fill: #1f77b4;
        stroke: black;
        stroke-width: 1;
        shape-rendering: crispEdges;
      }
    ]]></style>
  </defs>
  <rect x="50" y="50" width="100" height="100"></rect>
</svg>

Наконец, я выполнил cairosvg

$ cairosvg image.svg -o image.pdf

И, конечно же, это был синий прямоугольник.

blue

Ответ 2

Попробовали ли вы использовать атрибут стиля?

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <rect x="50" y="20" width="100" height="100"
  style="fill:#1f77b4;stroke:black;stroke-width:1;shape-rendering: crispEdges;"
  stroke-opacity:0.9"/>
</svg> 

Это в конечном счете то же, что и вы, но, возможно, CairoSVG пропускает элементы стиля в вашем HTML.

Ответ 3

Я бы предложил использовать PhantomJS.

В основном это безголовый WebKit, управляемый Javascript.

Посмотрите rasterize.js script.

Вы можете захватить координаты и экспортировать (растеризовать) этот раздел в качестве изображения. Затем вы можете использовать в основном любой генератор PDF, вставив изображение. Кроме того, вы можете использовать другой script для создания PDF файла с помощью PhantomJS.