Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge columns in reportlab table

I am trying to create a table with reportlab that can have values that need to be merged across all or certain columns.

This is my example, where I need the first row to be merged across all five columns. I tried with the ('SPAN', (0, 0), (-1, -1)) line, which is commented in this example, so that you can see how the table looks initially. If I uncomment that line, I only get the first row written to the pdf.

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
head = Paragraph('''<b>Table head</b>''', styleBH)
hID = Paragraph('''<b>ID</b>''', styleBH)
hcount = Paragraph('''<b>count</b>''', styleBH)
hcandidate = Paragraph('''<b>candidate</b>''', styleBH)
hprice = Paragraph('''<b>price</b>''', styleBH)
htotal_price = Paragraph('''<b>total price</b>''', styleBH)

# Texts
description = Paragraph('long paragraph', styleN)
ID = Paragraph('1', styleN)
count = Paragraph('120', styleN)
price = Paragraph('$52.00', styleN)
total_price = Paragraph('$6240.00', styleN)

data = [[head],
    [hID, hcount, hcandidate, hprice, htotal_price],
        [ID, description, description, price, total_price]]

table = Table(data, colWidths=[2.05 * cm, 2.7 * cm, 5 * cm,
                               3 * cm, 3 * cm])

table.setStyle(TableStyle([
    # ('SPAN', (0, 0), (-1, -1)),
    ('GRID', (0, 0), (-1, -1), 0.25, colors.grey),
    ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
    ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
]))

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

I surfed through questions here but I did not find any clear example on how to do this. Any help is appreciated!

like image 495
Litwos Avatar asked Aug 06 '18 13:08

Litwos


1 Answers

(0,0) refers to start cell at top extreme left and (-1,-1) refers to end cell at the bottom extreme right.
change your ('SPAN', (0, 0), (-1, -1)) to ('SPAN', (0, 0), (4, 0))

SPAN, (sc,sr), (ec,er) indicates that the cells in columns sc - ec and rows sr - er should be combined into a super cell with contents determined by the cell (sc, sr).

If I tried to explain in a mathematical way i.e matrix representation it would be merge matrix[0][0] and matrix[0][4].
I know, its little bit confusing.

like image 116
Vishal Singh Avatar answered Nov 04 '22 19:11

Vishal Singh