Dinamic Header with reportlab.platypus

36 views Asked by At

I'm trying to generate a PDF from an excel. I can read and build the document now. My excel has a lot of sheet, one for each chapter with the exception of the first becouse it contains configurations about the papper and the footer. My intention now is to do an header with the name of the chapter (The chapter name is the name of the worksheet that is serving as the basis for the build). I have no idea how to do this becouse my page and my footer is static, but mey header need to be dinamic. I share my code below

from reportlab.lib.pagesizes import A4
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate, Paragraph
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib import colors, utils
import pandas as pd
import numpy as np

class CustomDocTemplate(BaseDocTemplate):
    def afterPage(self):
        # Verifica se self.page está dentro dos limites válidos
        if self.page < len(self.pageTemplates) and not self.pageTemplates[self.page]:
            # Adiciona novamente os PageTemplates
            self.addPageTemplates(self.pageTemplates)
        # Chama o método afterPage da classe pai
        super(CustomDocTemplate, self).afterPage()

def drawBackground(canvas, doc):
    imagem_fundo = "caminho\\para\\a\\imagem"
    canvas.saveState()
    canvas.drawImage(imagem_fundo, 0, 0, width=A4[0], height=A4[1], preserveAspectRatio=True)
    canvas.restoreState()

    # Adiciona a numeração de página
    page_number_text = "{}".format(doc.page)
    canvas.setFont("Helvetica", 10)  # Ajuste o tamanho e a fonte conforme necessário
    canvas.drawRightString(A4[0] - 20, 40, page_number_text)

    # Adiciona o rodapé
    rodape = []
    for index in df['GERAL'][df['GERAL']['Identificador'] == 'Rodapé'].index:
        valor_rodape = df['GERAL'].loc[index, 'Entradas']
        rodape.append(valor_rodape)

    rodape_y = 40
    for item in rodape:
        rodape_x = canvas.stringWidth(item, "Helvetica", 10) + 20
        canvas.drawRightString(rodape_x, rodape_y, item)
        rodape_y -= 12

# Crie um documento personalizado usando a classe CustomDocTemplate com tamanho A4
doc = CustomDocTemplate("exemplo.pdf", pagesize=A4)

dataframe = pd.ExcelFile('caminho\\para\\o\\excel')

sheet_names = dataframe.sheet_names     # Armazena os títulos de todas as planilhas do documento

df = {}                                 # Dicionário para armazenar as tabelas

styles = getSampleStyleSheet()      #Cria o objeto styles com os métodos pré-definidos da biblioteca

style_title = styles["Title"]
style_title.fontSize = 20
style_title.fontName = 'Helvetica-Bold'

#Alinhamento
Centralizado = 1
Justificado = 4

# Mapeia todas as planilhas e separa cada uma em um dataframe
for sheet_name in sheet_names:
    dfs = dataframe.parse(sheet_name)   # Pega os dados de uma planílha e armazena no dfs
    dfs = dfs.replace('', np.nan)       # Substitui as células vazias por NaN, caso existam
    df[sheet_name]=dfs                  # Armazena o dataframe no dicionário

# Defina o estilo dos parágrafos
styles = getSampleStyleSheet()
style_normal = styles['Normal']

# Defina um PageTemplate com um Frame para todo o conteúdo
frame = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height)
template = PageTemplate(id='all', frames=[frame], onPage=drawBackground)
doc.addPageTemplates([template])

# Crie uma lista de Flowables para adicionar ao documento
flowables = []

def texto(linha, story):
   style = getSampleStyleSheet()['Normal']
   style.fontName = 'Helvetica'
   style.fontSize = 12
   style.alignment = Justificado
   style.textColor = colors.black
                
   paragraph = Paragraph(linha['Entradas'], style)
   flowables.append(paragraph)

for sheet_name in sheet_names:
    current_xls = df[sheet_name].copy()  # Cria uma cópia do DataFrame da folha atual
    if sheet_name == 'GERAL':
        for index, row in current_xls.iterrows():
            if row['Identificador'] == 'Imagem de Alerta':
                imagem_alerta = row['Endereços']
    else:
        chapter_title = f"{sheet_name}".upper()
        first_section = True
        for index, row in current_xls.iterrows():
            if row['Identificador'] == 'Texto':
                texto(row, flowables)

# Construa o documento passando a lista de Flowables
doc.build(flowables)
0

There are 0 answers