开发者

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()


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()


AutoReply:

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

w, h = table.wrap(width, height)
table.wrapOn(c, width, height)
table.drawOn(c, *coord(ml - 0.05, y + 4.6, height - h, cm))

the trick is in the "height - h", h is the height of the table and this depend of the content of the table


I know that Postscript's reference is the lower, left corner. I'm guessing that PDF is the same, so you subtract from the y value to go down. Print the beginning and ending "y" values in the function to see how they are changing and adjust the "y" value depending on the length of the sentence. And how does the function know what "height" is? I use ReportLab but could probably help with a specific example if you care to post one.


Even though this is an old question, it's still relevant for those who don't want to use a document template.

As mentioned, you can use 'VALIGN' to wrap text within the cells, but there is another hack if you want to further control the table elements on the canvas.

Before:

Wrap text in a table reportlab?

table=Table(data, style=[
        ('INNERGRID', (0,0), (-1,-1), 0.25, black),
        ('BOX', (0,0), (-1,-1), 0.25, black),
        ('VALIGN',(0,0),(-1, -1),'TOP'),
        ])

table.wrapOn(self.c, (inch*8)-50, self.height)   
table.drawOn(self.c, *self.coord(x=1, y=20, unit=cm))

Now adding two components:

  1. rowHeights attribute
  2. _argH for finer editing of the row heights

After:

Wrap text in a table reportlab?

from reportlab.lib.units import mm, cm, inch

 table=Table(data, rowHeights = 8*mm, style=[
        ('INNERGRID', (0,0), (-1,-1), 0.25, black),
        ('BOX', (0,0), (-1,-1), 0.25, black),
        ('VALIGN',(0,0),(-1, -1),'TOP'),
        ])

    table._argH[0] = 1*cm + 4   
    table._argH[1] = 1*cm + 4   
    table._argH[2] = 1*cm + 4   
    table._argH[3] = 1*cm + 4   
    table._argH[4] = 1*cm + 4   

table.wrapOn(self.c, (inch*8)-50, self.height)   
table.drawOn(self.c, *self.coord(x=1, y=20, unit=cm))

In this case my maximum cell values = 5 which is denoted as 0 - 4 cells.

You can find the number of cell values used in the table like so:

print(len(table.cellvalues))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜