Kurzanleitung¶
Vollständige Dokumentation der Methoden: fpdf.FPDF
API doc
Lektion 1 - Minimalbeispiel¶
Beginnen wir mit dem Klassiker:
from fpdf import FPDF
pdf = FPDF()
pdf.add_page()
pdf.set_font("helvetica", style="B", size=16)
pdf.cell(40, 10, "Hello World!")
pdf.output("tuto1.pdf")
Nachdem wir die Bibliothek eingebunden haben, erstellen zuerst wir ein FPDF
Objekt. Der FPDF
Konstruktor wird hier mit den Standardwerten verwendet: Das Seitenformat wird auf A4-Hochformat gesetzt und als Maßeinheit Millimeter festgelegt.
Diese Werte hätten wir auch explizit angegeben können:
pdf = FPDF(orientation="P", unit="mm", format="A4")
L
), sowie andere Seitenformate (Letter
und Legal
) und Maßeinheiten (pt
, cm
, in
) zu verwenden. Bisher haben wir dem Dokument noch keine Seite hinzugefügt. Um eine Seite hinzuzufügen, verwenden wir add_page
. Der Ursprung der Koordinaten liegt in der oberen linken Ecke und die aktuelle Schreibposition ist standardmäßig jeweils 1 cm von den Rändern entfernt. Diese Randabstände können mit set_margins
angespasst werden.
Bevor wir Text hinzufügen können, müssen wir zuerst mit set_font
eine Schriftart festlegen, um ein gültiges Dokument zu erzeugen. Wir wählen Helvetica, fett in Schriftgröße 16 pt:
pdf.set_font('Helvetica', style='B', size=16)
Anstelle von B
hätten wir mit I
kursiv , U
unterstichen oder durch die Übergabe einer leeren Zeichenkette einen "normale" Textstil wählen können. Beliebige Kombinationen der drei Werte sind zulässig. Beachte, dass die Schriftgröße in Punkt und nicht in Millimetern (oder einer anderen durch den Benutzer bei der Erstellung mit unit=
festgelegten Maßeinheit) angegeben wird. Dies ist die einzige Ausnahme vom Grundsatz, dass immer die durch den Benutzer gewählte Maßeinheit bei der Festlegung von Positions- oder Größenangaben genutzt wird. Neben Helvetica
stehen Times
, Courier
, Symbol
und ZapfDingbats
als Standardschriftarten zur Verfügung.
Wir können jetzt eine erste Textzelle mit cell
einfügen. Eine Zelle ist ein rechteckiger Bereich - optional umrahmt - der Text enthalten kann. Sie wird an der jeweils aktuellen Schreibposition gerendert. Wir können die Abmessungen der Zelle, den Text und dessen Formatierung (zentriert oder ausgerichtet), einen ggf. gewünschten Rahmen und die Festlegung der neuen Schreibposition nach dem Schreiben der Zelle (rechts, unten oder am Anfang der nächsten Zeile) bestimmen.
Um einen Rahmen hinzuzufügen, würden wir die Methode folgendermaßen einbinden:
pdf.cell(40, 10, 'Hello World!', 1)
Um eine neue Zelle mit zentriertem Text hinzuzufügen und anschließend in die nächste Zeile zu springen, können wir Folgendes schreiben:
pdf.cell(60, 10, 'Powered by FPDF.', new_x="LMARGIN", new_y="NEXT", align='C')
Anmerkung: Der Zeilenumbruch kann auch mit ln
erfolgen. Diese Methode erlaubt es, zusätzlich die Höhe des Umbruchs anzugeben.
Schließlich wird das Dokument mit output
geschlossen und unter dem angegebenen Dateipfad gespeichert. Ohne Angabe eines Parameters liefert output()
den PDF bytearray
-Puffer zurück.
Lektion 2 - Kopfzeile, Fußzeile, Seitenumbruch und Bild¶
Hier ein zweiseitiges Beispiel mit Kopfzeile, Fußzeile und Logo:
from fpdf import FPDF
class PDF(FPDF):
def header(self):
# Rendering logo:
self.image("../docs/fpdf2-logo.png", 10, 8, 33)
# Setting font: helvetica bold 15
self.set_font("helvetica", style="B", size=15)
# Moving cursor to the right:
self.cell(80)
# Printing title:
self.cell(30, 10, "Title", border=1, align="C")
# Performing a line break:
self.ln(20)
def footer(self):
# Position cursor at 1.5 cm from bottom:
self.set_y(-15)
# Setting font: helvetica italic 8
self.set_font("helvetica", style="I", size=8)
# Printing page number:
self.cell(0, 10, f"Page {self.page_no()}/{{nb}}", align="C")
# Instantiation of inherited class
pdf = PDF()
pdf.add_page()
pdf.set_font("Times", size=12)
for i in range(1, 41):
pdf.cell(0, 10, f"Printing line number {i}", new_x="LMARGIN", new_y="NEXT")
pdf.output("new-tuto2.pdf")
Dieses Beispiel verwendet die Methoden header
und footer
, um Kopf- und Fußzeilen zu verarbeiten. Sie werden jeweils automatisch aufgerufen. Die Methode 'header' direkt nach dem Hinzugügen einer neuen Seite, die Methode 'footer' wenn die Bearbeitung einer Seite durch das Hinzufügen einer weiteren Seite oder das Abspeichern des Dokuments abgeschlossen wird. Die Methoden existieren bereits in der Klasse FPDF, sind aber leer. Um sie zu nutzen, müssen wir die Klasse erweitern und sie überschreiben.
Das Logo wird mit der Methode image
eingebunden, und auf der Seite durch die Angabe der Position der linken oberen Ecke und die gewünschte Bildbreite platziert. Die Höhe wird automatisch berechnet, um die Proportionen des Bildes zu erhalten.
Um die Seitenzahl einzufügenn, übergeben wir zuerst der Zelle einen Nullwert als Breite der Zelle. Das bedeutet, dass die Zelle bis zum rechten Rand der Seite reichen soll. Das ist besonders praktisch, um Text zu zentrieren. Die aktuelle Seitenzahl wird durch die Methode page_no
ermittelt und in die Zelle geschrieben. Die Gesamtseitenzahl wird mit Hilfe des speziellen Platzhalterwertes {nb}
ermittelt, der beim Schließen des Dokuments ersetzt wird aufgerufen. Beachte die Verwendung der Methode set_y
, mit der du die vertikale Schreibposition an einer absoluten Stelle der Seite - von oben oder von unten aus - setzen kannst.
Eine weitere interessante Funktion wird hier ebenfalls verwendet: der automatische Seitenumbruch. Sobald eine Zelle eine festgelegte Grenze in der Seite überschreitet (standardmäßig 2 Zentimeter vom unteren Rand), wird ein Seitenumbruch durchgeführt und die Einstellungen der gewahlten Schrift auf der nächsten Seite automatisch beibehalten. Obwohl die Kopf- und Fußzeilen ihre eigene Schriftart (Helvetica
) wählen, wird im Textkörper Times
verwendet. Dieser Mechanismus der automatischen Übernahme der Einstellungen nach Seitenumbruch gilt auch für Farben und Zeilenbreite. Der Grenzwert, der den Seitenumbruch auslöst, kann mit set_auto_page_break
festgelegt werden .
Lektion 3 - Zeilenumbrüche und Farben¶
Fahren wir mit einem Beispiel fort, das Absätze im Blocksatz ausgibt. Es demonstriert auch die Verwendung von Farben.
from fpdf import FPDF
class PDF(FPDF):
def header(self):
# Setting font: helvetica bold 15
self.set_font("helvetica", style="B", size=15)
# Calculating width of title and setting cursor position:
width = self.get_string_width(self.title) + 6
self.set_x((210 - width) / 2)
# Setting colors for frame, background and text:
self.set_draw_color(0, 80, 180)
self.set_fill_color(230, 230, 0)
self.set_text_color(220, 50, 50)
# Setting thickness of the frame (1 mm)
self.set_line_width(1)
# Printing title:
self.cell(
width,
9,
self.title,
border=1,
new_x="LMARGIN",
new_y="NEXT",
align="C",
fill=True,
)
# Performing a line break:
self.ln(10)
def footer(self):
# Setting position at 1.5 cm from bottom:
self.set_y(-15)
# Setting font: helvetica italic 8
self.set_font("helvetica", style="I", size=8)
# Setting text color to gray:
self.set_text_color(128)
# Printing page number
self.cell(0, 10, f"Page {self.page_no()}", align="C")
def chapter_title(self, num, label):
# Setting font: helvetica 12
self.set_font("helvetica", size=12)
# Setting background color
self.set_fill_color(200, 220, 255)
# Printing chapter name:
self.cell(
0,
6,
f"Chapter {num} : {label}",
new_x="LMARGIN",
new_y="NEXT",
align="L",
fill=True,
)
# Performing a line break:
self.ln(4)
def chapter_body(self, filepath):
# Reading text file:
with open(filepath, "rb") as fh:
txt = fh.read().decode("latin-1")
# Setting font: Times 12
self.set_font("Times", size=12)
# Printing justified text:
self.multi_cell(0, 5, txt)
# Performing a line break:
self.ln()
# Final mention in italics:
self.set_font(style="I")
self.cell(0, 5, "(end of excerpt)")
def print_chapter(self, num, title, filepath):
self.add_page()
self.chapter_title(num, title)
self.chapter_body(filepath)
pdf = PDF()
pdf.set_title("20000 Leagues Under the Seas")
pdf.set_author("Jules Verne")
pdf.print_chapter(1, "A RUNAWAY REEF", "20k_c1.txt")
pdf.print_chapter(2, "THE PROS AND CONS", "20k_c1.txt")
pdf.output("tuto3.pdf")
Die Methode get_string_width
ermöglicht die Bestimmung die Breite des übergebenen Textes in der aktuellen Schriftart. Das Beispiel nutzt sie zur Berechnung der Position und der Breite des Rahmens, der den Titel umgibt. Anschließend werden die Farben mit set_draw_color
, set_fill_color
und und set_text_color
gesetzt und die Linienstärke mit set_line_width
auf 1 mm (Abweichend vom Standardwert von 0,2) festgelegt. Schließlich geben wir die Zelle aus (Der letzte Parameter True zeigt an, dass der Hintergrund gefüllt werden muss).
Zur Erstellung von Absätzen wir die Methode multi_cell
genutzt. Jedes Mal, wenn eine Zeile den rechten Rand der Zelle erreicht oder ein Zeilenumbruchzeichen \\n
im Text erkannt wird, wird ein Zeilenumbruch durchgeführt und automatisch eine neue Zelle unterhalb der aktuellen Zelle erstellt. Der Text wird standardmäßig im Blocksatz ausgerichtet.
Es werden zwei Dokumenteigenschaften definiert: Titel (set_title
) und Autor (set_author
). Dokumenteneigenschaften können auf zwei Arten eingesehen werden. Man kann das Dokument mit dem Acrobat Reader öffnen und im Menü Datei die Option Dokumenteigenschaften auswählen. Alternativ kann man auch mit der rechten Maustaste auf das Dokument klicken und die Option Dokumenteigenschaften wählen.
Lektion 4 - Mehrspaltiger Text¶
Dieses Beispiel ist eine Abwandlung des vorherigen Beispiels und zeigt, wie sich Text über mehrere Spalten verteilen lässt.
from fpdf import FPDF
class PDF(FPDF):
def header(self):
self.set_font("helvetica", style="B", size=15)
width = self.get_string_width(self.title) + 6
self.set_x((210 - width) / 2)
self.set_draw_color(0, 80, 180)
self.set_fill_color(230, 230, 0)
self.set_text_color(220, 50, 50)
self.set_line_width(1)
self.cell(
width,
9,
self.title,
border=1,
new_x="LMARGIN",
new_y="NEXT",
align="C",
fill=True,
)
self.ln(10)
def footer(self):
self.set_y(-15)
self.set_font("helvetica", style="I", size=8)
self.set_text_color(128)
self.cell(0, 10, f"Page {self.page_no()}", align="C")
def chapter_title(self, num, label):
self.set_font("helvetica", size=12)
self.set_fill_color(200, 220, 255)
self.cell(
0,
6,
f"Chapter {num} : {label}",
new_x="LMARGIN",
new_y="NEXT",
border="L",
fill=True,
)
self.ln(4)
def chapter_body(self, fname):
# Reading text file:
with open(fname, "rb") as fh:
txt = fh.read().decode("latin-1")
with self.text_columns(
ncols=3, gutter=5, text_align="J", line_height=1.19
) as cols:
# Setting font: Times 12
self.set_font("Times", size=12)
cols.write(txt)
cols.ln()
# Final mention in italics:
self.set_font(style="I")
cols.write("(end of excerpt)")
def print_chapter(self, num, title, fname):
self.add_page()
self.chapter_title(num, title)
self.chapter_body(fname)
pdf = PDF()
pdf.set_title("20000 Leagues Under the Seas")
pdf.set_author("Jules Verne")
pdf.print_chapter(1, "A RUNAWAY REEF", "20k_c1.txt")
pdf.print_chapter(2, "THE PROS AND CONS", "20k_c1.txt")
pdf.output("tuto4.pdf")
Der Hauptunterschied zur vorherigen Lektion ist die Verwendung der Methode text_columns
. Diese sammelt zunächst allen text, auch in mehreren Teilen, und verteilt ihn anschließend auf die angegebene Anzahl an Spalten. Eventuell notwendige Seitenumbrüche werden dabei automatisch vorgenommen. Beachtenswert dabei ist, dass während die TextColumns
instanz als Kontextmanager offen ist, Schriftstile und ander Eigenschaften frei verändert werden können. Nach schließen des Kontextes werden die Einstellungen wieder auf den vorherigen Stand zurückgesetzt.
Lektion 5 - Tabellen erstellen¶
import csv
from fpdf import FPDF
from fpdf.fonts import FontFace
from fpdf.enums import TableCellFillMode
with open("countries.txt", encoding="utf8") as csv_file:
data = list(csv.reader(csv_file, delimiter=","))
pdf = FPDF()
pdf.set_font("helvetica", size=14)
# Basic table:
pdf.add_page()
with pdf.table() as table:
for data_row in data:
row = table.row()
for datum in data_row:
row.cell(datum)
# Styled table:
pdf.add_page()
pdf.set_draw_color(255, 0, 0)
pdf.set_line_width(0.3)
headings_style = FontFace(emphasis="BOLD", color=255, fill_color=(255, 100, 0))
with pdf.table(
borders_layout="NO_HORIZONTAL_LINES",
cell_fill_color=(224, 235, 255),
cell_fill_mode=TableCellFillMode.ROWS,
col_widths=(42, 39, 35, 42),
headings_style=headings_style,
line_height=6,
text_align=("LEFT", "CENTER", "RIGHT", "RIGHT"),
width=160,
) as table:
for data_row in data:
row = table.row()
for datum in data_row:
row.cell(datum)
pdf.output("tuto5.pdf")
Das erste Beispiel wird auf die einfachst mögliche Weise umgesetzt, und einfach nur die Daten in die Tabelle eingefügt. Das Ergebnis ist eine sehr schlichte Darstellung, kann aber sehr schnell erzeugt werden.
Die zweite Tabelle bringt einige Verfeinerungen: Farben, reduzierte Gesamtbreite, geringere Zeilenhöhe, zentrierter Text, individuelle Spaltenbreiten und rechts justierte Zahlenwerte. Zusätzliche wurden die horizontalen Linien ausgeblendet. Dies wird dadurch erreicht, dass das Argument borders_layout
einen geeigneten Wert des Enums TableBordersLayout
erhält.
Lektion 6 - Links erstellen und Textstile mischen¶
In dieser Lektion werden verschiedene Möglichkeiten der Erstellung interner und externer Links beschrieben.
Es wird auch gezeigt, wie man verschiedene Textstile (fett, kursiv, unterstrichen) innerhalb eines Textes verwenden kann.
from fpdf import FPDF
pdf = FPDF()
# First page:
pdf.add_page()
pdf.set_font("helvetica", size=20)
pdf.write(5, "To find out what's new in self tutorial, click ")
pdf.set_font(style="U")
link = pdf.add_link(page=2)
pdf.write(5, "here", link)
pdf.set_font()
# Second page:
pdf.add_page()
pdf.image(
"../docs/fpdf2-logo.png", 10, 10, 50, 0, "", "https://py-pdf.github.io/fpdf2/"
)
pdf.set_left_margin(60)
pdf.set_font_size(18)
pdf.write_html(
"""You can print text mixing different styles using HTML tags: <b>bold</b>, <i>italic</i>,
<u>underlined</u>, or <b><i><u>all at once</u></i></b>!
<br><br>You can also insert links on text, such as <a href="https://py-pdf.github.io/fpdf2/">https://py-pdf.github.io/fpdf2/</a>,
or on an image: the logo is clickable!"""
)
pdf.output("tuto6.pdf")
Die hier gezeigte neue Methode zur Einbindung von Text lautet write()
. Sie ähnelt der bereits bekannten multi_cell()
. Die wichtigsten Unterschiede sind:
- Das Ende der Zeile befindet sich am rechten Rand und die nächste Zeile beginnt am linken Rand.
- Die aktuelle Position wird an das Textende gesetzt.
Die Methode ermöglicht es uns somit, zuerst einen Textabschnitt zu schreiben, dann den Schriftstil zu ändern und genau an der Stelle fortzufahren, an der wir aufgehört haben. Der größte Nachteil ist jedoch, dass die von multi_cell()
bekannte Möglichkeit zur Festlegung der Textausrichtung fehlt.
Auf der ersten Seite des Beispiels nutzen wir write()
. Der Anfang des Satzes wird in "normalem" Stil geschrieben, dann mit der Methode set_font()
auf Unterstreichung umgestellt und der Satz beendet.
Um einen internen Link hinzuzufügen, der auf die zweite Seite verweist, nutzen wir die Methode add_link()
, die einen anklickbaren Bereich erzeugt, den wir "link" nennen und der auf eine andere Stelle innerhalb des Dokuments verweist.
Um einen externen Link mit Hilfe eines Bildes zu erstellen, verwenden wir image()
. Es besteht die Möglichkeit, der Methode ein Linkziel als eines ihrer Argumente zu übergeben. Der Link kann sowohl einer interner als auch ein externer sein.
Eine weitere Möglichkeit, den Schriftstil zu ändern und Links hinzuzufügen, stellt die Verwendung der Methode write_html()
dar. Sie ist ein HTML-Parser, der das Hinzufügen von Text, Änderung des Schriftstils und Erstellen von Links mittels HTML ermöglicht.