Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Reportlab PDF - Centering Text on page

I am using ReportLab to generate a pdf dynamically with python.

I would like a line of text to be centered on a page. Here is the specific code I currently have, but do not know how to center the text horizontally.

header = p.beginText(190, 740)
header.textOut("Title of Page Here")

# I know i can use TextLine etc in place of textOut

p.drawText(header)

The text displays and I can manually move the left position so the text looks centered, but I need this to be centered programmatically since the text will be dynamic and I don't know how much text there will be.

like image 852
jhanifen Avatar asked Sep 20 '10 21:09

jhanifen


3 Answers

You can use Flowable object like Paragraph and assign alignment value to 1:

styles = getSampleStyleSheet()
title_style = styles['Heading1']
title_style.alignment = 1
title = Paragraph("Hello Reportlab", title_style)
story.append(title)

This example will create a pdf document with centered text:

from flask import make_response
import io
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.lib.styles import getSampleStyleSheet

story=[]
pdf_doc = io.BytesIO()
doc = SimpleDocTemplate(pdf_doc)

styles = getSampleStyleSheet()
title_style = styles['Heading1']
title_style.alignment = 1
title = Paragraph("Hello Reportlab", title_style)
story.append(title)
doc.build(story)

content = pdf_doc.getvalue()

#output to browser
response = make_response(content)
response.mimetype = 'application/pdf'
return response

If you want the text to be floaten to the left, you need to change alignment to 0:

title_style.alignment = 0

If you want the text to be floaten to the right, you need to change alignment to 2:

title_style.alignment = 2
like image 135
ASSILI Taher Avatar answered Sep 18 '22 13:09

ASSILI Taher


The reportlab canvas has a drawCentredString method. And yes, they spell it like that.

We’re British, dammit, and proud of our spelling!

Edit: As for text objects, I'm afraid you don't. You can do something along those lines, though:

from reportlab.pdfbase.pdfmetrics import stringWidth
from reportlab.rl_config import defaultPageSize

PAGE_WIDTH  = defaultPageSize[0]
PAGE_HEIGHT = defaultPageSize[1]

text = "foobar foobar foobar"
text_width = stringWidth(text)
y = 1050 # wherever you want your text to appear
pdf_text_object = canvas.beginText((PAGE_WIDTH - text_width) / 2.0, y)
pdf_text_object.textOut(text) # or: pdf_text_object.textLine(text) etc.

You can use other page sizes, obviously.

like image 18
Jim Brissom Avatar answered Nov 03 '22 03:11

Jim Brissom


I just needed this too, and wrote this:

def createTextObject(canv, x, y, text, style, centered=False):
    font = (style.fontName, style.fontSize, style.leading)
    lines = text.split("\n")
    offsets = []
    if centered:
        maxwidth = 0
        for line in lines:
            offsets.append(canv.stringWidth(line, *font[:2]))
        maxwidth = max(*offsets)
        offsets = [(maxwidth - i)/2 for i in offsets]
    else:
        offsets = [0] * len(lines)
    tx = canv.beginText(x, y)
    tx.setFont(*font)
    for offset, line in zip(offsets, lines):
        tx.setXPos(offset)
        tx.textLine(line)
        tx.setXPos(-offset)
    return tx
like image 7
EB. Avatar answered Nov 03 '22 01:11

EB.