I'm working on a PDF generation script using ReportLab in Python. The script generates a PDF with a client table and some additional information. I have implemented a custom PageNumCanvas class to handle page numbering.(PageNumCanvas is from https://www.blog.pythonlibrary.org/2013/08/12/reportlab-how-to-add-page-numbers/)
this is the PageNumCanvas. I override(in save method) the first page to add the page no on a fixed location.
But i need to load the page_count dynamically, in the client table.
class PageNumCanvas(canvas.Canvas):
"""
http://code.activestate.com/recipes/546511-page-x-of-y-with-reportlab/
http://code.activestate.com/recipes/576832/
This below code is taken from the
https://www.blog.pythonlibrary.org/2013/08/12/reportlab-how-to-add-page-numbers/
"""
#----------------------------------------------------------------------
def __init__(self, *args, **kwargs):
"""Constructor"""
canvas.Canvas.__init__(self, *args, **kwargs)
self.pages = []
#----------------------------------------------------------------------
def showPage(self):
"""
On a page break, add information to the list
"""
self.pages.append(dict(self.__dict__))
self._startPage()
#----------------------------------------------------------------------
def save(self):
"""
Add the page number to each page (page x of y)
"""
page_count = len(self.pages)
self.__dict__.update(self.pages[0])
self.setFont("Helvetica", 9)
self.drawRightString(270, 679, str(page_count))
for page in self.pages:
self.__dict__.update(page)
self.draw_page_number(page_count)
canvas.Canvas.showPage(self)
canvas.Canvas.save(self)
#----------------------------------------------------------------------
def draw_page_number(self, page_count):
"""
Add the page number
"""
page = "Page %s of %s" % (self._pageNumber, page_count)
self.setFont("Helvetica", 9)
self.drawRightString(200*mm, 20*mm, page)
class YourPdfClass:
def __init__(self):
pass
def header(self, canvas, doc):
pass
def write_pdf_lines(self, columns_fields, file_path):
pdf_filename = file_path
pdf_document = SimpleDocTemplate(pdf_filename, pagesize=letter
)
# Calculate the available width within the margins
available_width = pdf_document.width
styless = getSampleStyleSheet()
client_data=client_data = [
[
Paragraph(f"Client: <b>{x}</b>", styless['Normal']),
Paragraph(f"Downloaded By: <b>{y}</b>", styless['Normal']),
Paragraph(f"Date and Time: <b>{05-Jan-2024, 03:20 pm}</b>", styless['Normal'])
],
[
Paragraph(f"Records: <b>{z}</b>", styless['Normal']),
Paragraph("Pages:{}", styless['Normal']),
""
]
]
client_table=Table(client_data,
# colWidths=[available_width / 3] * 3,
spaceBefore=10)
# Build the PDF document
print("we started making pdf")
pdf_document.build([client_table],canvasmaker=PageNumCanvas)
def save(self):
"""
Add the page number to each page (page x of y)
"""
page_count = len(self.pages)
self.__dict__.update(self.pages[0])
self.setFont("Helvetica", 9)
self.drawRightString(270, 679, str(page_count))
for page in self.pages:
self.__dict__.update(page)
self.draw_page_number(page_count)
canvas.Canvas.showPage(self)
canvas.Canvas.save(self)
This load the data in fixed location. but if the dynamic value of other fields are large, it will get bigger, so it will look like misplaced.
Any insights into why this might be happening and suggestions for fixing it would be greatly appreciated. Thank you!
Ok sorry lets try again.
How's about we render the document but don't save it and use PageNumCanvas to count the pages. At this point we know the number of pages and we can update the cell that has the page count re-rendering the document.
using {{TOTAL_PAGES}}
So change the client_data:
]
and:
Let me know how you get on. Sorry for the late reply I am quite often away working. Good luck :)