Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to position a python Reportlab table at position 10,100 and use drawString

I am a python hobbyist and reportlab newbie.
I know how to use drawString to put text at a particular place on a page, e.g.: c.drawString(10,100,"Welcome to Reportlab!")

But I can't figure out how to place a table (which will only be a few lines long) so that the table begins at the same position as the c.drawString(10,100,"Welcome to Reportlab!"), which I will place elsewhere if I learn how to put my table there instead.

I also can't figure out how to use drawString in the same script, since using a canvas is the only way I know how to use the drawString functioning. My 4 lines of canvas code (following this paragraph) would close the canvas/file and create the PDF. The table code (further below) also closes the file and builds the PDF, and I don't see how to use the "doc.build(elements)" line to close the canvas which I use for drawString operations.

c = canvas.Canvas(r"e:\hellonu.pdf", pagesize=letter)
c.setFont("Courier", 9) #choose your font type and font size
c.drawString(10,60,"Welcome to Reportlab!")
c.save()

I would appreciate any guidance you could give me (1) about how to place the table so that it begins at 10,100, and (2) how to use drawString in the same script. If some of my code does nothing useful, please don't assume I put it there intentionally; I tried to copy enough from examples, so that my table would have wordwrap functioning.

Here's the code I have been playing with:

# http://zewaren.net/site/node/139
from reportlab.lib import colors
from reportlab.lib.pagesizes import LETTER, inch, portrait
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph
from reportlab.lib.styles import getSampleStyleSheet


doc = SimpleDocTemplate(r"e:\test_report_lab.pdf", pagesize=LETTER, rightMargin=30,leftMargin=30, topMargin=30,bottomMargin=18)
doc.pagesize = portrait(LETTER)
elements = []


data = [
["Directory"],
["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "],
]


style = TableStyle([('ALIGN',(1,1),(-2,-2),'RIGHT'),
                       ('TEXTCOLOR',(1,1),(-2,-2),colors.red),
                       ('VALIGN',(0,0),(0,-1),'TOP'),
                       ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
                       ('BOX', (0,0), (-1,-1), 0.25, colors.black),
                       ])

#Configure style and word wrap
s = getSampleStyleSheet()
s = s["BodyText"]
s.wordWrap = 'CJK'
data2 = [[Paragraph(cell, s) for cell in row] for row in data]
t=Table(data2)
t.setStyle(style)


#Send the data and build the file
elements.append(t)
doc.build(elements)
like image 895
Marc B. Hankin Avatar asked Dec 23 '22 21:12

Marc B. Hankin


1 Answers

Lately, I stumbled across the same issue. The problem here is that in reportlab, tables are so-called "flowables" whereas the drawString command is "fixed".

I found a solution thanks to this great tutorial written by Mike Driscoll: "Reportlab: Mixing Fixed Content and Flowables".

Here is a slighty adapted version which constitutes a working snippet:

from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import mm
from reportlab.pdfgen import canvas
from reportlab.platypus import Image, Paragraph, Table
from reportlab.lib import colors

c = canvas.Canvas('example.pdf', pagesize=A4)  # alternatively use bottomup=False
width, height = A4

data = [[1, 2, 3], [2, 1, 3], [3, 2, 1]]

table = Table(data, colWidths=10*mm)
table.setStyle([("VALIGN", (0,0), (-1,-1), "MIDDLE"),
                ("ALIGN", (0,0), (-1,-1), "CENTER"),
                ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black)])

table.wrapOn(c, width, height)
table.drawOn(c, 0*mm, 5*mm)

styles = getSampleStyleSheet()    
ptext = "This is an example."
p = Paragraph(ptext, style=styles["Normal"])
p.wrapOn(c, 50*mm, 50*mm)  # size of 'textbox' for linebreaks etc.
p.drawOn(c, 0*mm, 0*mm)    # position of text / where to draw

c.save()

I can also recommend two more tutorials by Mike Driscoll, which have allowed me to get quickly familiar with reportlab.

  • A Simple Step-by-Step Reportlab Tutorial
  • Reportlab Tables – Creating Tables in PDFs with Python

Thanks a lot, Mike!

like image 113
nostradamus Avatar answered Dec 28 '22 07:12

nostradamus