关于python:将SVG转换为PDF(svglib + reportlab不够好)

Convert SVG to PDF (svglib + reportlab not good enough)

我正在批量创建一些SVG,需要将它们转换为PDF文档以进行打印。 我一直在尝试使用svglib及其svg2rlg方法,但是我发现在保存文档中的矢量图形方面确实令人震惊。 它几乎不能正确定位文本。

我动态生成的SVG格式正确,并且已经在原始输入上测试了svglib,以确保这不是我要介绍的问题。

那么,svglib和ReportLab之后我有哪些选择? 它要么免费,要么非常便宜,因为我们已经超出了这个项目的预算。 我们无法负担ReportLab Plus每年1k的费用。

我正在使用Python,但是在此阶段,只要它在我们的Ubuntu服务器上运行,我都会很高兴。

编辑:测试王子。 更好,但是它仍然忽略了一半文档。


我为此使用inkscape。在您的django视图中执行以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from subprocess import Popen

x = Popen(['/usr/bin/inkscape', your_svg_input, \\
    '--export-pdf=%s' % your_pdf_output])
try:
    waitForResponse(x)
except OSError, e:
    return False

def waitForResponse(x):
    out, err = x.communicate()
    if x.returncode < 0:
        r ="Popen returncode:" + str(x.returncode)
        raise OSError(r)

您可能需要作为参数传递,以绘制.svg中引用的所有字体文件,因此请注意,如果文本未正确显示在.pdf输出中。


CairoSVG是我正在使用的一种:

1
2
import cairosvg
cairosvg.svg2pdf(url='image.svg', write_to='image.pdf')


rst2pdf使用reportlab生成PDF。它可以使用inkscape和pdfrw读取PDF。

pdfrw本身有一些示例,这些示例显示读取PDF并使用reportlab输出。

在下面解决Martin的评论(我可以编辑此答案,但没有信誉对其发表评论...):

reportlab对SVG文件一无所知。某些工具(例如svg2rlg)试图通过将它们绘制到reportlab画布中来将SVG图像重新创建为PDF。但是,您可以使用pdfrw进行另一种方式-如果您可以使用其他工具将SVG文件转换为PDF图像,则pdfrw可以获取转换后的PDF,并将其作为XObject形式添加到您生成的PDF中与reportlab。就reportlab而言,它实际上与放置JPEG图像没有什么不同。

某些工具会对SVG文件产生可怕的后果(例如,光栅化它们)。以我的经验,inkscape通常做得很好,并将其保留为矢量格式。您甚至可以无头这样做,例如" inkscape my.svg -A my.pdf"。

我首先编写pdfrw的全部原因是为了这个确切的用例-能够在reportlab创建的新PDF中重用矢量图像。


只是为了让您知道并针对未来的问题,我找到了解决该问题的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# I only install svg2rlg, not svglib (svg2rlg is inside svglib as well)
import svg2rlg

# Import of the canvas
from reportlab.pdfgen import canvas

# Import of the renderer (image part)
from reportlab.graphics import renderPDF

rlg = svg2rlg.svg2rlg("your_img.svg")
c = canvas.Canvas("example.pdf")
c.setTitle("my_title_we_dont_care")

# Generation of the first page
# You have a last option on this function,
# about the boundary but you can leave it as default.
renderPDF.draw(rlg, c, 80, 740 - rlg.height)
renderPDF.draw(rlg, c, 60, 540 - rlg.height)
c.showPage()

# Generation of the second page
renderPDF.draw(rlg, c, 50, 740 - rlg.height)
c.showPage()

# Save
c.save()

享受一下位置(80,740-h),这只是位置。

如果代码不起作用,则可以在渲染器的reportlab库中查看。
您在reportlab中具有一个功能,可以从图像直接创建pdf:

1
renderPDF.drawToFile(rlg,"example.pdf","title")

您可以打开它并阅读。这不是很复杂。此代码来自此功能。


使用svglib或cairosvg时,无法正确呈现svg中的文本。
我的解决方案是将svg文件导入draw.io,然后将其导出为pdf。