I am generating a PDF using ReportLab. The PDF consists of a massive table with around 10,000 rows and 10 columns. Each column has varying strings of lengths, and 50-60% of the time the strings are longer than the row length meaning word wrapping is necessary. As far as I could tell there are 2 ways to accomplish this -- Set the strings to use the normal style sheet in getSampleStyleSheet ->
styleSheet = getSampleStyleSheet()
style = styleSheet['Normal']
data = [[Paragraph(cell, style) for cell in row] for row in batch]
Or by using WrapOn on the table flowable (Section 5.3 in the user guide) ->
reportTable = Table(data, colWidths=columnWidths, hAlign='LEFT', repeatRows=1)
reportTable.setStyle(tblstyle)
reportTable.wrap(50, 50) #these are 2 random ints that are both smaller than the cells.
When I use getSampleStyleSheet, word wrapping does work for each cell which is great. The problem then becomes the style sheet text settings overrides whatever is set in my table style.
So it all boils down to -> Can getSampleStyleSheet be used for word wrapping and TableStyle be used for text color, size, align, etc? If not, how can I get TableStyle to wrap text as the columns have varying widths?
I've tried variations of
- Wrap text in a table reportlab?
- https://www.folkstalk.com/2022/09/reportlab-table-wrap-text-with-code-examples.html
- wrap text is not working with reportlab SimpleDocTemplate
- https://www.programcreek.com/python/example/58583/reportlab.lib.styles.getSampleStyleSheet
Full Code of the PDF builder function:
def reportLabPdf(outfile, batch, columnWidths, rowHeights):
styleSheet = getSampleStyleSheet()
style = styleSheet['Normal']
data = [[Paragraph(cell, style) for cell in row] for row in batch]
# Define table style
tblstyle = TableStyle([('INNERGRID', (0, 0), (-1, -1), 0.25, colors.white),
('BOX', (0, 0), (-1, -1), 0.25, colors.white),
('FONTSIZE', (0, 0), (-1, 0), 12),
('FONTSIZE', (0, 1), (-1, -1), 8),
('TEXTFONT', (0, 0), (-1, 0), 'Helvetica-Bold'),
('TEXTFONT', (0, 1), (0, -1), 'Calibri-Bold'),
('TEXTFONT', (0, 1), (-1, -1), 'Calibri'),
('TEXTCOLOR',(1,1),(-2,-2),colors.red),
('TEXTCOLOR', (0, 0), (0, -1), colors.blue),
('TEXTCOLOR', (0, -1), (-1, -1), colors.green),
('TEXTCOLOR', (1, 1), (1, -1), colors.black),
('LEFTPADDING', (0, 0), (-1, -1), 4),
('RIGHTPADDING', (0, 0), (-1, -1), 4),
('TOPPADDING', (0, 0), (-1, -1), 8),
('BOTTOMPADDING', (0, 0), (-1, -1), 8),
('ROWBACKGROUNDS', (0, 0), (-1, -1),
(colors.HexColor('#e8e9ec'), colors.HexColor('#CED1D6'))),
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#99D9EA')),
('ALIGN', (0, 0), (-1, 0), 'CENTER'),
('ALIGN', (0, 1), (-1, -1), 'CENTER')
])
doc = SimpleDocTemplate(outfile, pagesize=landscape(legal),rightMargin=0.5 * inch,
leftMargin=0.5 * inch, topMargin=0.5 * inch, bottomMargin=0.5 * inch)
reportTable = Table(data, colWidths=columnWidths, hAlign='LEFT', repeatRows=1)
reportTable.setStyle(tblstyle)
story = []
story.append(reportTable)
doc.build(story)