在Python中将嵌入CSS的SVG转换为PDF
我正在尝试用Python把SVG图片转换成PDF格式的图片。我试过了两个工具,一个是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>
但是用CairoSVG生成这个SVG的PDF时,结果只显示了一个黑色的矩形。而用svglib时,矩形没有任何边框或样式,所以根本看不见。有没有人知道怎么在Python中把带有CSS样式的SVG转换成PDF图片呢?
3 个回答
1
我建议你使用 PhantomJS。
简单来说,它是一个无头的WebKit,主要通过JavaScript来驱动。
你可以看看 rasterize.js 这个脚本。
你可以获取某个区域的坐标,然后把这个部分导出(栅格化)成一张图片。接着,你可以使用任何PDF生成器,把这张图片嵌入进去。或者,你也可以用另一个脚本,通过PhantomJS直接生成PDF文件。
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时跳过了style元素。
12
(感谢@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
果然,得到了一个蓝色的矩形。