Search code examples
pythonreportlab

Wrap text in a table reportlab?


I use a table but, I draw in in a canvas to control the position of the flowables, this because I have a template in a pdf, an I merge with pyPDF.

The wrap is done in a table but the text go up, not down that's what I hope.

c is the canvas

Code

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

width, height = A4
styles = getSampleStyleSheet()

def coord(x, y, unit=1):
    x, y = x * unit, height -  y * unit
    return x, y

descrpcion = Paragraph('long paragraph', styles["Normal"])
partida = Paragraph('1', styles["Center"])
candidad = Paragraph('120', styles["Center"])
precio_unitario = Paragraph('$52.00', styles["right"])
precio_total = Paragraph('$6240.00', styles["right"])

data= [[partida, candidad, descrpcion, precio_unitario, precio_total]]
table = Table(data, colWidths=[2.05 * cm, 2.7 * cm, 9.6 * cm,
                               2.65 * cm, 2.7 * cm])

c = canvas.Canvas(PDF, pagesize=A4)
table.wrapOn(c, width, height)
table.drawOn(c, *coord(1.8, 9.6, cm))
c.save()

Solution

  • The description text went up as you wrap it in a styles["Normal"] You can try to wrap your text in a styles["BodyText"] This will allow your text to align themselves according to the width of the cell you specify. You could also include formatting which is similar to HTML text formatting.

    Then use TableStyle to format the content in the table, for example, color text, center paragraph, span rows/columns and so on.

    I edited the code above to a working version (example):

    from reportlab.pdfgen import canvas
    from reportlab.lib.pagesizes import A4
    from reportlab.lib.units import cm
    from reportlab.lib.styles import getSampleStyleSheet
    from reportlab.platypus import Paragraph, Table, TableStyle
    from reportlab.lib.enums import TA_JUSTIFY, TA_LEFT, TA_CENTER
    from reportlab.lib import colors
    
    width, height = A4
    styles = getSampleStyleSheet()
    styleN = styles["BodyText"]
    styleN.alignment = TA_LEFT
    styleBH = styles["Normal"]
    styleBH.alignment = TA_CENTER
    
    def coord(x, y, unit=1):
        x, y = x * unit, height -  y * unit
        return x, y
    
    # Headers
    hdescrpcion = Paragraph('''<b>descrpcion</b>''', styleBH)
    hpartida = Paragraph('''<b>partida</b>''', styleBH)
    hcandidad = Paragraph('''<b>candidad</b>''', styleBH)
    hprecio_unitario = Paragraph('''<b>precio_unitario</b>''', styleBH)
    hprecio_total = Paragraph('''<b>precio_total</b>''', styleBH)
    
    # Texts
    descrpcion = Paragraph('long paragraph', styleN)
    partida = Paragraph('1', styleN)
    candidad = Paragraph('120', styleN)
    precio_unitario = Paragraph('$52.00', styleN)
    precio_total = Paragraph('$6240.00', styleN)
    
    data= [[hdescrpcion, hcandidad,hcandidad, hprecio_unitario, hprecio_total],
           [partida, candidad, descrpcion, precio_unitario, precio_total]]
    
    table = Table(data, colWidths=[2.05 * cm, 2.7 * cm, 5 * cm,
                                   3* cm, 3 * cm])
    
    table.setStyle(TableStyle([
                           ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
                           ('BOX', (0,0), (-1,-1), 0.25, colors.black),
                           ]))
    
    c = canvas.Canvas("a.pdf", pagesize=A4)
    table.wrapOn(c, width, height)
    table.drawOn(c, *coord(1.8, 9.6, cm))
    c.save()