12

我正在尝试使用 Python 从 SVG 图像生成 PDF 图像。我已经尝试过CairoSVGsvglib。问题是在这两种情况下生成的 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>

使用 CairoSVG 呈现此 SVG 的 PDF 时,PDF 图像呈现为黑色矩形。使用 svglib,矩形没有应用任何描边或样式,因此它是不可见的。有没有人知道将带有 CSS 样式的 SVG 转换为Python 中的 PDF 图像的方法?

4

3 回答 3

11

(在@MonkeyWrench 的帮助下,因为他没有发布答案。)

根据文件

CairoSVG 可以使用 lxml 来解析 SVG 文件,并且可以使用 tinycss 加 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

果然,它是一个蓝色的矩形。

蓝色的

于 2013-07-28T20:41:03.243 回答
1

您是否尝试过使用 style 属性?

<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 中的样式元素。

于 2013-02-15T21:14:34.990 回答
1

我建议使用PhantomJS

基本上它是一个无头 WebKit,由 Javascript 驱动。

查看rasterize.js脚本。

您可以获取坐标并将该部分导出(栅格化)为图像。然后,您可以通过嵌入图像来使用基本上任何 PDF 生成器。或者,您可以使用另一个脚本通过 PhantomJS 生成 PDF 文件。

于 2013-07-23T20:02:58.427 回答