Vodič¶
Metode – popolna dokumentacija: fpdf.FPDF
API doc
Vodič 1 - Minimalni primer¶
Začnimo s klasičnim primerom:
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")
Po vključitvi datoteke knjižnice ustvarimo objekt FPDF
. Konstruktor FPDF se tu uporablja z privzetimi vrednostmi: strani so v pokončni postavitvi A4 in merska enota je milimeter. To bi lahko eksplicitno določili z:
pdf = FPDF(orientation="P", unit="mm", format="A4")
Možno je nastaviti PDF v ležeči način (L
) ali uporabiti druge formate strani (npr. Letter
in Legal
) ter merske enote (pt
, cm
, in
).
Zaenkrat ni strani, zato jo moramo dodati z add_page. Izvor je v zgornjem levem kotu, trenutni položaj pa je privzeto nastavljen na 1 cm od robov; robove lahko spremenimo z set_margins.
Pred tiskanjem besedila je obvezno izbrati pisavo z set_font, sicer dokument ne bi bil veljaven. Izberemo Helvetica krepko 16:
pdf.set_font('Helvetica', style='B', size=16)
Določimo lahko tudi ležečo (I
), podčrtano (U
) ali običajno pisavo (prazno niz ali katerokoli kombinacijo). Velikost pisave je izražena v pikah, ne v milimetrih (ali drugi merski enoti); to je edina izjema. Druge vgrajene pisave so Times
, Courier
, Symbol
in ZapfDingbats
.
Zdaj lahko natisnemo celico z cell. Celica je pravokotno področje, morda z okvirjem, ki vsebuje nekaj besedila. Izriše se na trenutnem položaju. Določimo njene dimenzije, besedilo (poravnano ali centrirano), ali naj se narišejo obrobe in kam se trenutni položaj premakne po tem (na desno, spodaj ali na začetek naslednje vrstice). Da bi dodali okvir, naredimo to:
pdf.cell(40, 10, 'Hello World!', 1)
Za dodajanje nove celice poleg nje s centriranim besedilom in premik v novo vrstico:
pdf.cell(60, 10, 'Powered by FPDF.', new_x="LMARGIN", new_y="NEXT", align='C')
Opomba: prelom vrstice lahko izvedemo tudi z ln. Ta metoda omogoča tudi določitev višine preloma.
Nazadnje je dokument zaprt in shranjen pod navedeno potjo datoteke z uporabo output. Brez navedenega parametra output()
vrne PDF bytearray
medpomnilnik.
Vodič 2 - Glava, noga, prelom strani in slika¶
Tukaj je primer dvostranskega dokumenta z glavo, nogo in logotipom:
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")
Ta primer uporablja header in footer za obdelavo glav in nog dokumenta. Kličeta se samodejno. V osnovnem razredu FPDF
že obstajata, a vendar ne izvajata ničesar, zato je razred potrebno razširiti in metodi prepisati.
Logotip je natisnjen z image, kjer določimo zgornji levi kot in širino. Višina se izračuna samodejno, da ostanejo razmerja slike nespremenjena.
Za izpis številke strani se kot širino celice poda None
. To pomeni, da se celica raztegne do desnega roba strani; to je priročno za centriranje besedila. Trenutno številko strani vrne page_no, medtem ko skupno število strani dobimo z uporabo posebne vrednosti {nb}
, ki se nadomesti ob zapiranju dokumenta (to vrednost lahko spremenimo z alias_nb_pages()). Omeniti velja tudi uporabo set_y, ki omogoča nastavitev navpičnega položaja na absolutno lokacijo strani, pričenši na vrhu ali dnu.
Zanimiva možnost, uporabljena tukaj, je samodejno prelamljanje strani. Takoj, ko bi celica presegla dno strani (privzeto 2 centimetra od roba), se ustvari nov prelom strani in pisava se povrne na prejšnje stanje. Čeprav glava in noga uporabljata svojo pisavo (helvetica
), se v telesu uporabi Times
. Ta mehanizem samodejnega obnavljanja velja tudi za barve in širino črte. Mejo, ki sproži prelom strani, lahko nastavimo z set_auto_page_break.
Vodič 3 - Prelomi vrstic in barve¶
Nadaljujmo s primerom, ki natisne poravnane odstavke in ilustrira rabo barv.
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")
get_string_width omogoča določitev dolžine niza v trenutni pisavi, kar nam pomaga izračunati položaj in širino okvira, ki obdaja naslov. Nato se nastavijo barve preko set_draw_color, set_fill_color in set_text_color, pa tudi debelina črte z set_line_width na 1 mm (privzeta je 0,2 mm). Na koncu izpišemo celico (zadnji parameter True
nakazuje, da se okno obarva).
Metoda, uporabljena za tiskanje odstavkov, je multi_cell. Besedilo je privzeto poravnano. Vsakič, ko vrstica doseže desni rob celice ali se pojavi znak za prelom vrstice (\n
), se vrstice prelomi in nova celica se ustvari pod trenutnim položajem. Samodejni prelom se izvrši na lokaciji najbližjega presledka ali mehke črtice (\u00ad
) pred desnim robom. Mehka črtica se ob prelomu vrstice spremeni v običajno črtico, sicer pa se ignorira.
Dve lastnosti dokumenta sta določeni: naslov set_title in avtor set_author. Do njih se lahko dostopa na dva načina: dokument se odpre neposredno v Acrobat Readerju in v meniju File izbere Document Properties ali pa se z desno tipko miške izbere Document Properties.
Vodič 4 - Večstolpčno besedilo¶
Ta primer je različica prejšnjega, prikazuje, kako razdeliti besedilo v več stolpcev.
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")
Ključna razlika od prejšnjega vodiča je uporaba metode text_columns
. Zbira vse besedilo, po potrebi po delih, in ga razdeli čez zahtevano število stolpcev, pri čemer samodejno vstavi prelome strani, kjer je to potrebno. Upoštevajte, da dokler je TextColumns
instanca aktivna kot upravljavec konteksta, lahko spreminjate slog besedila in druge lastnosti pisave, te spremembe pa bodo veljale samo znotraj tega konteksta. Ko je enkrat zaprt, se obnovijo prejšnje nastavitve.
Vodič 5 - Ustvarjanje tabel¶
Ta vodič bo razložil, kako ustvariti dve različni tabeli, da prikaže, kaj je mogoče doseči z nekaj osnovnimi prilagoditvami.
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")
Rezultatni PDF - Countries CSV data
Prvi primer je izveden na najbolj osnovni način, saj se podatki predajo metodi FPDF.table()
. Rezultat je precej preprost, vendar hitro dosegljiv.
Druga tabela prinaša nekaj izboljšav: barve, omejeno širino tabele, zmanjšano višino vrstic, centrirane naslove, stolpce s prilagojeno širino, desno poravnane številke ... Poleg tega so odstranjene vodoravne črte. Dosegli smo to z izbiro borders_layout
med razpoložljivimi vrednostmi: TableBordersLayout
.
Vodič 6 - Ustvarjanje povezav in mešanje slogov besedila¶
Ta vodič bo razložil več načinov, kako vstaviti povezave v PDF dokument, pa tudi, kako dodati povezave na zunanje vire.
Poleg tega bo pokazal več načinov uporabe različnih slogov besedila (krepko, ležeče, podčrtano) znotraj istega besedila.
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")
Nova metoda, prikazana tukaj za izpis besedila, je write(). Zelo je podobna metodi multi_cell(), vendar sta tu dve ključni razliki:
- Konec vrstice je na desnem robu, naslednja vrstica se začne na levem robu.
- Trenutni položaj se premakne na konec izpisanega besedila.
Ta metoda nam tako omogoča napisati kos besedila, spremeniti slog pisave in nadaljevati natanko tam, kjer smo ostali. Njena glavna slabost pa je, da ne omogoča poravnavanja besedila (justify) tako kot multi_cell().
Na prvi strani primera smo za ta namen uporabili write(). Začetek stavka je bil napisan z običajnim slogom pisave, nato smo z set_font() preklopili na podčrtano in dokončali stavek.
Za dodajanje notranje povezave, ki kaže na drugo stran, smo uporabili add_link(), ki ustvari klikabilno območje z imenom "link", ki vodi na drugo stran v dokumentu.
Za izdelavo zunanje povezave z uporabo slike smo uporabili image(). Metoda ima parameter link, ki omogoča nastavitev povezave (lahko je interna ali eksterna).
Kot alternativa je na voljo še en način za spreminjanje sloga pisave in vstavljanje povezav: metoda write_html()
, ki je HTML razčlenjevalnik in omogoča vstavljanje besedila, spreminjanje sloga pisave in povezav preko HTML kode.