How do I get multiple lines to print on one label in reportlab/tkinter/python? For example, the below prints "Hello" and "World" on two different labels(screenshot attached). I would like to be able to print "Hello" and "World" on the same label, along with additional items below them that would look something like this:
Hello World
Tomorrow
Wednesday
I have tried adding in the same line(sheet.add_label("Hello", "World") but get attached error. Any and all help, thoughts, comments appreciated. Sample working script below:
import labels
from reportlab.graphics import shapes
specs = labels.Specification(210, 297, 2, 8, 90, 25, corner_radius=2)
def draw_label(label, width, height, obj):
label.add(shapes.String(2, 2, str(obj), fontName="Helvetica", fontSize=40))
sheet = labels.Sheet(specs, draw_label, border=True)
sheet.add_label("Hello")
sheet.add_label("World")
sheet.save('basic.pdf')
print("{0:d} label(s) output on {1:d} page(s).".format(sheet.label_count, sheet.page_count))
It seems this problem exists as issue since 2017.
Long strings don't wrap to new line · Issue #15 · bcbnz/pylabels
But you can modify draw_label
to get list of lines and use two label.add()
with different position in String()
def draw_label(label, width, height, lines):
#print('lines:', lines)
label.add(shapes.String(2, 20, lines[0], fontName="Helvetica", fontSize=20))
label.add(shapes.String(2, 2, lines[1], fontName="Helvetica", fontSize=20))
sheet = labels.Sheet(specs, draw_label, border=True)
# [ text, text ]
sheet.add_label(["Hello","World"])
You could make it even more complex using list with other values (like x
, y
, fontName
, fontSize
, etc.)
def draw_label(label, width, height, lines):
for x, y, text in lines:
label.add(shapes.String(x, y, text, fontName="Helvetica", fontSize=20))
sheet = labels.Sheet(specs, draw_label, border=True)
# [ (x, y, text), (x, y, text), ... ]
sheet.add_label([ (2, 40, "Hello"), (2, 20, "World"), (2, 2, "Python") ])
Full working code
import labels
from reportlab.graphics import shapes
specs = labels.Specification(210, 297, 2, 8, 90, 25, corner_radius=2)
def draw_label(label, width, height, lines):
for x, y, text in lines:
label.add(shapes.String(x, y, text, fontName="Helvetica", fontSize=20))
sheet = labels.Sheet(specs, draw_label, border=True)
# [ (x, y, text), (x, y, text), ... ]
sheet.add_label([ (2, 40, "Hello"), (2, 20, "World"), (2, 2, "Python") ])
sheet.add_label([ (2, 40, "Other"), (2, 20, "Label") ])
sheet.save('basic.pdf')
print("{0:d} label(s) output on {1:d} page(s).".format(sheet.label_count, sheet.page_count))
EDIT:
You could create more complex code to add images
sheet.add_label([
('text', 2, 40, "Hello"),
('text', 2, 20, "World"),
('image', 2, 2, 50, 50, "/home/user/images/logo.png")
])
And it would need to use if/else
to check 'text'/'image'
and add different shape
.
Something like this
import labels
from reportlab.graphics import shapes
specs = labels.Specification(210, 297, 2, 8, 90, 25, corner_radius=2)
def draw_label(label, width, height, items):
for item in items:
if item[0] == 'text':
print('adding string', item)
_, x, y, text = item
label.add(shapes.String(x, y, text, fontName="Helvetica", fontSize=20))
elif item[0] == 'image':
print('adding image', item)
_, x, y, width, heigh, path = item
label.add(shapes.Image(x, y, width, heigh, path))
sheet = labels.Sheet(specs, draw_label, border=True)
# [ ('text', x, y, text), ('image', x, y, width, height, path), ... ]
sheet.add_label([ ('text', 2, 40, "Hello"), ('text', 2, 20, "World"), ('image', 100, 0, 90, 90 , "/home/furas/images/grass.jpg") ])
sheet.add_label([ ('text', 2, 40, "Other"), ('text', 2, 20, "Label") ])
sheet.save('basic.pdf')
print("{0:d} label(s) output on {1:d} page(s).".format(sheet.label_count, sheet.page_count))