Рубрики
Без рубрики

Создание PDFS с FPDF2 и Python

Получите практические, реальные навыки Python на наших ресурсах и пути

Автор оригинала: Mike Driscoll.

REPORTLAB – основной инструментарий, который я использую для генерации PDFS с нуля. Тем не менее, я обнаружил, что есть еще один, называемый FPDF2 Отказ Пакет FPDF2 на самом деле является портом «бесплатный» -PDF пакет, который был написан в PHP.

Примечание: PYFPDF теперь мертв. Эта статья была изначально написана с учетом этого пакета. Это было заменено на FPDF2.

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

Монтаж

Установка FPDF2 легко, поскольку она была разработана для работы с PIP. Вот как:

Python -M PIP Установка FPDF2

Вы заметите, когда вы устанавливаете этот пакет, что не имеет зависимостей, что приятно.

Хотите узнать больше о работе с PDFS в Python? Затем проверьте мою книгу: REPORTLAB: PDF Обработка с покупкой Python Now на ScenPub

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

Теперь, когда у вас установлен FPDF2, давайте попробуем использовать его, чтобы создать простой PDF. Откройте свой редактор Python и создайте новый файл под названием Simple_demo.py Отказ Затем введите следующий код в него:

# simple_demo.py

from fpdf import FPDF

pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", size=12)
pdf.cell(200, 10, txt="Welcome to Python!", ln=1, align="C")
pdf.output("simple_demo.pdf")

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

pdf = FPDF(orientation='P', unit='mm', format='A4')

Я не вентилятор, используя букву «p», чтобы сказать классу, какова его ориентация. Вы также можете использовать «l», если вы предпочитаете ландшафт над портретом.

Пакет FPDF2 поддерживает «PT», «CM» и «в» в качестве альтернативных измерительных единиц.

Если вы погрузитесь в источник, вы обнаружите, что пакет FPDF2 поддерживает только следующие размеры страницы:

  • А3
  • А4.
  • A5.
  • письмо
  • юридический

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

В любом случае, следующий шаг – создать страницу, используя add_page . метод. Затем мы устанавливаем шрифт страницы через Set_Font метод. Вы отметите, что мы проходим на имя семьи шрифта и размер, который мы хотим. Вы также можете установить стиль шрифта с Стиль аргумент Если вы хотите сделать это, обратите внимание, что требуется такая строка, как «B» для смелых или «BI» для Смелый итализованный Отказ

Далее мы создаем клетки Это 200 миллиметров широк и 10 миллиметров высоты. Ячейка в основном является текучем, который удерживает текст и может иметь включенную границу. Он будет разделен автоматически, если включен автоматический разрыв страницы, и ячейка выходит за пределы размера страницы. TXT Параметр – это текст, который вы хотите распечатать в PDF. ln Параметр говорит PYFPDF, чтобы добавить линейный разрыв, если установлен на один, что мы здесь делаем. Наконец, мы можем установить выравнивание текста либо быть выровненным (по умолчанию), либо в центре («C»). Мы выбрали последнее здесь.

Наконец, мы сохраняем документ на диск, вызывая Выход Способ с пути к файлу, который мы хотим сохранить.

Когда я запустил этот код, я закончил PDF, который выглядел так:

Теперь давайте немного узнаем о том, как FPDF2 работает со шрифтами.

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

FPDF2 имеет набор основных шрифтов, жесткокодируемых в своем классе FPDF:

self.core_fonts={'courier': 'Courier',
    'courierB': 'Courier-Bold',
    'courierBI': 'Courier-BoldOblique',
    'courierI': 'Courier-Oblique',
    'helvetica': 'Helvetica',
    'helveticaB': 'Helvetica-Bold', 
    'helveticaBI': 'Helvetica-BoldOblique',
    'helveticaI': 'Helvetica-Oblique',
    'symbol': 'Symbol',
    'times': 'Times-Roman',
    'timesB': 'Times-Bold',
    'timesBI': 'Times-BoldItalic',
    'timesI': 'Times-Italic',
    'zapfdingbats': 'ZapfDingbats'}

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

# change_fonts.py

from fpdf import FPDF

def change_fonts():
    pdf = FPDF()
    pdf.add_page()
    font_size = 8
    for font in pdf.core_fonts:
        if any([letter for letter in font if letter.isupper()]):
            # skip this font
            continue
        pdf.set_font(font, size=font_size)
        txt = "Font name: {} - {} pts".format(font, font_size)
        pdf.cell(0, 10, txt=txt, ln=1, align="C")
        font_size += 2
    
    pdf.output("change_fonts.pdf")
    
if __name__ == '__main__':
    change_fonts()

Здесь мы создаем простой функцию под названием Change_Fonts И тогда мы создаем экземпляр класса FPDF. Следующий шаг состоит в том, чтобы создать страницу, а затем петлю по основным шрифтам. Когда я попробовал это, я обнаружил, что FPDF2 не учитывает варианты имена своих основных шрифтов в качестве действительных шрифтов (I. Helveticab, Helveticabi и т. Д.). Итак, для пропуска этих вариантов мы создаем понимание списка и проверьте любые символы капитала в имени шрифта. Если есть один, мы пропускаем этот шрифт. В противном случае мы устанавливаем шрифт и размер шрифта и выписывайте его. Мы также увеличиваем размер шрифта на две точки каждый раз через петлю. Если вы хотите изменить цвет шрифта, то вы можете позвонить set_text_color и пропустите значение RGB, которое вам требуется.

Результат выполнения этого кода выглядит так:

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

  • Семья (Font Family)
  • Стиль (стиль шрифта)
  • fname (имя файла шрифта или полный путь к файлу шрифта)
  • UNI (флаг TTF Unicode)

Примером, что использует документацию FPDF2 следующим образом:

pdf.add_font('DejaVu', '', 'DejaVuSansCondensed.ttf', uni=True)

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

  • Fpdf_fontpath.
  • System_ttfonts.

Похоже, что они являются константами, которые определяются либо в вашей среде, либо в сам пакет PYFPDF. Документация не объясняет, как они установлены или изменены. Вместо этого вы должны использовать set_global () С пути к шрифтам, которые вы хотите использовать.

import fpdf

fpdf_mod.set_global("SYSTEM_TTFONTS", os.path.join(os.path.dirname(__file__),'fonts'))

System_ttfonts установлен на Нет по умолчанию иначе.

Рисунок

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

# draw_lines.py

from fpdf import FPDF

def draw_lines():
    pdf = FPDF()
    pdf.add_page()
    pdf.line(10, 10, 10, 100)
    pdf.set_line_width(1)
    pdf.set_draw_color(255, 0, 0)
    pdf.line(20, 20, 100, 20)
    pdf.output('draw_lines.pdf')
    
if __name__ == '__main__':
    draw_lines()

Здесь мы называем линия Способ и пройти две пары координат X/Y. Ширина линии по умолчанию до 0,2 мм, поэтому мы увеличиваем его до 1 мм для второй линии, вызывая set_line_width метод. Мы также устанавливаем цвет второй строки, позвонив set_draw_color на значение RGB, эквивалентно красному. Вывод выглядит так:

Теперь мы можем двигаться дальше и нарисовать пару форм:

# draw_shapes.py

from fpdf import FPDF

def draw_shapes():
    pdf = FPDF()
    pdf.add_page()
    pdf.set_fill_color(255, 0, 0)
    pdf.ellipse(10, 10, 10, 100, 'F')
    
    pdf.set_line_width(1)
    pdf.set_fill_color(0, 255, 0)
    pdf.rect(20, 20, 100, 50)
    pdf.output('draw_shapes.pdf')
    
if __name__ == '__main__':
    draw_shapes()

Когда вы рисуете форму, как Эллипс или rect , вам нужно будет пройти через координаты X и Y, которые представляют верхний левый угол рисунка. Тогда вы захотите пройти в ширину и высоту формы. Последний аргумент, в котором вы можете передать, это Стиль которые могут быть «D» или пустой строкой (по умолчанию), «F» для заполнения или «DF» для навлечения и заполнения. В этом примере мы заполняем эллипс и используем по умолчанию для прямоугольника. Результат в конечном итоге выглядит так:

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

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

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

# add_image.py

from fpdf import FPDF

def add_image(image_path):
    pdf = FPDF()
    pdf.add_page()
    pdf.image(image_path, x=10, y=8, w=100)
    pdf.set_font("Arial", size=12)
    pdf.ln(85)  # move 85 down
    pdf.cell(200, 10, txt="{}".format(image_path), ln=1)
    pdf.output("add_image.pdf")
    
if __name__ == '__main__':
    add_image('snakehead.jpg')

Новый кусок кода здесь является вызов изображение метод. Его подпись выглядит так, как это:

image(name, x = None, y = None, w = 0, h = 0, type = '', link = '')

Вы указываете путь к файлу изображения, координату X и Y и ширина и высоту. Если вы укажете только ширину или высоту, другая рассчитана для вас и пытается сохранить исходные пропорции изображения. Вы также можете указать тип файла явно, в противном случае он угадан из имени файла. Наконец, вы можете добавить ссылку/URL при добавлении изображения.

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

Теперь давайте узнаем, как FPDF2 поддерживает умноженные документы.

Учетные документы

FPDF2 имел поддержку умноженной поддержки по умолчанию. Если вы добавляете достаточно ячейки на страницу, он автоматически создаст новую страницу и продолжает добавлять новый текст на следующую страницу. Вот простой пример:

# multipage_simple.py

from fpdf import FPDF

def multipage_simple():
    pdf = FPDF()
    pdf.set_font("Arial", size=12)
    pdf.add_page()
    line_no = 1
    for i in range(100):
        pdf.cell(0, 10, txt="Line #{}".format(line_no), ln=1)
        line_no += 1
    pdf.output("multipage_simple.pdf")
    
if __name__ == '__main__':
    multipage_simple()

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

Заголовки и колонтитулы

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

# header_footer.py

from fpdf import FPDF

class CustomPDF(FPDF):
    
    def header(self):
        # Set up a logo
        self.image('snakehead.jpg', 10, 8, 33)
        self.set_font('Arial', 'B', 15)
        
        # Add an address
        self.cell(100)
        self.cell(0, 5, 'Mike Driscoll', ln=1)
        self.cell(100)
        self.cell(0, 5, '123 American Way', ln=1)
        self.cell(100)
        self.cell(0, 5, 'Any Town, USA', ln=1)
        
        # Line break
        self.ln(20)
        
    def footer(self):
        self.set_y(-10)
        
        self.set_font('Arial', 'I', 8)
        
        # Add a page number
        page = 'Page ' + str(self.page_no()) + '/{nb}'
        self.cell(0, 10, page, 0, 0, 'C')
        
def create_pdf(pdf_path):
    pdf = CustomPDF()
    # Create the special value {nb}
    pdf.alias_nb_pages()
    pdf.add_page()
    pdf.set_font('Times', '', 12)
    line_no = 1
    for i in range(50):
        pdf.cell(0, 10, txt="Line #{}".format(line_no), ln=1)
        line_no += 1
    pdf.output(pdf_path)
    
if __name__ == '__main__':
    create_pdf('header_footer.pdf')

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

def header(self):
    # Set up a logo
    self.image('snakehead.jpg', 10, 8, 33)
    self.set_font('Arial', 'B', 15)
    
    # Add an address
    self.cell(100)
    self.cell(0, 5, 'Mike Driscoll', ln=1)
    self.cell(100)
    self.cell(0, 5, '123 American Way', ln=1)
    self.cell(100)
    self.cell(0, 5, 'Any Town, USA', ln=1)
    
    # Line break
    self.ln(20)

Здесь мы просто сложный код в Logo Image, который мы хотим использовать, а затем мы устанавливаем шрифт, который мы будем использовать в нашем заголовке. Далее мы добавляем адрес, и мы позиционируем этот адрес справа от изображения. Вы заметите, что когда вы используете FPDF2, происхождение находится в левом верхнем углу страницы. Поэтому, если мы хотим переместить наш текст справа, то нам нужно создать ячейку с рядом единиц измерения. В этом случае мы перемещаем следующие три линии вправо, добавляя клетку 100 мм. Затем мы добавляем перерыв линии в конце, что следует добавить 20 мм вертикального пространства.

Далее, мы хотим переопределить нижний колонтитул Метод:

def footer(self):
    self.set_y(-10)
    
    self.set_font('Arial', 'I', 8)
    
    # Add a page number
    page = 'Page ' + str(self.page_no()) + '/{nb}'
    self.cell(0, 10, page, 0, 0, 'C')

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

Окончательный кусок кода, чтобы посмотреть, находится в create_pdf Функция:

def create_pdf(pdf_path):
    pdf = CustomPDF()
    # Create the special value {nb}
    pdf.alias_nb_pages()
    pdf.add_page()
    pdf.set_font('Times', '', 12)
    line_no = 1
    for i in range(50):
        pdf.cell(0, 10, txt="Line #{}".format(line_no), ln=1)
        line_no += 1
    pdf.output(pdf_path)

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

Когда вы запускаете этот код, вы должны увидеть страницу, которая выглядит что-то подобное:

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

Столы

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

# simple_table.py

from fpdf import FPDF

def simple_table(spacing=1):
    data = [['First Name', 'Last Name', 'email', 'zip'],
            ['Mike', 'Driscoll', 'mike@somewhere.com', '55555'],
            ['John', 'Doe', 'jdoe@doe.com', '12345'],
            ['Nina', 'Ma', 'inane@where.com', '54321']
            ]
    
    pdf = FPDF()
    pdf.set_font("Arial", size=12)
    pdf.add_page()
    
    col_width = pdf.w / 4.5
    row_height = pdf.font_size
    for row in data:
        for item in row:
            pdf.cell(col_width, row_height*spacing,
                     txt=item, border=1)
        pdf.ln(row_height*spacing)
        
    pdf.output('simple_table.pdf')
    
if __name__ == '__main__':
    simple_table()

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

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

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

# simple_table_html.py

from fpdf import FPDF, HTMLMixin

class HTML2PDF(FPDF, HTMLMixin):
    pass

def simple_table_html():
    pdf = HTML2PDF()
    
    table = """

ячейка 1. ячейка 2.
ячейка 2. ячейка 3.

“” “pdf.add_page () pdf.write_html (таблица) pdf.output (‘simple_table_html.pdf’) Если __name__: simple_table_html ()

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

На веб-сайте есть несколько примеров, которые используют Framework Web2PY в сочетании с PYFPDF для создания лучших таблиц, но код был неполным, поэтому я не буду продемонстрировать, что здесь.

Преобразовать HTML к PDF

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

# html2fpdf.py

from fpdf import FPDF, HTMLMixin

class HTML2PDF(FPDF, HTMLMixin):
    pass

def html2pdf():
    html = '''

Это обычный текст

Вы также можете смелый , Итализировать или подчеркивать “‘() pdf.add_page () pdf.write_html (html) pdf.output (‘ html2pdf.pdf ‘) Если __name__: HTML2PDF ()

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

Web2py.

Web2Py Framework включает пакет FPDF2, чтобы облегчить создание отчетов в рамках. Это позволяет вам создавать шаблоны PDF в Web2PY. Документация немного скудна на эту тему, поэтому я не буду охватить эту тему в этой книге. Тем не менее, появляется, что вы можете сделать на полпути приличные отчеты, используя Web2PY таким образом.

Шаблоны

Вы также можете создавать шаблоны с использованием FPDF2. Пакет даже включает в себя дизайнерский скрипт, который использует WxPython для его пользовательского интерфейса. Шаблоны, которые вы можете создать, будет в том случае, если вы хотите указать, где каждый элемент появляется на странице, его стиль (шрифт, размер и т. Д.) и текст по умолчанию для использования. Система шаблонов поддерживает использование файлов CSV или баз данных. Во время этой темы есть только один пример в документации, который немного разочаровывает. Хотя я думаю, что эта часть библиотеки проводит обещание, из-за отсутствия документации, я не чувствую себя комфортно, писать об этом широко.

Обертывание

Пакет FPDF2 – это довольно хороший проект, который позволяет вам делать основные PDF Generation. Они делают указывают в FAQ, которые они не поддерживают диаграммы или виджеты или «гибкую систему макета страницы», как REPORTLAB. Они также не поддерживают экстракцию текста PDF или преобразования, такие как PDFMINER или PYPDF2. Однако, если все, что вам нужно, это основные основы для генерации PDF, то эта библиотека может работать для вас. Я думаю, что его кривая обучения проще, чем ReportLab есть. Тем не менее, FPDF2 нигде не так, как богатую функциональностью как REPORTLAB, и я не чувствовал, что у вас была совсем такая же гранулярность контроля, когда она пришла к размещению элементов на странице.

Связанное чтение

  • Создание интерактивных форм PDF в ReportLab с Python
  • Заполнение PDF Формы с Python.
  • Экспорт данных из PDFS с Python

Исходный код

  • pyfpdf_examples.tar.tar.tar.tar.