在Python中将带有嵌入式CSS的SVG转换为PDF

在Python中将带有嵌入式CSS的SVG转换为PDF,python,svg,pdf-generation,Python,Svg,Pdf Generation,我正在尝试使用Python从SVG图像生成PDF图像。我试过两种方法。问题是,在这两种情况下,生成的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"&

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

您尝试过使用样式属性吗

<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> 

我建议使用

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

看看剧本

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

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

据报道,

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和svglib都能正确呈现此标记。但是,我尝试将SVG图像转换为在网页上呈现的图像。将样式属性应用于每个单独的元素是不实际的。尽管这对我的情况不起作用,但这是有用的信息。谢谢!我必须为D3可视化制作缩略图,到目前为止,我想到的最好的方法是使用phantomjs来渲染SVG的有点复杂的设置。由于phantomjs是一个真正的webkit浏览器,SVG的呈现方式与浏览器版本完全相同(有一个phantompy模块,但它在我的环境中出现故障,我没有时间调查原因)。CairoSVG文档有这样一个注释:CairoSVG可以使用lxml解析SVG文件,和tinycss+CSS选择以应用标记的样式属性中未包含的CSS。如果这些包不可用,CSS将仅在样式属性中受支持。如果您安装tinycss和cssselect软件包,它可能会解决您的问题。请参阅此处的依赖项部分:@monkey扳手:这是迄今为止最好的提示,如果您愿意,您可以给出答案并收集赏金。
rasterize.js
可以生成PDF,无需外部生成器。有示例,提供了积分,所有内容都会检查。干得好,收你的赏金。:-)很高兴它成功了。我已经离开一段时间了。更好地关注未来。只是为了更好地理解解决方案——与使用PhantomJS相比,这种方法有什么好处?
$ cairosvg image.svg -o image.pdf