Сообщить об ошибке.

Верхний/нижний колонтитулы PDF-документа, модуль fpdf2 в Python

Добавление верхнего/нижнего колонтитулов в создаваемый PDF

В этом примере используются методы FPDF.header() и FPDF.footer() для обработки заголовков и колонтитулов каждой страницы. Они вызываются автоматически. Они уже определены как пустые методы в классе FPDF() и ничего не делают, следовательно нужно их просто переопределить.

Картинка логотипа вставляется в PDF-документ методом FPDF.image() с указанием ее левого верхнего угла x и y - это числа 10мм и 8мм, а так-же ширина изображения - 33 мм. Высота вычисляется автоматически, чтобы соблюсти пропорции изображения.

Для печати номера страницы, в качестве ширины ячейки передается нулевое значение. Это означает, что ширина ячейки будет максимальной и простирается до правого поля страницы, что удобно для центрирования текста. Номер текущей страницы возвращается методом FPDF.page_no(). Что касается общего количества страниц, то оно получается с помощью специального значения {nb}, которое будет подставлено при закрытии документа, для этого сначала вызывается метод FPDF.alias_nb_pages().

Обратите внимание на использование метода FPDF.set_y(), который позволяет установить позицию в абсолютном месте страницы, начиная сверху или снизу.

Так же в примере используется еще один интересный метод: автоматический разрыв страницы. Как только ячейка пересекает границу страницы (по умолчанию 2 сантиметра снизу), то автоматически происходит разрыв страницы и шрифт восстанавливается к заданному для всего документа. Если верхний и нижний колонтитулы будут использовать свой собственный шрифт, то основная часть PDF-документа продолжает использовать Sans. Этот механизм автоматического восстановления также применяется к цветам и ширине линий. Предел, который вызывает разрыв страницы, можно установить с помощью метода FPDF.set_auto_page_break().

from fpdf import FPDF

class PDF(FPDF):

    colontitle = None

    def header(self):
        """Оформление верхнего контитула каждого листа"""
        # Визуализация логотипа (добавьте свою картину 
        # или закомментируйте следующую строку)
        self.image("/path/to/logo.png", 10, 8, 33)
        # Настройка шрифта: Sans bold 15
        self.set_font("Sans", "I", 15)
        # вычисление длины колонтитула
        width = self.get_string_width(self.colontitle) + 6
        # установка курсора:
        self.set_x((210 - width) / 2)
        # добавляем текст колонтитул в PDF:
        self.cell(width, 9, self.colontitle, 1, 0, "C")
        # Выполнение разрыва строки:
        self.ln(20)

    def footer(self):
        """Оформление нижнего контитула каждого листа"""
        # Устанавливаем курсор на 1,5 см от нижнего края
        self.set_y(-15)
        # Настройка шрифта: Sans italic 8
        self.set_font("Sans", "I", 8)
        # добавляем текст контитула:
        self.cell(0, 10, f"Страница {self.page_no()}/{{nb}}", 0, 0, "C")

# создание экземпляра 
# унаследованного класса
pdf = PDF()
# включаем TTF шрифты, поддерживающие кириллицу
pdf.add_font("Sans", style="", fname="Noto_Sans/NotoSans-Regular.ttf", uni=True)
pdf.add_font("Sans", style="B", fname="Noto_Sans/NotoSans-Bold.ttf", uni=True)
pdf.add_font("Sans", style="I", fname="Noto_Sans/NotoSans-Italic.ttf", uni=True)
pdf.add_font("Sans", style="BI", fname="Noto_Sans/NotoSans-BoldItalic.ttf", uni=True)
# метод, получает общее количество  
# страниц в документе при его закрытии
pdf.alias_nb_pages()
# текст верхнего колонтитула документа
pdf.colontitle = "Колонтитул документа"
# добавляем пустую страницу
pdf.add_page()
# настройка шрифта
pdf.set_font("Sans", size=10)
for i in range(1, 41):
    pdf.cell(0, 10, f"Номер строки {i}", 0, 1)
pdf.output("test.pdf")

Описание используемых методов модуля fpdf2.

FPDF.alias_nb_pages(alias='{nb}'):

Метод FPDF.alias_nb_pages задает псевдоним для последующего вывода общего количества страниц. Он будет заменен при закрытии документа.

Такое поведение полезно для вставки количества страниц документа в то время, когда это количество еще неизвестно программе.

Эту замену можно отключить по соображениям производительности, вызвав FPDF.alias_nb_pages(None).

Примечание: При использовании этой функции с методами FPDF.cell()/FPDF.multicell() или с атрибутом FPDF.underline, ширина отображаемого текста будет учитывать длину псевдонима, а не длину строки "фактическое количество страниц", что может привести к небольшим различиям в позиционировании.

FPDF.page_no:

Метод FPDF.page_no получает и возвращает номер текущий страницы.

FPDF.pages_count:

Метод FPDF.pages_count возвращает общее количество страниц документа после его создания.