i try to align a watermark in a pdf so it is exactly in the middle at the bottom with the following code:
from reportlab.pdfgen import canvas
from reportlab.lib.units import inch
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase.pdfmetrics import stringWidth
# text = "test test test"
text = "Peter Schmidt, Musterstraße 1, 50767 Köln"
pdf = canvas.Canvas("watermark.pdf", pagesize=A4)
pdf.translate(inch, inch)
pdf.setFillColor(colors.grey, alpha=0.6)
pdf.setFont("Helvetica", 15)
widthText = stringWidth(text, "Helvetica", 15) / 2
widthPage = pdf._pagesize[0]
x = (widthPage / 2) - (widthText / 2)
pdf.drawCentredString(x, -45, text)
pdf.save()
Generally it seems to work fine and when i use the text
text = "Peter Schmidt, Musterstraße 1, 50767 Köln"
it centers fine
but when i try it with a shorter text like
text = "test test test"
its not working anymore and the text is far to right
How can i solve this that the text is allways in the middle of the pdf?
The issue here is that the horizontal Zero Position is not at the very left of the page but shifted right for some amount that serves as the left margin of the page. You need to find out, how big that margin is in order to calculate the correct position. If you are using a document template, that margin is defined somewhere in that template. I have not jet found a way to get the margin size programmatically without a template. But Using your code on my system appears to result in a left margin of 70.
With that information, the following code yields the desired result:
from reportlab.pdfgen import canvas
from reportlab.lib.units import inch
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase.pdfmetrics import stringWidth
text = "test test test"
#text = "Peter Schmidt, Musterstraße 1, 50767 Köln"
#text = "1"
pdf = canvas.Canvas("watermark.pdf", pagesize=A4)
pdf.translate(inch, inch)
pdf.setFillColor(colors.grey, alpha=0.6)
pdf.setFont("Helvetica", 15)
widthPage = pdf._pagesize[0]
leftMargin = 70 # acquired experimentally
# option 1 using drawCentredString()
x = (widthPage / 2) - leftMargin
pdf.drawCentredString(x, 0, text)
# option 2 using drawString()
widthText = stringWidth(text, "Helvetica", 15)
x2 = (widthPage / 2) - (widthText / 2) - leftMargin
pdf.drawString(x2, -45, text)
pdf.save()
The fact that you code worked for the long string was pure luck.
Note that the option using the drawCentredString()
method does not need the width of the test at all.
The option using the drawString()
method does need the width of the string. Note that the /2
is removed from the calculation of widthText
to yield the correct width.