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)