Search code examples
pythonpdfpypdf

Center the page number in a footer using PyPDF


I'm using PyPDF to create a formatted report. I want the page number (e.g. Page 1 of 3) to be centered in the footer, pretty much exactly how the PyPDF tutorial shows. Here's the tutorial I'm referencing.

Below is the code I put in the footer method:

def footer(self):
    genDateTime = "Report generated on: " + datetime.datetime.now().strftime('%m/%d/%Y %I:%M:%S %p')
    page = 'Page ' + str(self.page_no()) + '/{nb}'

    self.set_y(-10)
    self.set_font('Arial', '', 9)

    self.cell(0, 5, "Clinical Report: Confidential", 0, 0, 'L')
    self.cell(0, 5, page, 0, 0, 'C')
    self.cell(0, 5, genDateTime, 0, 0, 'R')

Here is a screenshot of the bottom of the page. As you can see, the Confidential and DateTime labels are showing up as expected, but the Page # label is right justified:

Screenshot

Thanks for the help.


Solution

  • I think the issue is with how you are setting cell width. PyPDF by default places cells sequentially, starting at the far right of the previously placed cell. When you call self.cell(), the first argument is width -- by default if width is 0, it makes the width extend to the far right of the page. So when you place self.cell(0, 5, "Clinical Report: Confidential", 0, 0, 'L'), that text box is extending all the way to the right of the page. Then when you try to place self.cell(0, 5, page, 0, 0, 'C'), it is centering it in the remaining space on that line -- but there is no space left so it just places it at the end. Try giving your first cell some width like this:

    def footer(self):
        genDateTime = "Report generated on: " + datetime.datetime.now().strftime('%m/%d/%Y %I:%M:%S %p')
        page = 'Page ' + str(self.page_no()) + '/{nb}'
    
        self.set_y(-10)
        self.set_font('Arial', '', 9)
    
        self.cell(5, 5, "Clinical Report: Confidential", 0, 0, 'L')
        self.cell(0, 5, page, 0, 0, 'C')
        self.cell(0, 5, genDateTime, 0, 0, 'R')
    

    You might have to make the width greater than 5 to display all your text, but you can play with that.