I am new to reportLab package and I want create an Invoice , So I want header on the first Page , than table that can be one more than one page but if for example comes into 2 pages and half ( half of page 3) it shouldn't not end in half of page I should add empty rows to the footer which has a static height, the idea I have is to calculat remaing space at the last page from bottom - footer height , all this free space i will add into empty rows in my table I have coded this:
import random
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Spacer, Paragraph
from reportlab.lib.styles import getSampleStyleSheet
class InvoiceGenerator:
def __init__(self, pdf_filename):
self.pdf_filename = pdf_filename
self.story = []
def generate_invoice(self):
doc = SimpleDocTemplate(self.pdf_filename, pagesize=letter)
# Add elements to the story
self.add_header(doc)
self.add_table(doc)
self.add_footer(doc)
# Build the PDF
doc.build(self.story)
print(f"Document Height: {doc.height}")
def add_header(self,doc):
# Calculate the remaining space on the last page after adding the table
# Calculate the height of the footer
header_text = "Hello"
header_paragraph = Paragraph(header_text, self.get_style('header'))
def add_table(self, doc):
# Example table data with random values
table_data = [["Designation", "Quantities", "Unit Price", "Total Price"]]
for _ in range(180): # You can adjust the number of rows as needed
designation = random.choice(['Product A', 'Product B', 'Product C'])
quantities = random.randint(1, 10)
unit_price = random.randint(1, 10)
total_price = quantities * unit_price
table_data.append([designation, quantities, unit_price, total_price])
# Create the table
table = Table(table_data)
table.setStyle(TableStyle([
('BOX', (0, 0), (-1, -1), 1, colors.black),
]))
# Add the table to the story
self.story.append(table)
def add_footer(self, doc):
# Calculate the remaining space on the last page after adding the table
remaining_space = doc.bottomMargin
# Calculate the height of the footer
footer_text = "Hello"
footer_paragraph = Paragraph(footer_text, self.get_style('footer'))
footer_height = footer_paragraph.wrap(doc.width, remaining_space)[1]
# Calculate the number of blank rows based on the remaining space minus the height of the footer
num_blank_rows = int((remaining_space - footer_height) / 12) # Adjust the spacing as needed
# Add blank rows to fill the remaining space on the last page
for _ in range(num_blank_rows):
self.story.append(Spacer(1, 12)) # Adjust the spacing as needed
# Add the footer
self.story.append(footer_paragraph)
def get_style(self, style_type):
styles = getSampleStyleSheet()
if style_type == 'header':
return styles['Heading1']
if style_type == 'footer':
return styles['Heading2']
else:
return None
# Example usage
pdf_filename = "invoice_example.pdf"
invoice_generator = InvoiceGenerator(pdf_filename)
invoice_generator.generate_invoice()
but table must has empty rows until end of page
