'Problems creating PDF with tables and multicells in FPDF Python

I am trying to create a table with the FPDF library that is capable of expanding the height of the cells when the text is very large.

I am going to show the code that I have, which is the same that appears on the official documentation page:

from fpdf import FPDF

data = (
    ("First name", "Last name", "Age", "City"),
    ("Jules", "Smith", "34", "San Juan"),
    ("Mary", "Ramos", "45", "Orlando"),
    ("Carlson", "Banks", "19", "Los Angeles"),
    ("Lucas", "Cimon", "31", "Saint-Mahturin-sur-Loire udfhisudhf fughdiufhg fduihgsdiufg dfghsdifugh fdiguhdsfiug fdughdifugh dfhgsdiufhg"),
)

pdf = FPDF()
pdf.add_page()
pdf.set_font("Times", size=10)
line_height = pdf.font_size * 2.5
col_width = pdf.epw / 4 
for row in data:
    for datum in row:
        pdf.multi_cell(col_width, line_height, datum, border=1, ln=3)
    pdf.ln(line_height)
pdf.output('table_with_cells.pdf')

this is the result:

THE PDF RESULT

The last column of the last row is taller because it has more content, that's fine, but I would like the height of all columns in that row to be the same dynamically. Something like this:

I WOULD LIKE THIS RESULT

How can I get it?

Note: The data that will be in the table comes from the database, so I can't know exactly the length of each string



Solution 1:[1]

probably it's to late for you, but since we are at it...

Assumptions:
As always with FPDF, in order to adjust 'line_height' and 'col_width' parameters to use in cell/multicell methods...you MUST know something about the content of your data, at least the max length of the longest word in your table. Otherwise...you have to set some reasonable max boundaries according to your knowledge.
For instance, using your data, for setting the line_height... if ironically a 'first name' were composed by 75 chars (or more), multiply the font_size for 2.5 will not be enough and the final table printed on the pdf will be unreadable. But you can be pretty sure that you will nobody in the world has a first name that long. =) Therefore you can be confident that 2.5 is a reasonable factor, even if you don't know all elements in the first column of your table.

Anyway...
the only solution here, is count previously the number of words of each cell, defining a new,good,unique line_height for each data rows containing a string with many "N" words. This new line_height depends on the number of words of your long string. Finally, you can easily create your table choosing the proper line_height, according to your current row.

from fpdf import FPDF

data = (
    ("First name", "Last name", "Age", "City"),
    ("Jules", "Smith", "34", "San Juan"),
    ("Mary", "Ramos", "45", "Orlando"),
    ("Carlson", "Banks", "19", "Los Angeles"),
    ("Milano Roma Firenze Venezia Genova Napoli Livorno Bergamo Siracusa \       
    Rimini Pisa Bologna Brescia Torino"),
    )
pdf = FPDF()
pdf.add_page()
pdf.set_font("Times", size=10)
line_height = pdf.font_size * 2.5
col_width = pdf.epw / 4.5

lh_list = [] #list with proper line_height for each row
use_default_height = 0 #flag

#create lh_list of line_heights which size is equal to num rows of data
for row in data:
    for datum in row:
        word_list = datum.split()
        number_of_words = len(word_list) #how many words
        if number_of_words>2: #names and cities formed by 2 words like Los Angeles are ok)
            use_default_height = 1
            new_line_height = pdf.font_size * (number_of_words/2) #new height change according to data 
    if not use_default_height:
        lh_list.append(line_height)
    else:
        lh_list.append(new_line_height)
        use_default_height = 0

#create your fpdf table ..passing also max_line_height!
for j,row in enumerate(data):
    for datum in row:
        line_height = lh_list[j] #choose right height for current row
        pdf.multi_cell(col_width, line_height, datum, border=1,align='L',ln=3, 
        max_line_height=pdf.font_size)
    pdf.ln(line_height)

pdf.output('table_with_cells.pdf')

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Myron_is_Ben4