Создание PDF при помощи PyFPDF и Python

автор

ReportLab – это основной инструмент, который я использую для создания PDF с нуля. Однако, я заметил, что есть еще один — PyFPDF или FPDF для Python. Пакет PyFPDF – это порт «бесплатного» пакета PDF, который написан на PHP. Релиза этого проекта не было несколько лет, однако есть движения в его репозитории на Github, так что работа над проектом ведется. Пакет PyFPDF поддерживает Python 2.7 и Pyhton 3.4+.

В данной статье не будет утомительных разборов пакета PyFPDF. Однако, мы раскроем более чем исчерпывающую информацию для эффективного использования. Обратите внимание на то, что существует небольшая книжечка «Python и PDF: pyFPDF» от Эдвуда Оказио на Leanpub, если вы захотите узнать больше о библиотеке, сверх той информации, которая указана в данной статье или документации пакета.

Установка

Установка PyFPDF – это просто, так как он подразумевает работу с pip. Установка проходит следующим образом:

На момент написания, эта команда устанавливала версию 1.7.2 на Python 3.6 без каких-либо проблем. Во время установки вы увидите, что этот пакет не имеет зависимостей, что приятно.

Базовое использование

Теперь, когда у вас есть установленный PyFPDF, попробуем использовать его для создания простого файла PDF. Откройте ваш редактор Python и создайте новый файл под названием **simple_demo.py**. После этого, введите следующий код:

Первый элемент, который нам нужно обсудить, это импорт. Здесь мы импортируем класс FPDF из пакета fpdf. Настройки по умолчанию этого класса создают PDF в режиме Portrait, используя миллиметры в качестве единицы измерения и размер страницы А4. Если вы хотите быть четче, вы можете вписать следующую строку установки:

Я не фанат использования буквы «P», чтобы указать классу, какая это ориентация. Вы можете использовать «L», если предпочитаете пейзаж вместо портрета.

Пакет PyFPDF поддерживает supports ‘pt’, ‘cm’ и ‘in’ в качестве альтернативных единиц измерения. Если обратиться к источнику, вы увидите, что пакет PyFPDF поддерживает только следующие размеры страниц:

  • А3
  • A4
  • A5
  • letter
  • legal

Это выглядит немного ограниченно, в сравнении с ReportLab, где у вас в распоряжении несколько дополнительных размеров поддерживаемых изначально, кроме этого, вы можете указать собственный размер страницы, если вам это нужно.

В любом случае, следующий шаг – это создание страницы при помощи метода add_page. Далее, мы указываем шрифт при помощи метода set_font. Вы увидите, что мы передаем родительское наименование шрифта и размер, которые нам нужны. Вы также можете настроить стиль шрифта при помощи аргумента style. Если вы хотите сделать это, помните, что для этого нужна строка, такая как «В» для жирного шрифта, или «Bl» для полужирного.

Далее, мы создаем клетку, шириной 200 миллиметров и 10 миллиметров в высоту. Клетка, по большому счету, плавающая, и содержит текст, к ней можно подключить границы. Она разделяется автоматически, если включен автоматический разрыв страницы, так что клетка перейдет за границу страницы. Параметр txt – это текст, который вам нужно ввести в PDF. Параметр In указывает PyFPDF, что нужно добавить разрыв строки, если он указан как 1, что мы и делаем в нашей статье. Наконец, мы можем установить выравнивание текста по ширине (по умолчания), или по центру («С»). Здесь мы выбираем второй вариант.

Наконец, мы сохраняем документ на диск, вызывая метод output с путем к файлу, который мы хотим сохранить.
После запуска кода, мой PDF выглядит следующим образом:

Давайте попробуем узнать побольше о работе PyFPDF со шрифтами.

Работа со шрифтами

PyFPDF содержит набор базовых шрифтов, старательно прописанных в класс FPDF:

Обратите внимание на то, что Arial здесь отсутствует, несмотря на то, что мы использовали его в предыдущем примере. Arial преобразован в Helvetica в исходном коде, так что фактически вы не пользуетесь Arial вообще. В любом случае, давайте узнаем, как менять шрифты при помощи PyFPDF:

Здесь мы создаем простую функцию под названием change_fonts, после чего мы создаем экземпляр класса FPDF.

Следующий шаг – это создание страницы и создание цикла над валидными шрифтами (другими словами — helveticaB, helveticaBI, и так далее). Чтобы пропустить эти варианты, мы создаем перечень сравнений и проверяем его на наличие любых заглавных букв в названии шрифта.

Если таковы имеются, мы пропускаем этот шрифт. В противном случае, мы настроим шрифт и его размер и впишем их. Мы также будем увеличивать размер шрифта на две точки через каждый цикл. Если вы хотите изменить цвет шрифта, вам нужно вызывать set_text_color и передать необходимое значение RGB.
В результате мы получим следующую картину:

Мне нравится простота, с которой можно менять шрифты в PyFPDF. Однако набор базовых шрифтов слишком мал. Вы можете добавить шрифты TrueType, OpenType или Type1 при помощи PyFPDF, используя метод add_font. Этот метод принимает следующие аргументы:

  • family (семейство шрифта)
  • style (стиль шрифта)
  • fname (имя файла шрифта, или полный путь к файлу шрифта)
  • uni (флаг TTF Unicode)

Пример, используемый документацией PyFPDF:

Вы можете вызвать **add_font** перед тем, как использовать его через метод **set_font**. Я пробовал делать это в Windows и получил ошибку: система не может найти этот шрифт, чего я и ожидал. Это очень простой способ добавления шрифтов, и он определенно работает. Обратите внимание на то, что здесь используются следующие части поиска:

  • FPDF_FONTPATH
  • SYSTEM_TTFONTS

Они представляют собой константы, которые определены в вашей среде, или напрямую в пакете PyFPDF. В документации не объясняется, как они настраиваются или модифицируются, однако, если вы посмотрите поближе на исходный код и API, станет ясно, что вам нужно добавить следующее в начало кода:

В противном случае SYSTEM_TTFONTS будет установлен в None

Рисование

Пакет PyFPDF содержит ограниченную поддержку рисования. Вы можете рисовать линии, эллипсы и прямоугольники. Для начала узнаем, как рисовать линии:

Здесь мы вызываем метод line, чтобы передать ему две пары координат x и y. Ширина линии по умолчанию – 0.2мм, так что мы расширим её до 1 мм для второй линии, вызывав метод set_line_width. Мы также указываем цвет второй линии, вызвав метод set_draw_color и указав значение RGB, эквивалентное красному цвету. Результат выглядит следующим образом:

Теперь мы можем перейти к рисованию нескольких фигур:

Когда вы рисуете фигуру, вроде эллипса или прямоугольника, вам нужно передать координаты x и y, которые обозначают верхний левый угол рисунка. Далее, вам может понадобиться указать ширину и высоту фигуры.

Последний аргумент, который передается методу style – это «D», или пустая строка (default), «F» для заливки, «DF» — для заливки и рисунка. В данном примере мы зальем эллипс и используем default для прямоугольника. Результат будет выглядеть следующим образом:

Теперь поговорим о поддержке изображений.

Добавление изображений

Пакет PyFPDF поддерживает добавление форматов JPEG, PNG и GIF в ваш PDF. Если вы попробуете залить анимированный GIF файл, будет отображаться только первый кадр. Также стоит обратить внимание на то, что если вы добавите одно и то же изображение несколько раз подряд в документ, то PyFPDF достаточно умен, чтобы добавлять только одну копию изображения. Вот очень простой пример добавления изображения в PDF при помощи PyFPDF:

Новая часть кода в данном случае – это вызов метода image. Сигнатура выглядит следующим образом:

Вы определяете путь к файлу изображения, координаты x и y, а также широту и высоту. Если определить только широту, или только высоту, второй параметр будет автоматически рассчитан для вас с учетом пропорций изображения. Вы также можете явно указать тип файла, в противном случае он будет подобран согласно с названием файла. Наконец, вы можете добавить ссылку или URL при прикреплении изображения.
Запустив этот код, вы увидите следующий результат:

Давайте узнаем, как PyFPDF поддерживает обработку документов в несколько страниц.

Многостраничные документы

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

Все, что здесь происходит – это создание 100 строк текста. Когда я запустил этот код, то получил 4 страницы текста.

Верхние и нижние колонтитулы

Пакет PyFPDF включает в себя встроенную поддержку верхних и нижних колонтитулов, а также нумерацию страниц. Класс FPDF должен стать подклассом, затем нужно ввести методы header и footer вручную для того, чтобы они заработали. Давайте взглянем на пример:

Так как это достаточно длинный кусок кода, давайте пройдемся по нему детально. Первый раздел, на который мы хотим взглянуть, это метод header:

Мы только что вручную вписали изображение логотипа, который нам нужно использовать, после этого мы установили шрифт, который будет использован в верхнем колонтитуле. Далее, мы добавляем адрес и размещаем его справа от изображения.

Обратите внимание на то, что если вы используете PyFPDF, начальная точка – это верхний левый угол страницы. Так что если мы хотим сместить наш текст вправо, то нам нужно создать клетку с количеством единиц измерений. В этом случае, мы смещаем следующие три линии вправо, добавив 100-миллиметровую клетку. Далее, мы добавим разрыв линии в конце, добавив, таким образом, 20 мм вертикального пространства.

Далее, нам нужно вписать метод footer:

Первое, что мы делаем здесь, это настраиваем позицию y в начале страницы на -10 мм, или -1 см. Это сместит начало нижнего колонтитула прямо над низом страницы. Далее, мы настроим шрифт для нашего нижнего колонтитула. Наконец мы создаем нумерацию страницы. Вы увидите упоминание {nb}. Это особое значение в PyFPDF, которое подключается, когда вы вызываете alias_nb_pages и показывает общее количество страниц в документе. Последний шаг в нижнем колонтитуле, это вписать и центрировать текст.

Последняя часть кода выглядит как в случае с функцией create_pdf:

Здесь мы вызываем волшебный метод **alias_nb_pages**, которые поможет нам получить общее количество страниц. Мы также может указать шрифт для части страницы, которая не является нижним или верхним колонтитулом. Далее, мы пишем 50 строк текста в документе, чтобы создать многостраничный PDF.

Запустив этот код, вы должны получить следующий результат:

Давайте рассмотрим, как создавать таблицы при помощи PyFPDF.

Таблицы

В PyFPDF нет управления таблицами. Вместо этого, вам нужно создавать таблицы при помощи клеток или HTML. Сначала рассмотрим создание таблиц при помощи клеток:

Мы только что создали простой список списков и запустили над ним цикл. Для каждого пункта списка и каждого элемента в размещенном пункте мы создали клетку в нашем объекте PDF. Обратите внимание на то, что мы включили границу для этих клеток.

По окончанию итерации над пунктом, мы добавляем разрыв строки. Если вам нужно, чтобы в клетках было больше места, вы можете передать значение этого места. Запустив этот скрипт, у меня вышла таблица, которая выглядит следующим образом:

Это достаточно грубый способ создания таблиц в PDF. Лично я предпочитаю методику ReportLab в данном случае.

Альтернативный метод – это использование HTML при создании таблицы:

Здесь мы используем класс HTMLMixin пакета PyFPDF, чтобы принимать HTML в качестве вводного и трансформируем его в PDF. Запустив данный пример, вы должны получить следующий результат:

Существует несколько примеров, где используется фреймворк Web2Py в сочетании с PyFPDF, для создания более красивых таблиц, но код еще не доведен до конца, так что мы не будем рассматривать этот метод здесь.

Трансформация HTML в PDF

В пакете PyFDPF есть ограниченная поддержка HTML Тегов. Вы можете создавать заголовки, абзацы и базовый стиль текста при помощи HTML. Также вы можете добавлять гиперссылки, изображения, списки и таблицы.

Вы можете ознакомиться с документацией для полного списка тегов и атрибутов, которые поддерживаются. Также вы взять базовый код HTML и превратить его в PDF при помощи HTMLMixin, что мы и видели в предыдущем разделе, при создании нашей таблицы.

Здесь мы используем стандартную разметку HTML для разработки PDF. Выглядит достаточно симпатично, когда вы запускаете этот код:

Web2Py

Фреймворк Web2Py включает в себя пакет PyFPDF, чтобы упростить создание отчетов в фреймворке. Это позволяет вам создавать шаблоны PDF в Web2Py. Документация немного скудная в контексте данной темы. Из-за этого мы не будем рассматривать этот момент в статье. Однако, вы определенно можете создавать наполовину достойные отчеты, используя Web2Py в этих целях.

Шаблоны

Вы можете создавать шаблоны при помощи PyFPDF. Пакет даже включает дизайнерский скрипт, который использует wxPython в качестве пользовательского интерфейса. Шаблоны, которые вы можете создавать, могут быть в том месте, где вы хотите расположить элемент страницы, его стиль (размер, шрифт, и т.д.), а также шаблон текста.

Система шаблона поддерживает использование CSV или баз данных. К сожалению, существует только один пример в документации, который затрагивает данную тему. Хотя эта часть библиотеки и многообещающая, факт того, что её документация скудная, неудобно писать об этом подробно.

Подведем итоги

Пакет PyFPDF это отличный проект, который открывает перед вами возможности базовой генерации PDF файлов. Разработчики упомянули в FAQ, что они не поддерживают графики и виджеты, как и «гибкую систему компоновки страниц», как в случае с ReportLab.

Также не поддерживается извлечение текста PDF, или конверсию, как PDFMiner или PyPDF2. Однако, если все, что вам нужно – это основы в генерации PDF, то эта библиотека вам отлично подойдет. Процесс обучения намного проще, чем у ReportLab. Однако возможности и функции PyFPDF и рядом не стояли с богатым ассортиментом ReportLab.

Вам может быть интересно

Scroll Up