12

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.

Oli
  • 235,628
  • 64
  • 220
  • 299
  • Could you use a combo of the following approaches http://stackoverflow.com/a/6599172/1104941 and http://www.blog.pythonlibrary.org/2012/01/07/reportlab-converting-hundreds-of-images-into-pdfs/ The latter uses reportlab but I'm wondering if you can get away without the Plus version given you're just generating pdfs. You may be able to go straight to pdf with Cairo but I can't say for sure hence the comment instead of an answer. – sgallen Jan 13 '12 at 17:06

4 Answers4

9

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.

ram1
  • 6,290
  • 8
  • 41
  • 46
  • Does inkscape handle fonts well? Are fonts that are installed on a windows environment recognized in inkscape? – Shmack Mar 01 '21 at 23:30
  • @ShanerM13 Inkscape does handle fonts well. I haven't used Inkscape on Windows but the answer to your second question appears to be [yes, if done correctly](https://wiki.inkscape.org/wiki/index.php/Installing_fonts). – ram1 Mar 04 '21 at 19:43
3

CairoSVG is the one I am using:

import cairosvg
cairosvg.svg2pdf(url='image.svg', write_to='image.pdf')
plaes
  • 31,788
  • 11
  • 91
  • 89
  • Tested it now, but unfortunately it's just as feeble at rendering my SVGs. – Oli Jan 15 '12 at 00:36
  • Are you sure that your SVG's are actually formatted correctly? Cairo's rendering is quite solid.. Also, I'm using WeasyPrint for PDF's, though it's still a bit incomplete, but works fine despite limitations... – plaes Jan 15 '12 at 07:33
1

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.

Patrick Maupin
  • 8,024
  • 2
  • 23
  • 42
  • How does this address the OP's problem? I believe he doesn't *want* to use reportlab because it's SVG handling quality is lacking. – Martijn Pieters Oct 06 '12 at 08:25
0

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.

Al3x_M
  • 214
  • 3
  • 3