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:
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:
- rowHeights attribute
- _argH for finer editing of the row heights
After:
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))
精彩评论