Los diferentes ejemplos muestran rapidamente como usar PyFPDF. Encontrará todas las características principales explicadas.

English: Tutorial

Ejemplo Mínimo

Empecemos con el ejemplo clásico:

from fpdf import FPDF

pdf = FPDF()
pdf.add_page()
pdf.set_font('Arial', 'B', 16)
pdf.cell(40, 10, 'Hola Mundo!')
pdf.output('tuto1.pdf', 'F')

Demo

Luego de incluir la biblioteca, creamos un objeto FPDF. El constructor FPDF es usado aqui con los valores predeterminados: páginas en A4 portrait -vertical- y la unidad de medida en milimetros. Podría haberlos especificado explicitamente:

pdf=FPDF('P', 'mm', 'A4')

Es posible usar landscape -apaisado- (L), otros formatos de página (como Letter -carta- y Legal -oficio-) y únidad de medida (pt, cm, in).

Por el momento no hay una página, entonces tenemos que agregar una con add_page. El origen es la esquina superior-izquierda y la posición actual está ubicada a 1 cm de los bordes; los margenes pueden ser cambiados con set_margins.

Antes de que podámos imprimir texto, es obligatorio seleccionar una fuente con set_font, de lo contrario el documento será inválido. Elegimos Arial bold 16:

pdf.set_font('Arial', 'B', 16)

Podríamos haber especificado italic -cursiva- con I, underline -subrayado- con U o fuente regular con string vacio (o cualquier combinación). Noar que el tamaño de la fuente es dado en puntos, no milimetros (u otra unidad de medida del usuario); esta es la única excepción. Las otras fuentes estándar son Times, Courier, Symbol y ZapfDingbats.

Podemos ahora imprimir una celda con cell. Una celda es un área rectangular, posiblemente enmarcada, que contiene algún texto. Se imprime en la posición actual. Especificamos sus dimensiones, su texto (centrado o alineado), si los bordes deberían ser dibujados, y donde la posición actual se mueve después (a la derecha, abajo o al principio de la próxima linea). Para agregar un marco, haremos:

pdf.cell(40, 10, 'Hola mundo !', 1)

Para agregar una nueva celda próxima a ella con texto centrada y luego ir a la siguiente línea, haríamos:

pdf.cell(60, 10, 'Hecho con FPDF.', 0, 1, 'C')

Nota: el salto de línea puede hacerse también con ln. Este método permite especificar adicionalmente la altura del salto.

Finalmente, el documento es cerrado y enviado al explorador con output. Podemos haberlo grabado a un fichero al pasarle el nombre de archivo.

Precaución: en caso cuando el PDF es enviado al explorador, nada más debe ser enviádo a la salida, ni antes ni después (el mínimo caracter importa).

Encabezado, pie de página, salto de página e imágen

Aquí hay un ejemplo de dos páginas con encabezado, pie y logo:

from fpdf import FPDF

class PDF(FPDF):
    def header(self):
        # Logo
        self.image('logo_pb.png', 10, 8, 33)
        # Arial bold 15
        self.set_font('Arial', 'B', 15)
        # Move to the right
        self.cell(80)
        # Title
        self.cell(30, 10, 'Title', 1, 0, 'C')
        # Line break
        self.ln(20)

    # Page footer
    def footer(self):
        # Position at 1.5 cm from bottom
        self.set_y(-15)
        # Arial italic 8
        self.set_font('Arial', 'I', 8)
        # Page number
        self.cell(0, 10, 'Page ' + str(self.page_no()) + '/{nb}', 0, 0, 'C')

# Instantiation of inherited class
pdf = PDF()
pdf.alias_nb_pages()
pdf.add_page()
pdf.set_font('Times', '', 12)
for i in range(1, 41):
    pdf.cell(0, 10, 'Printing line number ' + str(i), 0, 1)
pdf.output('tuto2.pdf', 'F')

Demo

Este ejemplo hace uso de métodos header y footer para procesar el encabezado y pie. Son llamados automáticamente. Ya existen en la clase FPDF pero no hacen nada, por lo tanto tenemos que extender la clase y sobreescribirlos.

El log es impreso con el método image especificando su esquina superior izquierda y su ancho. La altura es calculada automáticamente para respetar las proporciones de la imágen.

Para imprimir el número de página, un valor nulo es pasado como ancho de celda. Significa que la celda deberá ser extendida hasta el margen derecho de la página; es útil centrar texto. El número de página actual es devuelto por el método page_no; y para el número total de páginas, será obtenido mediante el valor especial {nb} que será sustituido al cerrar el documento (si de antemano se llamó alias_nb_pages). Notar el uso del método set_y que permite establecer la posición en una ubicación absoluta en la página, empezando desde arriba hacia abajo.

Otra característica interesante es usada aquí: el salto de página automático. Tan pronto una celda cruza el límite de una página (por defecto a 2 centimetros desde abajo), un salto es realizado y la fuente es restaurada. Aunque el encabezado y pie de página tienen su propia fuente (Arial), el cuerpo continua en Times. Este mecanismo de restauración automática tambien se aplica a los colores y el ancho de la línea. El límite que dispara los saltos de página puede establecerce con set_auto_page_break.

Saltos de línea y colores

Continuemos con un ejemplo que imprime parrafos justificados. También ilustra el uso de colores.

from fpdf import FPDF

title = '20000 Leagues Under the Seas'

class PDF(FPDF):
    def header(self):
        # Arial bold 15
        self.set_font('Arial', 'B', 15)
        # Calcular ancho del texto (title) y establecer posición
        w = self.get_string_width(title) + 6
        self.set_x((210 - w) / 2)
        # Colores del marco, fondo y texto
        self.set_draw_color(0, 80, 180)
        self.set_fill_color(230, 230, 0)
        self.set_text_color(220, 50, 50)
        # Grosor del marco (1 mm)
        self.set_line_width(1)
        # Titulo
        self.cell(w, 9, title, 1, 1, 'C', 1)
        # Salto de línea
        self.ln(10)

    def footer(self):
        # Posición a 1.5 cm desde abajo
        self.set_y(-15)
        # Arial italic 8
        self.set_font('Arial', 'I', 8)
        # Color de texto en gris
        self.set_text_color(128)
        # Numero de pagina
        self.cell(0, 10, 'Page ' + str(self.page_no()), 0, 0, 'C')

    def chapter_title(self, num, label):
        # Arial 12
        self.set_font('Arial', '', 12)
        # Color de fondo
        self.set_fill_color(200, 220, 255)
        # Titulo
        self.cell(0, 6, 'Chapter %d : %s' % (num, label), 0, 1, 'L', 1)
        # Salto de línea
        self.ln(4)

    def chapter_body(self, name):
        # Leer archivo de texto
        with open(name, 'rb') as fh:
            txt = fh.read().decode('latin-1')
        # Times 12
        self.set_font('Times', '', 12)
        # Emitir texto justificado
        self.multi_cell(0, 5, txt)
        # Salto de línea
        self.ln()
        # Mención en italic -cursiva-
        self.set_font('', 'I')
        self.cell(0, 5, '(end of excerpt)')

    def print_chapter(self, num, title, name):
        self.add_page()
        self.chapter_title(num, title)
        self.chapter_body(name)

pdf = PDF()
pdf.set_title(title)
pdf.set_author('Jules Verne')
pdf.print_chapter(1, 'A RUNAWAY REEF', '20k_c1.txt')
pdf.print_chapter(2, 'THE PROS AND CONS', '20k_c2.txt')
pdf.output('tuto3.pdf', 'F')

Demo

El método get_string_width permite determinar la longitud de una cadena en la fuente actual, usado aquí para calcular la posición y el ancho del marco que rodea al título. Los colores son establecidos (vía set_draw_color, set_fill_color y set_text_color) y el grosor de la línea es establecido a 1 mm (contra 0.2 por defecto) con set_line_width. Finalmente, emitimos la celda (el último parámetro es True para indicar que el fondo debe ser rellenado).

El método usado para imprimir parrafos es multi_cell. Cada vez que una línea alcanza el extremo derecho de la celda o un caracter de retorno de linea, un salto de línea es emitido y una nueva celda es automáticamente creada bajo la actual. El texto es justificado por defecto.

Dos propiedades del documento son definidas: el título (set_title) y el autor (set_author). Las propiedades pueden ser vistas de dos formas. La primera es abrir el documento directamente con Acrobat Reader, ir al menú Archivo y elegir la opción Propiedades del Documento. La segunda, también disponible en el plug-in, es hacer click izquierdo y seleccionar Propiedades del documento (Document Properties).

Notas de instalación

Anteriormente, para importar el objeto se debía usar el paquete pyfpdf:

from pyfpdf import FPDF

A partir de la versión 1.7, para importar el objeto se debe usar el paquete fpdf:

from fpdf import FPDF