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

Создание и добавление таблиц в PDF-документ

Таблицы могут быть созданы и добавлены в PDF-документ с использованием методов FPDF.cell(), FPDF.multi_cell() или FPDF.write_html().

Содержание:


Создание и добавление таблиц методом FPDF.multi_cell().

Метод FPDF.multi_cell() при построении таблиц позволяет размещать в ячейках многострочное содержимое.

Для генерации PDF-документа на русском языке, необходимо подключить шрифты, поддерживающие кириллицу методом FPDF.add_font() и установить их по умолчанию методом FPDF.set_font().

from fpdf import FPDF

data = [
    ("Имя", "Фамилия", "Возраст", "Город"),
    ("Jules", "Smith", "34", "San Juan"),
    ("Mary", "Ramos", "45", "Orlando"),
    ("Carlson", "Banks", "19", "Los Angeles"),
    ("Lucas", "Cimon", "31", "Saint-Mahturin-sur-Loire"),
]

pdf = FPDF()
# директория где лежат системные шрифты OS Linux
font_dir = '/usr/share/fonts/truetype/freefont'
# добавляем TTF-шрифт, поддерживающий кириллицу.
pdf.add_font("Serif", style="", fname=f"{font_dir}/FreeSerif.ttf", uni=True)
pdf.add_page()
pdf.set_font("Serif", size=10)
# высота ячейки
line_height = pdf.font_size * 2.5
# одинаковая ширина ячеек
col_width = pdf.epw / 4
# проходимся по списку с данными
for row in data:
    # получаем данные колонки таблицы
    for datum in row:
        # выводим строку с колонками
        pdf.multi_cell(col_width, line_height, datum, border=1, ln=3, max_line_height=pdf.font_size)
    pdf.ln(line_height)
pdf.output('table_with_cells.pdf')

Добавление таблиц методом FPDF.write_html().

Альтернативный метод с использованием объекта FPDF.HTMLMixin с теми же данными, что и выше, и шириной столбцов, определяемой как процент от эффективной ширины листа PDF-документа.

Для генерации PDF-документа на русском языке, необходимо подключить шрифты, поддерживающие кириллицу методом FPDF.add_font() и установить их по умолчанию методом FPDF.set_font().

from fpdf import FPDF, HTMLMixin

data = (
    ("Имя", "Фамилия", "Возраст", "Город"),
    ("Jules", "Smith", "34", "San Juan"),
    ("Mary", "Ramos", "45", "Orlando"),
    ("Carlson", "Banks", "19", "Los Angeles"),
    ("Lucas", "Cimon", "31", "Saint-Mahturin-sur-Loire"),
)

class PDF(FPDF, HTMLMixin):
    pass

pdf = PDF()
# директория где лежат системные шрифты OS Linux
font_dir = '/usr/share/fonts/truetype/freefont'
# добавляем TTF-шрифт, поддерживающий кириллицу.
pdf.add_font("Serif", style="", fname=f"{font_dir}/FreeSerif.ttf", uni=True)
pdf.add_font("Serif", style="B", fname=f"{font_dir}/FreeSerifBold.ttf", uni=True)
pdf.set_font("Serif", size=16)
pdf.add_page()
pdf.write_html(
    f"""<table border="1"><thead><tr>
    <th width="25%">{data[0][0]}</th>
    <th width="25%">{data[0][1]}</th>
    <th width="15%">{data[0][2]}</th>
    <th width="35%">{data[0][3]}</th>
</tr></thead><tbody><tr>
    <td>{'</td><td>'.join(data[1])}</td>
</tr><tr>
    <td>{'</td><td>'.join(data[2])}</td>
</tr><tr>
    <td>{'</td><td>'.join(data[3])}</td>
</tr><tr>
    <td>{'</td><td>'.join(data[4])}</td>
</tr></tbody></table>""",
    table_line_separators=True)
pdf.output('table_html.pdf')

Повторение "шапки" таблицы на каждой странице.

Обратите внимание, если для создания таблицы используется метод FPDF.multi_cell() вместо FPDF.cell(), то потребуется дополнительный код для вычисления количества строк в ячейке, а так же потребуется первоначальный вызов FPDF.multi_cell() с аргументом split_only=True.

Для генерации PDF-документа на русском языке, необходимо подключить шрифты, поддерживающие кириллицу методом FPDF.add_font() и установить их по умолчанию методом FPDF.set_font().

Следующий код демонстрирует как можно выводить "шапку" таблицы при ее переносе на другой лист.

from fpdf import FPDF

TABLE_COL_NAMES = ("Имя", "Фамилия", "Возраст", "Город")
TABLE_DATA = (
     ("Jules", "Smith", "34", "San Juan"),
    ("Mary", "Ramos", "45", "Orlando"),
    ("Carlson", "Banks", "19", "Los Angeles"),
    ("Lucas", "Cimon", "31", "Angers"),
)

pdf = FPDF()
# директория где лежат системные шрифты OS Linux
font_dir = '/usr/share/fonts/truetype/freefont'
# добавляем TTF-шрифт, поддерживающий кириллицу.
pdf.add_font("Serif", style="", fname=f"{font_dir}/FreeSerif.ttf", uni=True)
pdf.add_font("Serif", style="B", fname=f"{font_dir}/FreeSerifBold.ttf", uni=True)
pdf.add_page()
pdf.set_font("Serif", size=16)
line_height = pdf.font_size * 2
# равномерно распределим контент
col_width = pdf.epw / 4

def render_table_header():
    """Вывод строки с заголовками колонок таблицы"""
    # включение жирного текста
    pdf.set_font(style="B")
    for col_name in TABLE_COL_NAMES:
        pdf.cell(col_width, line_height, col_name, border=1)
    pdf.ln(line_height)
    # отключение жирного текста
    pdf.set_font(style="")  

# Вывод строки с заголовком таблицы
render_table_header()
# повторим данные 10 раз, что бы 
# таблица перешла на второй лист  
for _ in range(10):
    # проходим по строкам с данными
    for row in TABLE_DATA:
        # если, при добавлении строки с высотой
        #  `line_height` будет разрыв страницы
        if pdf.will_page_break(line_height):
            # то запускаем функцию заголовка таблицы
            render_table_header()
        for datum in row:
            # выводим в цикле колонки с данными
            pdf.cell(col_width, line_height, datum, border=1)
        pdf.ln(line_height)

pdf.output("table_headers_page.pdf")

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

FPDF.cell(w=None, h=None, txt='', border=0, ln=0, align='', fill=False, link='', center=False, markdown=False):

Метод FPDF.cell() печатает ячейку с шириной w и высотой h (прямоугольную область) с дополнительными границами border и строкой символов txt.

Левый верхний угол ячейки соответствует текущей позиции курсора. Текст можно выровнять, передав аргументу align по левому L, правому R краю или по центру C. После вызова метода, текущая позиция перемещается вправо или на следующую строку. На выведенный текст можно поставить ссылку link.

Если автоматический разрыв страницы включен FPDF.set_auto_page_break(auto=True) и ячейка выходит за пределы нижнего поля/отступа листа, то перед выводом выполняется разрыв страницы.

Метод FPDF.cell() возвращает логическое значение, указывающее, был ли запущен разрыв страницы.

Получаемые аргументы:

  • w=None: int, ширина ячейки. Значение по умолчанию: None, то есть соответствует ширине текста. Если 0, то ячейка расширяется до правого края листа PDF-документа.

  • h=None: int, , ширина ячейки. Значение по умолчанию: None, это означает высоту, равную текущему размеру шрифта.

  • txt='': текст для печати. Значение по умолчанию: пустая строка.

  • border=0: указывает, нужно ли рисовать границы вокруг ячейки. Значение может быть либо числом (0: без рамки; 1: с рамкой), либо строкой, содержащей некоторые или все следующие символы (в любом порядке):

    • 'L' - рисует границу слева;
    • 'T' - рисует границу сверху;
    • 'R' - рисует границу справа ;
    • 'B' - рисует границу внизу.
  • ln=0: int, указывает, куда должна перейти текущая позиция курсора после вызова.

    Возможные значения:

    • 0 - вправо;
    • 1 - в начало следующей строки;
    • 2 - ниже с тем же смещением по горизонтали.

    Установка значения 1 эквивалентна установке 0 и вызову сразу после этого метода перевода строки FPDF.ln(). Значение по умолчанию 0.

  • align='': центрирует или выравнивает текст внутри ячейки.

    Возможные значения:

    • 'L' или пустая строка - выравнивание по левому краю (значение по умолчанию);
    • 'J' - выравнивание по ширине;
    • 'C' - выравнивание по центру;
    • 'R' - выравнивание по правому краю.
  • fill=False: bool, должен ли фон ячейки быть окрашенным (True) или прозрачным (False). Значение по умолчанию: False.

  • link='': необязательная ссылка для добавления в ячейку, внутренняя (идентификатор, возвращаемый FPDF.add_link()) или внешний URL.

  • center=False: выравнивает ячейку горизонтально, по центру страницы.

  • markdown=False: включает минимальную разметку, подобную markdown. Поддерживает только: **полужирный**, __курсив__, -подчеркнутый-. По умолчанию False. По умолчанию False.

FPDF.multi_cell(w, h=None, txt='', border=0, align='J', fill=False, split_only=False, link='', ln=0, max_line_height=None, markdown=False):

Метод FPDF.multi_cell() позволяет печатать текст с разрывами строки.

Разрывы строки могут быть автоматическими (как только текст достигает правой границы ячейки) или явными (символ новой строки \n).

При печати будет складываться столько ячеек, сколько необходимо, одна под другой. Текст может быть выровнен по левому краю, по центру или по ширине.

У блоки ячеек можно сделать рамки - видимыми.

Метод FPDF.multi_cell() возвращает логическое значение, указывающее, был ли запущен разрыв страницы, или если установлен split_only==True, то возвращает список, представляющий собой аргумент txt разделенный на строки.

  • w: int, ширина ячейки. Если равна 0, то ячейка расширяется до правого края листа PDF-документа.

  • h=None: ширина ячейки. Значение по умолчанию: None, это означает высоту, равную текущему размеру шрифта.

  • txt='': текст для печати. Значение по умолчанию: пустая строка.

  • border=0: указывает, нужно ли рисовать границы вокруг ячейки. Значение может быть либо числом (0: без рамки; 1: с рамкой), либо строкой, содержащей некоторые или все следующие символы (в любом порядке):

    • 'L' - рисует границу слева;
    • 'T' - рисует границу сверху;
    • 'R' - рисует границу справа ;
    • 'B' - рисует границу внизу.
  • align='J': центрирует или выравнивает текст внутри ячейки. По умолчанию будет выравнивать по ширине листа.

    Возможные значения:

    • 'L' или пустая строка - выравнивание по левому краю;
    • 'J' - выравнивание по ширине;
    • 'C' - выравнивание по центру;
    • 'R' - выравнивание по правому краю
  • fill=False: bool, должен ли фон ячейки быть окрашенным (True) или прозрачным (False). Значение по умолчанию: False.

  • split_only: если True, ничего не выводит, только выполняет перенос слов и возвращает результирующий многострочный массив строк.

  • link='': необязательная ссылка для добавления в ячейку, внутренняя (идентификатор, возвращаемый FPDF.add_link()) или внешний URL.

  • ln=0: int, указывает, куда должна перейти текущая позиция курсора после вызова.

    Возможные значения:

    • 0 - вправо;
    • 1 - в начало следующей строки;
    • 2 - ниже с тем же смещением по горизонтали.
    • 3 - вправо с тем же смещением по вертикали..

    Установка значения 1 эквивалентна установке 0 и вызову сразу после этого перевода строки FPDF.ln().

  • max_line_height: int, необязательная максимальная высота каждой сгенерированной дочерней ячейки.

  • markdown=False: включает минимальную разметку, подобную markdown. Поддерживает только: **полужирный**, __курсив__, -подчеркнутый-. По умолчанию False.

Использование аргумента ln=3 совместно с аргументом max_line_height=pdf.font_size полезно для построения таблиц с многострочным текстом в ячейках.

FPDF.set_line_width(width):

Метод FPDF.set_line_width() задает ширину линии для всех операций обводки (границы ячеек таблицы; рисование линии, прямоугольника и т.д.). По умолчанию значение равно 0,2 мм. Метод может быть вызван до создания первой страницы, и значение сохраняется от страницы к странице.

Аргумент width ширина, выраженная в единицах измерения, заданных при создании экземпляра FPDF()

FPDF.will_page_break(height):

Метод FPDF.will_page_break() сообщает, приведет ли добавление элемента с высотой height к разрыву страницы.

Аргумент height - высота добавляемой секции, принимает значение float.

Метод возвращает логическое значение, указывающее, произойдет ли разрыв страницы.