Search code examples
python-3.xreportlab

Reportlab header out of flowable Table


I'm trying to create a header that will go on each page in my PDF document that I'm generating with Reportlab. What I'm trying to achieve is to have a header that consists of a Table.

I have a method that creates the header like this:

    def make_header(self, canvas, doc):
    small_size = '8'
    big_size= '10'
    paragraphs = {}
    canvas.saveState()
    for key, name in (('doc_type', 'Document type'), ('owner', 'Owner'),
                      ('classification', 'Classification'),
                      ('document_nr', 'Document Number'),
                      ('date', 'Date'),
                      ('revision', 'Revision'),
                      ('title', 'Title')):
        t = self.header_info[key] if self.header_info[key] else ''
        paragraphs[key] = [Paragraph('<font size={}>{}</font>'.format(small_size, name), style=styles['Normal']),
                         Paragraph('<font size={}>{}</font>'.format(big_size, t), style=styles['Normal'])]

    im = self.scale_image("image.jpg", 10*cm)

    page = [Paragraph('<font size={}>{}</font>'.format(small_size, 'Page'), style=styles['Normal']),
            Paragraph('<font size={}>{}</font>'.format(big_size, doc.page), style=styles['Normal'])]

    t = Table([[im, paragraphs['doc_type'], paragraphs['owner'], paragraphs['date']],
               ['', paragraphs['classification'], paragraphs['document_nr'], paragraphs['revision']],
               ['', paragraphs['title'],'', page]])

    t.setStyle([('SPAN', (0,0), (0,2)),
                ('SPAN', (1,2), (2,2)),
                ('ALIGN', (0,0), (0,0), 'CENTER'),
                ('VALIGN', (0,0), (0,0), 'MIDDLE'),
                ('VALIGN', (1,0), (-1,-1), 'TOP')])
    self.table_grid(t)
    t.wrapOn(canvas, self.width-50, self.height)
    t.drawOn(canvas, *self.coord(10,10, mm))
    canvas.restoreState()

And then doing the following:

def build(self):
    t = Paragraph('test', style=styles['Normal'])
    self.doc.build([t], onFirstPage=self.make_header)

The only thing that shows up in my document is the "test" string but not the header. I have tested by using a print in make_header function so I know that it gets called and run.

I can't find whats missing so please help me in the right direction.


Solution

  • Hi your question was a bit confused with missing elements. I think the problem is with your idea of how one should use wrapOn and drawOn. Here is my hacked version which at least does something; for more help and discussions of reportlab you can ask at the users list https://pairlist2.pair.net/mailman/listinfo/reportlab-users

    from reportlab.platypus import Spacer, SimpleDocTemplate, Table, TableStyle
    from reportlab.platypus.paragraph import Paragraph
    from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
    from reportlab.lib import colors
    from reportlab.lib.units import inch
    
    styles = getSampleStyleSheet()
    class Test:
        header_info = dict(
                doc_type='MMMMM',
                )
        def make_header(self, canvas, doc):
            small_size = '8'
            big_size= '10'
            paragraphs = {}
            canvas.saveState()
            pageWidth, pageHeight = canvas._pagesize
    
            for key, name in (('doc_type', 'Document type'), ('owner', 'Owner'),
                              ('classification', 'Classification'),
                              ('document_nr', 'Document Number'),
                              ('date', 'Date'),
                              ('revision', 'Revision'),
                              ('title', 'Title')):
                t = self.header_info.get(key,'')
                paragraphs[key] = [Paragraph('<font size={}>{}</font>'.format(small_size, name), style=styles['Normal']),
                                 Paragraph('<font size={}>{}</font>'.format(big_size, t), style=styles['Normal'])]
    
            #im = self.scale_image("image.jpg", 10*cm)
    
            page = [Paragraph('<font size={}>{}</font>'.format(small_size, 'Page'), style=styles['Normal']),
                    Paragraph('<font size={}>{}</font>'.format(big_size, doc.page), style=styles['Normal'])]
    
            t = Table([['im', paragraphs['doc_type'], paragraphs['owner'], paragraphs['date']],
                       ['', paragraphs['classification'], paragraphs['document_nr'], paragraphs['revision']],
                       ['', paragraphs['title'],'', page]],
                        style=[('SPAN', (0,0), (0,2)),
                        ('SPAN', (1,2), (2,2)),
                        ('ALIGN', (0,0), (0,0), 'CENTER'),
                        ('VALIGN', (0,0), (0,0), 'MIDDLE'),
                        ('VALIGN', (1,0), (-1,-1), 'TOP'),
                        ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
                        ('BOX', (0,0), (-1,-1), 2, colors.black),
                        ])
    
            #self.table_grid(t)
            w,h = t.wrapOn(canvas, pageWidth-20, pageHeight-20)
            t.drawOn(canvas, 10, pageHeight-h-10)
            canvas.restoreState()
    
    
        def __init__(self):
            self.doc = SimpleDocTemplate('stackoverflow-48184260.pdf')
    
        def build(self):
            t = Paragraph('test', style=styles['Normal'])
            self.doc.build([t], onFirstPage=self.make_header)
    
    if __name__=='__main__':
        test = Test()
        test.build()