Python Reportlab PDF - 页面中文本居中

16 投票
5 回答
32033 浏览
提问于 2025-04-16 04:23

我正在使用ReportLab这个工具,用Python动态生成PDF文件。

我想让一行文字在页面上居中显示。这里是我目前的代码,但我不知道怎么让文字水平居中。

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)

文字可以显示出来,我可以手动调整左边的位置,让文字看起来居中,但我需要这个居中是自动的,因为文字内容是动态的,我不知道会有多少文字。

5 个回答

4

你可以使用一个叫做 Paragraph 的对象,并把 alignment 的值设为 1:

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

这个例子会生成一个文本居中的PDF文档:

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

如果你想让文本靠左显示,你需要把 alignment 改成 0:

title_style.alignment = 0

如果你想让文本靠右显示,你需要把 alignment 改成 2:

title_style.alignment = 2
7

我也正好需要这个,于是写了这个:

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
18

ReportLab的画布上有一个叫做 drawCentredString 的方法。没错,他们就是这么拼写的。

我们是英国人,见鬼,我们为我们的拼写感到骄傲!

补充说明:关于文本对象,我很抱歉,你可能无法做到。不过,你可以尝试类似的做法:

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.

当然,你也可以使用其他页面大小。

撰写回答