1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
|
# Tutorial #
Methods full documentation: [`fpdf.FPDF` API doc](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF)
## Tuto 1 - Minimal Example ##
Let's start with the classic example:
```python
{% include "../tutorial/tuto1.py" %}
```
[Resulting PDF](https://github.com/py-pdf/fpdf2/raw/master/tutorial/tuto1.pdf)
After including the library file, we create an `FPDF` object. The
[FPDF](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF) constructor is used here with the default values:
pages are in A4 portrait and the measure unit is millimeter.
It could have been specified explicitly with:
```python
pdf = FPDF(orientation="P", unit="mm", format="A4")
```
It is possible to set the PDF in landscape mode (`L`) or to use other page formats
(such as `Letter` and `Legal`) and measure units (`pt`, `cm`, `in`).
There is no page for the moment, so we have to add one with
[add_page](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.add_page). The origin is at the upper-left corner and the
current position is by default placed at 1 cm from the borders; the margins can
be changed with [set_margins](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.set_margins).
Before we can print text, it is mandatory to select a font with
[set_font](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.set_font), otherwise the document would be invalid.
We choose Helvetica bold 16:
```python
pdf.set_font('Helvetica', style='B', size=16)
```
We could have specified italics with `I`, underlined with `U` or a regular font
with an empty string (or any combination). Note that the font size is given in
points, not millimeters (or another user unit); it is the only exception.
The other built-in fonts are `Times`, `Courier`, `Symbol` and `ZapfDingbats`.
We can now print a cell with [cell](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.cell). A cell is a rectangular
area, possibly framed, which contains some text. It is rendered at the current
position. We specify its dimensions, its text (centered or aligned), if borders
should be drawn, and where the current position moves after it (to the right,
below or to the beginning of the next line). To add a frame, we would do this:
```python
pdf.cell(40, 10, 'Hello World!', 1)
```
To add a new cell next to it with centered text and go to the next line, we
would do:
```python
pdf.cell(60, 10, 'Powered by FPDF.', new_x="LMARGIN", new_y="NEXT", align='C')
```
**Remark**: the line break can also be done with [ln](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.ln). This
method allows to specify in addition the height of the break.
Finally, the document is closed and saved under the provided file path using
[output](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.output). Without any parameter provided, `output()`
returns the PDF `bytearray` buffer.
## Tuto 2 - Header, footer, page break and image ##
Here is a two page example with header, footer and logo:
```python
{% include "../tutorial/tuto2.py" %}
```
[Resulting PDF](https://github.com/py-pdf/fpdf2/raw/master/tutorial/tuto2.pdf)
This example makes use of the [header](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.header) and
[footer](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.footer) methods to process page headers and footers. They
are called automatically. They already exist in the FPDF class but do nothing,
therefore we have to extend the class and override them.
The logo is printed with the [image](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.image) method by specifying
its upper-left corner and its width. The height is calculated automatically to
respect the image proportions.
To print the page number, a null value is passed as the cell width. It means
that the cell should extend up to the right margin of the page; it is handy to
center text. The current page number is returned by
the [page_no](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.page_no) method; as for
the total number of pages, it is obtained by means of the special value `{nb}`
which will be substituted on document closure (this special value can be changed by
[alias_nb_pages()](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.alias_nb_pages)).
Note the use of the [set_y](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.set_y) method which allows to set
position at an absolute location in the page, starting from the top or the
bottom.
Another interesting feature is used here: the automatic page breaking. As soon
as a cell would cross a limit in the page (at 2 centimeters from the bottom by
default), a break is performed and the font restored. Although the header and
footer select their own font (`helvetica`), the body continues with `Times`.
This mechanism of automatic restoration also applies to colors and line width.
The limit which triggers page breaks can be set with
[set_auto_page_break](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.set_auto_page_break).
## Tuto 3 - Line breaks and colors ##
Let's continue with an example which prints justified paragraphs. It also
illustrates the use of colors.
```python
{% include "../tutorial/tuto3.py" %}
```
[Resulting PDF](https://github.com/py-pdf/fpdf2/raw/master/tutorial/tuto3.pdf)
[Jules Verne text](https://github.com/py-pdf/fpdf2/raw/master/tutorial/20k_c1.txt)
The [get_string_width](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.get_string_width) method allows determining
the length of a string in the current font, which is used here to calculate the
position and the width of the frame surrounding the title. Then colors are set
(via [set_draw_color](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.set_draw_color),
[set_fill_color](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.set_fill_color) and
[set_text_color](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.set_text_color)) and the thickness of the line is set
to 1 mm (against 0.2 by default) with
[set_line_width](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.set_line_width). Finally, we output the cell (the
last parameter to true indicates that the background must be filled).
The method used to print the paragraphs is [multi_cell](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.multi_cell). Text is justified by default.
Each time a line reaches the right extremity of the cell or a carriage return character (`\n`) is met,
a line break is issued and a new cell automatically created under the current one.
An automatic break is performed at the location of the nearest space or soft-hyphen (`\u00ad`) character before the right limit.
A soft-hyphen will be replaced by a normal hyphen when triggering a line break, and ignored otherwise.
Two document properties are defined: the title
([set_title](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.set_title)) and the author
([set_author](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.set_author)). Properties can be viewed by two means.
First is to open the document directly with Acrobat Reader, go to the File menu
and choose the Document Properties option. The second, also available from the
plug-in, is to right-click and select Document Properties.
## Tuto 4 - Multi Columns ##
This example is a variant of the previous one, showing how to lay the text across multiple columns.
```python
{% include "../tutorial/tuto4.py" %}
```
[Resulting PDF](https://github.com/py-pdf/fpdf2/raw/master/tutorial/tuto4.pdf)
[Jules Verne text](https://github.com/py-pdf/fpdf2/raw/master/tutorial/20k_c1.txt)
The key difference from the previous tutorial is the use of the
[`text_columns`](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.text_column) method.
It collects all the text, possibly in increments, and distributes it across the requested number of columns, automatically inserting page breaks as necessary. Note that while the `TextColumns` instance is active as a context manager, text styles and other font properties can be changed. Those changes will be contained to the context. Once it is closed the previous settings will be reinstated.
## Tuto 5 - Creating Tables ##
This tutorial will explain how to create two different tables,
to demonstrate what can be achieved with some simple adjustments.
```python
{% include "../tutorial/tuto5.py" %}
```
[Resulting PDF](https://github.com/py-pdf/fpdf2/raw/master/tutorial/tuto5.pdf) -
[Countries CSV data](https://github.com/py-pdf/fpdf2/raw/master/tutorial/countries.txt)
The first example is achieved in the most basic way possible, feeding data to [`FPDF.table()`](https://py-pdf.github.io/fpdf2/Tables.html). The result is rudimentary but very quick to obtain.
The second table brings some improvements: colors, limited table width, reduced line height,
centered titles, columns with custom widths, figures right aligned...
Moreover, horizontal lines have been removed.
This was done by picking a `borders_layout` among the available values:
[`TableBordersLayout`](https://py-pdf.github.io/fpdf2/fpdf/enums.html#fpdf.enums.TableBordersLayout).
## Tuto 6 - Creating links and mixing text styles ##
This tutorial will explain several ways to insert links inside a pdf document,
as well as adding links to external sources.
It will also show several ways we can use different text styles,
(bold, italic, underline) within the same text.
```python
{% include "../tutorial/tuto6.py" %}
```
[Resulting PDF](https://github.com/py-pdf/fpdf2/raw/master/tutorial/tuto6.pdf) -
[fpdf2-logo](https://py-pdf.github.io/fpdf2/fpdf2-logo.png)
The new method shown here to print text is
[write()](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.write)
. It is very similar to
[multi_cell()](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.multi_cell)
, the key differences being:
- The end of line is at the right margin and the next line begins at the left
margin.
- The current position moves to the end of the text.
The method therefore allows us to write a chunk of text, alter the font style,
and continue from the exact place we left off.
On the other hand, its main drawback is that we cannot justify the text like
we do with the
[multi_cell()](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.multi_cell)
method.
In the first page of the example, we used
[write()](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.write)
for this purpose. The beginning of the sentence is written in regular style
text, then using the
[set_font()](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.set_font)
method, we switched to underline and finished the sentence.
To add an internal link pointing to the second page, we used the
[add_link()](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.add_link)
method, which creates a clickable area which we named "link" that directs to
another page within the document.
To create the external link using an image, we used
[image()](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.image)
. The method has the
option to pass a link as one of its arguments. The link can be both internal
or external.
As an alternative, another option to change the font style and add links is to
use the `write_html()` method. It is an html parser, which allows adding text,
changing font style and adding links using html.
## Tuto 7 - Creating PDF/A Documents ##
_New in [:octicons-tag-24: 2.8.3](https://github.com/py-pdf/fpdf2/blob/master/CHANGELOG.md)_
### PDF/A Standards ###
<b>PDF/A-1</b> uses PDF-Version 1.4. All resources (pictures, graphics, fonts) must be embedded in the document. The color management must be precise and platform independently specified with ICC-Profiles and the document metadata must be given with XMP-Metadata.
<b>PDF/A-2</b> uses PDF-Version 1.7. It allows compression with JPEG2000, transparent elements, open type fonts and digital signatures.
The only extension for <b>PDF/A-3</b> is the possibility to embed any possible file.
### Conformance Classes ###
Level A (accessible) encompasses all the requirements of the standard, including mapping the content structure and the correct reading order of the document content. Text content must be extractable, and the structure must reflect the natural reading sequence.
Level B (Basic) guarantees a clear visual reproducibility of the content. Level B is generally easier to generate than Level A, but it does not ensure 100 percent text extraction or searchability. The hassle-free reuse of the content is not necessarily given.
To achieve this, here a little example:
```python
{% include "../tutorial/tuto7.py" %}
```
[Resulting PDF: tuto7.pdf](https://github.com/py-pdf/fpdf2/raw/master/tutorial/tuto7.pdf)
First, we add the needed embedded fonts using the
[add_font()](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.add_font)
method for each style.
Then, we add the ICC profile object to the output intents array using the
[add_output_intent()](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.add_output_intent)
method.
After adding some pages, using the embedded fonts, and writing some text,
we create the pdf by calling `create_pdf_with_metadata()`,
that uses [pikepdf](https://pypi.org/project/pikepdf/)
to create the necessary metadata and set the type to PDF/A-3B.
For more information on PDF metadata, check the dedicated documentation page: [Metadata](Metadata.md).
Note that instead of using a function, you could also subclass `FPDF.output()` to ensure that all your documents are PDF-A compliant, as done in [test/pdf-a/test_pdf_a.py](https://github.com/py-pdf/fpdf2/blob/master/test/pdf-a/test_pdf_a.py).
Tools like [VeraPDF](https://verapdf.org/) can check conformance of PDF documents produced:
verapdf --format text -v tutorial/tuto7.pdf
Produces:
PASS fpdf2/tutorial/tuto7.pdf 3b
|