将 SVG 转换为 PDF(svglib + reportlab 不够好)

发布于 2024-12-27 01:09:43 字数 390 浏览 2 评论 0原文

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

我的动态生成的 SVG 格式良好,并且我在原始输入上测试了 svglib,以确保这不是我引入的问题。

那么除了 svglib 和 ReportLab 之外我还有哪些选择呢?它要么必须是免费的,要么非常便宜,因为我们已经超出了该项目的预算。我们无法承担 ReportLab Plus 每年 1000 美元的费用。

我正在使用 Python,但在现阶段,只要它能在我们的 Ubuntu 服务器上运行,我就很高兴。

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

I'm creating some SVGs in batches and need to convert those to a PDF document for printing. I've been trying to use svglib and its svg2rlg method but I've just discovered that it's absolutely appalling at preserving the vector graphics in my document. It can barely position text correctly.

My dynamically-generated SVG is well formed and I've tested svglib on the raw input to make sure it's not a problem I'm introducing.

So what are my options past svglib and ReportLab? It either has to be free or very cheap as we're already out of budget on the project this is part of. We can't afford the 1k/year fee for ReportLab Plus.

I'm using Python but at this stage, I'm happy as long as it runs on our Ubuntu server.

Edit: Tested Prince. Better but it's still ignoring half the document.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

何必那么矫情 2025-01-03 01:09:43

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

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 中引用的所有字体文件作为参数传递给 inkscape,因此,如果您的文本在 .pdf 输出中未正确显示,请记住这一点。

I use inkscape for this. In your django view do like:

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)

You may need to pass as parameters to inkscape all the font files you refer to in your .svg, so keep that in mind if your text does not appear correctly on the .pdf output.

不弃不离 2025-01-03 01:09:43

CairoSVG 是我正在使用的:

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

CairoSVG is the one I am using:

import cairosvg
cairosvg.svg2pdf(url='image.svg', write_to='image.pdf')
音盲 2025-01-03 01:09:43

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

pdfrw 本身有一些示例显示阅读 PDF 并使用 reportlab 进行输出。

解决下面 Martin 的评论(我可以编辑这个答案,但没有声誉来评论它的评论......):

reportlab 对 SVG 文件一无所知。某些工具(例如 svg2rlg)尝试通过将 SVG 图像绘制到 reportlab 画布中来将其重新创建为 PDF。但是您可以使用 pdfrw 以不同的方式执行此操作 - 如果您可以使用其他工具将 SVG 文件转换为 PDF 图像,那么 pdfrw 可以获取转换后的 PDF,并将其作为表单 XObject 添加到您正在生成的 PDF 中与报告实验室。就reportlab而言,这实际上与放置JPEG图像没有什么不同。

有些工具会对您的 SVG 文件执行可怕的操作(例如,对其进行光栅化)。根据我的经验,inkscape 通常做得很好,并将它们保留为矢量格式。您甚至可以无头执行此操作,例如“inkscape my.svg -A my.pdf”。

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

rst2pdf uses reportlab for generating PDFs. It can use inkscape and pdfrw for reading PDFs.

pdfrw itself has some examples that show reading PDFs and using reportlab to output.

Addressing the comment by Martin below (I can edit this answer, but do not have the reputation to comment on a comment on it...):

reportlab knows nothing about SVG files. Some tools, like svg2rlg, attempt to recreate an SVG image into a PDF by drawing them into the reportlab canvas. But you can do this a different way with pdfrw -- if you can use another tool to convert the SVG file into a PDF image, then pdfrw can take that converted PDF, and add it as a form XObject into the PDF that you are generating with reportlab. As far as reportlab is concerned, it is really no different than placing a JPEG image.

Some tools will do terrible things to your SVG files (rasterizing them, for example). In my experience, inkscape usually does a pretty good job, and leaves them in a vector format. You can even do this headless, e.g. "inkscape my.svg -A my.pdf".

The entire reason I wrote pdfrw in the first place was for this exact use-case -- being able to reuse vector images in new PDFs created by reportlab.

江城子 2025-01-03 01:09:43

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

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

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

您可以打开它并阅读它。这并不是很复杂。这段代码来自这个函数。

Just to let you know and for the future issue, I find a solution for this problem:

# 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()

Enjoy a bit with the position (80, 740 - h), it is only the position.

If the code doesn't work, you can look at in the render's reportlab library.
You have a function in reportlab to create directly a pdf from your image:

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

You can open it and read it. It is not very complicated. This code come from this function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文